summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2016-05-04 12:36:51 -0300
committerJuan Linietsky <reduzio@gmail.com>2016-05-04 12:37:07 -0300
commit89d87294dbc84df8dd7740cd04cc4842b8738e96 (patch)
tree62d1015ed08cb12c6e57e6391d4f8cc9f32c355e
parent0fa5154c0af7895b0a5e11ff4899e12cc0cbbdd2 (diff)
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.
-rw-r--r--core/image.cpp60
-rw-r--r--core/image.h1
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp19
-rw-r--r--drivers/gles2/rasterizer_gles2.h4
-rw-r--r--servers/visual/rasterizer.h2
-rw-r--r--servers/visual/rasterizer_dummy.h2
-rw-r--r--servers/visual/visual_server_raster.cpp5
-rw-r--r--servers/visual/visual_server_raster.h4
-rw-r--r--servers/visual/visual_server_wrap_mt.h2
-rw-r--r--servers/visual_server.cpp4
-rw-r--r--servers/visual_server.h2
11 files changed, 103 insertions, 2 deletions
diff --git a/core/image.cpp b/core/image.cpp
index 52946bbb85..8635aa1b29 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -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)) {
diff --git a/core/image.h b/core/image.h
index fe1822f661..35bbd1a684 100644
--- a/core/image.h
+++ b/core/image.h
@@ -249,6 +249,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
*/
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 373de2bb22..20d1ca956a 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -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) {
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index 2a2f587f11..b52918c02f 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -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);
@@ -1336,6 +1338,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 */
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index e2de20785a..e3d1b14835 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -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;
diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h
index efa843839a..674c165966 100644
--- a/servers/visual/rasterizer_dummy.h
+++ b/servers/visual/rasterizer_dummy.h
@@ -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);
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 1db7971d3b..ad85ecc7c0 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -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) {
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 2b72b0b900..cb9e96e284 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -657,7 +657,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;
@@ -673,6 +673,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 */
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index b6018f1c25..6a42fcc8a6 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -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);
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 17d5b16b9f..5ac0e5b5d5 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -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);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index c70a72ef2a..750c090bbe 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -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;