ability to shrink all images x2 on load

this is for extreme cases when running on devices with very low video
memory, so you can still retain compatibility.
This commit is contained in:
Juan Linietsky 2016-05-04 12:36:51 -03:00 committed by Ariel Manzur
parent 4bc494ae2e
commit d6e30256ad
11 changed files with 103 additions and 2 deletions

View file

@ -901,6 +901,66 @@ static void _generate_po2_mipmap(const uint8_t* p_src, uint8_t* p_dst, uint32_t
}
void Image::shrink_x2() {
ERR_FAIL_COND(format==FORMAT_INDEXED || format==FORMAT_INDEXED_ALPHA);
ERR_FAIL_COND( data.size()==0 );
if (mipmaps) {
//just use the lower mipmap as base and copy all
DVector<uint8_t> new_img;
int ofs = get_mipmap_offset(1);
int new_size = data.size()-ofs;
new_img.resize(new_size);
{
DVector<uint8_t>::Write w=new_img.write();
DVector<uint8_t>::Read r=data.read();
copymem(w.ptr(),&r[ofs],new_size);
}
mipmaps--;
width/=2;
height/=2;
data=new_img;
} else {
DVector<uint8_t> new_img;
ERR_FAIL_COND( format>=FORMAT_INDEXED );
int ps = get_format_pixel_size(format);
new_img.resize((width/2)*(height/2)*ps);
{
DVector<uint8_t>::Write w=new_img.write();
DVector<uint8_t>::Read r=data.read();
switch(format) {
case FORMAT_GRAYSCALE:
case FORMAT_INTENSITY: _generate_po2_mipmap<1>(r.ptr(), w.ptr(), width,height); break;
case FORMAT_GRAYSCALE_ALPHA: _generate_po2_mipmap<2>(r.ptr(), w.ptr(), width,height); break;
case FORMAT_RGB: _generate_po2_mipmap<3>(r.ptr(), w.ptr(), width,height); break;
case FORMAT_RGBA: _generate_po2_mipmap<4>(r.ptr(), w.ptr(), width,height); break;
default: {}
}
}
width/=2;
height/=2;
data=new_img;
}
}
Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) {
if (!_can_modify(format)) {

View file

@ -248,6 +248,7 @@ public:
void resize_to_po2(bool p_square=false);
void resize( int p_width, int p_height, Interpolation p_interpolation=INTERPOLATE_BILINEAR );
Image resized( int p_width, int p_height, int p_interpolation=INTERPOLATE_BILINEAR );
void shrink_x2();
/**
* Crop the image to a specific size, if larger, then the image is filled by black
*/

View file

@ -921,6 +921,11 @@ void RasterizerGLES2::texture_allocate(RID p_texture,int p_width, int p_height,I
texture->alloc_height = texture->height;
};
if (shrink_textures_x2) {
texture->alloc_height = MAX(1,texture->alloc_height/2);
texture->alloc_width = MAX(1,texture->alloc_width/2);
}
texture->gl_components_cache=components;
texture->gl_format_cache=format;
@ -970,8 +975,15 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu
if (texture->alloc_width != img.get_width() || texture->alloc_height != img.get_height()) {
if (img.get_format() <= Image::FORMAT_INDEXED_ALPHA)
if (texture->alloc_width == img.get_width()/2 && texture->alloc_height == img.get_height()/2) {
img.shrink_x2();
} else if (img.get_format() <= Image::FORMAT_INDEXED_ALPHA) {
img.resize(texture->alloc_width, texture->alloc_height, Image::INTERPOLATE_BILINEAR);
}
};
@ -1452,6 +1464,11 @@ void RasterizerGLES2::texture_debug_usage(List<VS::TextureInfo> *r_info){
}
void RasterizerGLES2::texture_set_shrink_all_x2_on_set_data(bool p_enable) {
shrink_textures_x2=p_enable;
}
/* SHADER API */
RID RasterizerGLES2::shader_create(VS::ShaderMode p_mode) {

View file

@ -108,6 +108,8 @@ class RasterizerGLES2 : public Rasterizer {
bool use_half_float;
bool low_memory_2d;
bool shrink_textures_x2;
Vector<float> skel_default;
Image _get_gl_image_and_format(const Image& p_image, Image::Format p_format, uint32_t p_flags,GLenum& r_gl_format,GLenum& r_gl_internal_format,int &r_gl_components,bool &r_has_alpha_cache,bool &r_compressed);
@ -1334,6 +1336,8 @@ public:
virtual String texture_get_path(RID p_texture) const;
virtual void texture_debug_usage(List<VS::TextureInfo> *r_info);
virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable);
GLuint _texture_get_name(RID p_tex);
/* SHADER API */

View file

@ -196,6 +196,8 @@ public:
virtual String texture_get_path(RID p_texture) const=0;
virtual void texture_debug_usage(List<VS::TextureInfo> *r_info)=0;
virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable)=0;
/* SHADER API */
virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL)=0;

View file

@ -415,6 +415,8 @@ public:
virtual String texture_get_path(RID p_texture) const { return String(); }
virtual void texture_debug_usage(List<VS::TextureInfo> *r_info) {}
virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable) {}
/* SHADER API */
virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL);

View file

@ -127,6 +127,11 @@ void VisualServerRaster::texture_debug_usage(List<TextureInfo> *r_info){
rasterizer->texture_debug_usage(r_info);
}
void VisualServerRaster::texture_set_shrink_all_x2_on_set_data(bool p_enable) {
rasterizer->texture_set_shrink_all_x2_on_set_data(p_enable);
}
/* SHADER API */
RID VisualServerRaster::shader_create(ShaderMode p_mode) {

View file

@ -659,7 +659,7 @@ public:
virtual RID texture_create();
virtual void texture_allocate(RID p_texture,int p_width, int p_height,Image::Format p_format,uint32_t p_flags=TEXTURE_FLAGS_DEFAULT);
virtual void texture_set_data(RID p_texture,const Image& p_image,CubeMapSide p_cube_side=CUBEMAP_LEFT);
virtual void texture_set_data(RID p_texture,const Image& p_image,CubeMapSide p_cube_side=CUBEMAP_LEFT);
virtual Image texture_get_data(RID p_texture,CubeMapSide p_cube_side=CUBEMAP_LEFT) const;
virtual void texture_set_flags(RID p_texture,uint32_t p_flags) ;
virtual uint32_t texture_get_flags(RID p_texture) const;
@ -675,6 +675,8 @@ public:
virtual void texture_debug_usage(List<TextureInfo> *r_info);
virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable);
/* SHADER API */

View file

@ -101,6 +101,8 @@ public:
FUNC2(texture_set_path,RID,const String&);
FUNC1RC(String,texture_get_path,RID);
FUNC1(texture_set_shrink_all_x2_on_set_data,bool);
virtual void texture_debug_usage(List<TextureInfo> *r_info) {
//pass directly, should lock the server anyway
visual_server->texture_debug_usage(r_info);

View file

@ -355,8 +355,12 @@ void VisualServer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("texture_get_flags"),&VisualServer::texture_get_flags );
ObjectTypeDB::bind_method(_MD("texture_get_width"),&VisualServer::texture_get_width );
ObjectTypeDB::bind_method(_MD("texture_get_height"),&VisualServer::texture_get_height );
ObjectTypeDB::bind_method(_MD("texture_set_shrink_all_x2_on_set_data","shrink"),&VisualServer::texture_set_shrink_all_x2_on_set_data );
#ifndef _3D_DISABLED
ObjectTypeDB::bind_method(_MD("shader_create","mode"),&VisualServer::shader_create,DEFVAL(SHADER_MATERIAL));
ObjectTypeDB::bind_method(_MD("shader_set_mode","shader","mode"),&VisualServer::shader_set_mode);

View file

@ -138,6 +138,8 @@ public:
virtual void texture_set_path(RID p_texture,const String& p_path)=0;
virtual String texture_get_path(RID p_texture) const=0;
virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable)=0;
struct TextureInfo {
RID texture;
Size2 size;