diff --git a/cobalt/loader/image/image_data_decoder.cc b/cobalt/loader/image/image_data_decoder.cc index 0a19fdff7681..ea54006c4baf 100644 --- a/cobalt/loader/image/image_data_decoder.cc +++ b/cobalt/loader/image/image_data_decoder.cc @@ -119,7 +119,7 @@ std::unique_ptr ImageDataDecoder::AllocateImageData( size, pixel_format(), has_alpha ? render_tree::kAlphaFormatPremultiplied : render_tree::kAlphaFormatOpaque); - DLOG_IF(ERROR, !image_data) << "Failed to allocate image data (" + LOG_IF(ERROR, !image_data) << "Failed to allocate image data (" << size.width() << "x" << size.height() << ")."; return image_data; } @@ -127,8 +127,10 @@ std::unique_ptr ImageDataDecoder::AllocateImageData( scoped_refptr ImageDataDecoder::CreateStaticImage( std::unique_ptr image_data) { DCHECK(image_data); - return new StaticImage( - resource_provider()->CreateImage(std::move(image_data))); + auto img = resource_provider()->CreateImage(std::move(image_data)); + auto sz = img->GetEstimatedSizeInBytes(); + LOG(WARNING) << "Allocated " << sz << " bytes StaticImage"; + return new StaticImage(std::move(img)); } void ImageDataDecoder::CalculatePixelFormat() { diff --git a/cobalt/loader/resource_cache.h b/cobalt/loader/resource_cache.h index 7677f880d6b3..593c2eb33a48 100644 --- a/cobalt/loader/resource_cache.h +++ b/cobalt/loader/resource_cache.h @@ -931,7 +931,7 @@ void ResourceCache::ReclaimMemory(uint32 bytes_to_reclaim_down_to, // Log a warning if we're still over |bytes_to_reclaim_down_to| after // attempting to reclaim memory. This can occur validly when the size of // the referenced images exceeds the target size. - DLOG_IF(WARNING, memory_size_in_bytes_ > bytes_to_reclaim_down_to) + LOG_IF(WARNING, memory_size_in_bytes_ > bytes_to_reclaim_down_to) << "cached size: " << memory_size_in_bytes_ << ", target size: " << bytes_to_reclaim_down_to; } diff --git a/cobalt/renderer/backend/egl/framebuffer.cc b/cobalt/renderer/backend/egl/framebuffer.cc index 6348e81035f4..cd55ec73f5d2 100644 --- a/cobalt/renderer/backend/egl/framebuffer.cc +++ b/cobalt/renderer/backend/egl/framebuffer.cc @@ -80,6 +80,7 @@ FramebufferEGL::FramebufferEGL(GraphicsContextEGL* graphics_context, color_texture_.reset(new TextureEGL(graphics_context_, color_handle, size_, color_format, GL_TEXTURE_2D, base::Closure())); + LOG(WARNING) << "FramebufferEGL::FramebufferEGL new textureEGL: " << color_texture_->gl_handle(); // Create and attach a depth buffer if requested. depthbuffer_handle_ = 0; diff --git a/cobalt/renderer/backend/egl/graphics_context.cc b/cobalt/renderer/backend/egl/graphics_context.cc index d46389dc8910..394c0af2688c 100644 --- a/cobalt/renderer/backend/egl/graphics_context.cc +++ b/cobalt/renderer/backend/egl/graphics_context.cc @@ -360,8 +360,11 @@ void GraphicsContextEGL::ReleaseCurrentContext() { std::unique_ptr GraphicsContextEGL::CreateTexture( std::unique_ptr texture_data) { - return std::unique_ptr( + + auto ret = std::unique_ptr( new TextureEGL(this, std::move(texture_data), bgra_format_supported_)); + LOG(WARNING) << "GraphicsContextEGL::CreateTexture:" << ret->gl_handle(); + return ret; } std::unique_ptr GraphicsContextEGL::CreateTextureFromRawMemory( @@ -371,9 +374,12 @@ std::unique_ptr GraphicsContextEGL::CreateTextureFromRawMemory( const RawTextureMemoryEGL* texture_memory = &(raw_texture_memory->raw_texture_memory()); - return std::unique_ptr( + + auto ret = std::unique_ptr( new TextureEGL(this, texture_memory, offset, size, format, pitch_in_bytes, bgra_format_supported_)); + LOG(WARNING) << "GraphicsContextEGL::CreateTextureFromRawMemory: " << ret->gl_handle(); + return ret; } scoped_refptr GraphicsContextEGL::CreateOffscreenRenderTarget( @@ -439,6 +445,7 @@ std::unique_ptr GraphicsContextEGL::DownloadPixelDataAsRGBA( std::unique_ptr texture( new TextureEGL(this, pbuffer_render_target)); DCHECK(texture->GetSize() == render_target->GetSize()); + LOG(WARNING) << "GraphicsContextEGL::DownloadPixelDataAsRGBA:" << texture->gl_handle(); // This shouldn't be strictly necessary as glReadPixels() should implicitly // call glFinish(), however it doesn't hurt to be safe and guard against diff --git a/cobalt/renderer/backend/egl/texture.cc b/cobalt/renderer/backend/egl/texture.cc index 9039377a5d68..04c79ad2bf5d 100644 --- a/cobalt/renderer/backend/egl/texture.cc +++ b/cobalt/renderer/backend/egl/texture.cc @@ -46,6 +46,7 @@ TextureEGL::TextureEGL(GraphicsContextEGL* graphics_context, target_(GL_TEXTURE_2D) { gl_handle_ = texture_source_data->ConvertToTexture(graphics_context_, bgra_supported); + LOG(WARNING) << "TextureEGL::TextureEGL (ConvertToTexture)" << gl_handle_; } TextureEGL::TextureEGL(GraphicsContextEGL* graphics_context, @@ -58,6 +59,7 @@ TextureEGL::TextureEGL(GraphicsContextEGL* graphics_context, target_(GL_TEXTURE_2D) { gl_handle_ = data->CreateTexture(graphics_context_, offset, size, format, pitch_in_bytes, bgra_supported); + LOG(WARNING) << "TextureEGL::TextureEGL (CreateTexture)" << gl_handle_; } TextureEGL::TextureEGL(GraphicsContextEGL* graphics_context, GLuint gl_handle, @@ -98,6 +100,7 @@ TextureEGL::TextureEGL(GraphicsContextEGL* graphics_context, pbuffer_target->GetSurface(), EGL_BACK_BUFFER)); GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); + LOG(WARNING) << "TextureEGL::TextureEGL (render_target, has surface)" << gl_handle_; } else { // This is a FramebufferRenderTargetEGL. Wrap its color texture attachment. const FramebufferRenderTargetEGL* framebuffer_target = @@ -111,6 +114,7 @@ TextureEGL::TextureEGL(GraphicsContextEGL* graphics_context, // Do not destroy the wrapped texture. Let the render target do that. delete_function_ = base::Bind(&DoNothing); + LOG(WARNING) << "TextureEGL::TextureEGL (render_target, no surface)" << gl_handle_; } } diff --git a/cobalt/renderer/backend/egl/texture.h b/cobalt/renderer/backend/egl/texture.h index 7fe1ad224d5d..313798f580ba 100644 --- a/cobalt/renderer/backend/egl/texture.h +++ b/cobalt/renderer/backend/egl/texture.h @@ -16,6 +16,7 @@ #define COBALT_RENDERER_BACKEND_EGL_TEXTURE_H_ #include + #include "base/callback.h" #include "cobalt/renderer/backend/egl/render_target.h" #include "cobalt/renderer/backend/egl/texture_data.h" @@ -83,7 +84,7 @@ class TextureEGL { GLenum target_; // The OpenGL handle to the texture that can be passed into OpenGL functions. - GLuint gl_handle_; + GLuint gl_handle_ = 0; // If the texture was constructed from a render target, we keep a reference // to the render target. diff --git a/cobalt/renderer/backend/egl/texture_data_cpu.cc b/cobalt/renderer/backend/egl/texture_data_cpu.cc index 4dfbdf6fe004..43776d5de405 100644 --- a/cobalt/renderer/backend/egl/texture_data_cpu.cc +++ b/cobalt/renderer/backend/egl/texture_data_cpu.cc @@ -15,6 +15,7 @@ #include "cobalt/renderer/backend/egl/texture_data_cpu.h" #include + #include "base/memory/aligned_memory.h" #include "cobalt/renderer/backend/egl/graphics_context.h" #include "cobalt/renderer/backend/egl/utils.h" @@ -31,7 +32,7 @@ GLuint UploadPixelDataToNewTexture(GraphicsContextEGL* graphics_context, const uint8_t* data, const math::Size& size, GLenum format, int pitch_in_bytes, bool bgra_supported) { - GLuint texture_handle; + GLuint texture_handle = 0; GraphicsContextEGL::ScopedMakeCurrent scoped_make_current(graphics_context); diff --git a/cobalt/renderer/rasterizer/egl/software_rasterizer.cc b/cobalt/renderer/rasterizer/egl/software_rasterizer.cc index 92316a8c9fda..3095eebe3380 100644 --- a/cobalt/renderer/rasterizer/egl/software_rasterizer.cc +++ b/cobalt/renderer/rasterizer/egl/software_rasterizer.cc @@ -83,6 +83,7 @@ void SoftwareRasterizer::Submit( // The rasterized pixels are still on the CPU, ship them off to the GPU // for output to the display. We must first create a backend GPU texture // with the data so that it is visible to the GPU. + LOG(WARNING) << "SoftwareRasterizer::Submit creating Texture"; std::unique_ptr output_texture = context_->CreateTexture(std::move(bitmap_pixels)); diff --git a/cobalt/renderer/rasterizer/skia/hardware_image.cc b/cobalt/renderer/rasterizer/skia/hardware_image.cc index bd9a2c33bc30..d60e63b252c5 100644 --- a/cobalt/renderer/rasterizer/skia/hardware_image.cc +++ b/cobalt/renderer/rasterizer/skia/hardware_image.cc @@ -137,6 +137,7 @@ class HardwareFrontendImage::HardwareBackendImage { "HardwareBackendImage::InitializeFromImageData()"); backend->texture_ = cobalt_context->CreateTexture(image_data->PassTextureData()); + LOG(WARNING) << "HardwareBackendImage::InitializeFromImageData:" << backend->texture_->gl_handle(); backend->CommonInitialize(gr_context, cobalt_context); } @@ -151,6 +152,7 @@ class HardwareFrontendImage::HardwareBackendImage { texture_memory, offset, descriptor.size, ConvertRenderTreeFormatToGL(descriptor.pixel_format), descriptor.pitch_in_bytes); + LOG(WARNING) << "HardwareBackendImage::InitializeFromRawImageData:" << backend->texture_->gl_handle(); backend->CommonInitialize(gr_context, cobalt_context); } @@ -160,6 +162,7 @@ class HardwareFrontendImage::HardwareBackendImage { TRACE_EVENT0("cobalt::renderer", "HardwareBackendImage::InitializeFromTexture()"); backend->texture_ = std::move(texture); + LOG(WARNING) << "HardwareBackendImage::InitializeFromTexture:" << backend->texture_->gl_handle(); backend::GraphicsContextEGL* cobalt_context = backend->texture_->graphics_context(); backend->CommonInitialize(gr_context, cobalt_context); @@ -187,6 +190,7 @@ class HardwareFrontendImage::HardwareBackendImage { std::unique_ptr texture( new backend::TextureEGL(cobalt_context, render_target)); + LOG(WARNING) << "HardwareFrontEndImage::InitializeFromRenderTree: " << texture->gl_handle(); InitializeFromTexture(std::move(texture), gr_context, backend); @@ -297,6 +301,11 @@ math::Size AdjustSizeForFormat( } } // namespace +#define LHANDLE(message, backend_image) \ + { \ + LOG(WARNING) << message; \ + } + HardwareFrontendImage::HardwareFrontendImage( std::unique_ptr image_data, backend::GraphicsContextEGL* cobalt_context, GrContext* gr_context, @@ -311,6 +320,7 @@ HardwareFrontendImage::HardwareFrontendImage( backend_image_.reset(new HardwareBackendImage( base::Bind(&HardwareBackendImage::InitializeFromImageData, base::Passed(&image_data), cobalt_context, gr_context))); + LHANDLE("HardwareFrontendImage::HardwareFrontendImage 1 (HardwareImageData) : ",backend_image_); InitializeBackend(); } @@ -329,6 +339,7 @@ HardwareFrontendImage::HardwareFrontendImage( backend_image_.reset(new HardwareBackendImage(base::Bind( &HardwareBackendImage::InitializeFromRawImageData, raw_texture_memory, offset, descriptor, cobalt_context, gr_context))); + LHANDLE("HardwareFrontendImage::HardwareFrontendImage 2 (ConstRawTextureMemoryEGL) : ",backend_image_); InitializeBackend(); } @@ -353,6 +364,7 @@ HardwareFrontendImage::HardwareFrontendImage( backend_image_.reset(new HardwareBackendImage( base::Bind(&HardwareBackendImage::InitializeFromTexture, base::Passed(&texture), gr_context))); + LHANDLE("HardwareFrontendImage::HardwareFrontendImage 3 (backend::TextureEGL) : ",backend_image_); InitializeBackend(); } @@ -372,6 +384,7 @@ HardwareFrontendImage::HardwareFrontendImage( backend_image_.reset(new HardwareBackendImage( base::Bind(&HardwareBackendImage::InitializeFromRenderTree, root, size_, submit_offscreen_callback, cobalt_context, gr_context))); + LHANDLE("HardwareFrontendImage::HardwareFrontendImage 4 (render_tree::Node) : ",backend_image_); InitializeBackend(); } diff --git a/cobalt/renderer/rasterizer/skia/hardware_resource_provider.cc b/cobalt/renderer/rasterizer/skia/hardware_resource_provider.cc index 6b7a91e8b147..ace01bca781e 100644 --- a/cobalt/renderer/rasterizer/skia/hardware_resource_provider.cc +++ b/cobalt/renderer/rasterizer/skia/hardware_resource_provider.cc @@ -153,6 +153,7 @@ scoped_refptr HardwareResourceProvider::CreateImage( } #endif + LOG(WARNING) << "HardwareResourceProvider::CreateImage HardwareFrontendImage"; // Construct a frontend image from this data, which internally will send // a message to the rasterizer thread passing along the image data where the // backend texture will be constructed, and associated with this frontend @@ -307,6 +308,7 @@ HardwareResourceProvider::CreateImageFromSbDecodeTarget( cobalt_context_, gl_handle, math::Size(plane.width, plane.height), gl_format, plane.gl_texture_target, base::BindOnce(&DoNothing, decode_target_ref))); + LOG(WARNING) << "HardwareResourceProvider::CreateImageFromSbDecodeTarget: " << texture->gl_handle(); // If the decode target is specified as UYVY format, then we need to pass // this in as supplementary data, as the |texture| object only knows that @@ -316,6 +318,7 @@ HardwareResourceProvider::CreateImageFromSbDecodeTarget( alternate_rgba_format = AlternateRgbaFormat_UYVY; } + LOG(WARNING) << "HardwareResourceProvider::CreateImageFromSbDecodeTarget HardwareFrontendImage"; planes.push_back(base::WrapRefCounted(new HardwareFrontendImage( std::move(texture), alpha_format, cobalt_context_, gr_context_, std::move(content_region), rasterizer_task_runner_, @@ -325,6 +328,7 @@ HardwareResourceProvider::CreateImageFromSbDecodeTarget( if (planes_per_format == 1) { return planes[0]; } else { + LOG(WARNING) << "HardwareResourceProvider::CreateImageFromSbDecodeTarget HardwareMultiPlaneImage"; return new HardwareMultiPlaneImage( DecodeTargetFormatToRenderTreeMultiPlaneFormat(info.format), planes); } @@ -561,6 +565,7 @@ scoped_refptr HardwareResourceProvider::CreateMesh( scoped_refptr HardwareResourceProvider::DrawOffscreenImage( const scoped_refptr& root) { + LOG(WARNING) << "HardwareResourceProvider::DrawOffscreenImage HardwareFrontendImage"; return base::WrapRefCounted(new HardwareFrontendImage( root, submit_offscreen_callback_, cobalt_context_, gr_context_, rasterizer_task_runner_)); diff --git a/cobalt/renderer/rasterizer/skia/software_image.cc b/cobalt/renderer/rasterizer/skia/software_image.cc index b5ce2479cb93..685ad20c3dc0 100644 --- a/cobalt/renderer/rasterizer/skia/software_image.cc +++ b/cobalt/renderer/rasterizer/skia/software_image.cc @@ -43,12 +43,14 @@ std::unique_ptr SoftwareImageData::PassPixelData() { } SoftwareImage::SoftwareImage(std::unique_ptr source_data) { + LOG(WARNING) << "SoftwareImage::SoftwareImage (SoftwareImageData)"; owned_pixel_data_ = source_data->PassPixelData(); Initialize(owned_pixel_data_.get(), source_data->GetDescriptor()); } SoftwareImage::SoftwareImage( uint8_t* source_data, const render_tree::ImageDataDescriptor& descriptor) { + LOG(WARNING) << "SoftwareImage::SoftwareImage (ImageDataDescriptor)"; Initialize(source_data, descriptor); } diff --git a/cobalt/renderer/rasterizer/skia/software_resource_provider.cc b/cobalt/renderer/rasterizer/skia/software_resource_provider.cc index 25f9813ad42c..18998aee30f9 100644 --- a/cobalt/renderer/rasterizer/skia/software_resource_provider.cc +++ b/cobalt/renderer/rasterizer/skia/software_resource_provider.cc @@ -88,6 +88,7 @@ scoped_refptr SoftwareResourceProvider::CreateImage( std::unique_ptr skia_source_data( base::polymorphic_downcast(source_data.release())); + LOG(WARNING) << "SoftwareResourceProvider::CreateImage making SoftwareImage"; return scoped_refptr( new SoftwareImage(std::move(skia_source_data))); } diff --git a/starboard/raspi/shared/system_gles2.cc b/starboard/raspi/shared/system_gles2.cc index fd9140d05d4e..16220cf746dc 100644 --- a/starboard/raspi/shared/system_gles2.cc +++ b/starboard/raspi/shared/system_gles2.cc @@ -15,8 +15,205 @@ #include #include +#include +#include +#include "starboard/common/log.h" #include "starboard/gles.h" +#define GL_MEM_TRACE(x) trace_##x + +enum Objects { Buffers = 0, Textures = 1, Renderbuffers = 2 }; + +const char* type2str(Objects type) { + switch (type) { + case Buffers: + return "buffers"; + case Textures: + return "textures"; + case Renderbuffers: + return "renderbuffers"; + default: + SB_NOTREACHED(); + } + return ""; +} + +using MemObjects = std::map; +struct TrackedMemObject { + GLuint active = 0; + MemObjects objects; + size_t total_allocation = 0; +}; + +TrackedMemObject* getObjects() { + static TrackedMemObject objects[3] = { + TrackedMemObject(), + TrackedMemObject(), + TrackedMemObject(), + }; + return objects; +} + +void genObjects(Objects type, GLsizei n, GLuint* objects) { + TrackedMemObject& tracked_object = getObjects()[type]; + MemObjects& map = tracked_object.objects; + for (GLsizei i = 0; i < n; i++) { + GLuint object_id = objects[i]; + auto existing = map.find(object_id); + SB_CHECK(existing == map.end()); + map.insert(std::make_pair(object_id, 0)); + SB_LOG(ERROR) << "GLTRACE: added type:" << type2str(type) + << " object:" << object_id << " p:" << &tracked_object; + } +} +void deleteObjects(Objects type, GLsizei n, const GLuint* objects) { + TrackedMemObject& tracked_object = getObjects()[type]; + MemObjects& map = tracked_object.objects; + for (GLsizei i = 0; i < n; i++) { + GLuint object_id = objects[i]; + auto existing = map.find(object_id); + SB_CHECK(existing != map.end()); + if (existing->second != 0) { + SB_LOG(ERROR) << "GLTRACE: Released alloc for type:" << type2str(type) + << " size: " << existing->second + << " total:" << tracked_object.total_allocation << " (MB:" + << (tracked_object.total_allocation / (1024 * 1024)) << ")"; + } + tracked_object.total_allocation -= existing->second; + map.erase(existing); + } +} +void bindObject(Objects type, GLuint object) { + TrackedMemObject& tracked_object = getObjects()[type]; + MemObjects& map = tracked_object.objects; + tracked_object.active = object; + if (object == 0) + return; + auto existing = map.find(object); + if (existing == map.end()) { + SB_LOG(ERROR) << "GLTRACE: Cannot find object to bind, type:" + << type2str(type) << " object:" << object; + SB_CHECK(existing != map.end()); + } +} +void reportAllocation(Objects type, size_t estimated_allocation) { + TrackedMemObject& tracked_object = getObjects()[type]; + MemObjects& map = tracked_object.objects; + auto existing = map.find(tracked_object.active); + SB_CHECK(existing != map.end()); + auto previous = tracked_object.total_allocation; + // First subtract the previous allocation + tracked_object.total_allocation -= existing->second; + // update and add + existing->second = estimated_allocation; + tracked_object.total_allocation += existing->second; + auto mb_alloc = (tracked_object.total_allocation / (1024 * 1024)); + if (mb_alloc > 0 && previous != tracked_object.total_allocation) { + SB_LOG(ERROR) << "GLTRACE: Alloc for type:" << type2str(type) + << " size: " << estimated_allocation + << " total:" << tracked_object.total_allocation << " (MB:" + << (tracked_object.total_allocation / (1024 * 1024)) << ")"; + } +} + +// Buffers +void GL_MEM_TRACE(glGenBuffers)(GLsizei n, GLuint* buffers) { + glGenBuffers(n, buffers); + genObjects(Buffers, n, buffers); +} +void GL_MEM_TRACE(glDeleteBuffers)(GLsizei n, const GLuint* buffers) { + glDeleteBuffers(n, buffers); + deleteObjects(Buffers, n, buffers); +} +void GL_MEM_TRACE(glBindBuffer)(GLenum target, GLuint buffer) { + glBindBuffer(target, buffer); + bindObject(Buffers, buffer); +} +void GL_MEM_TRACE(glBufferData)(GLenum target, + GLsizeiptr size, + const void* data, + GLenum usage) { + glBufferData(target, size, data, usage); + reportAllocation(Buffers, size); +} + +// Textures +void GL_MEM_TRACE(glGenTextures)(GLsizei n, GLuint* textures) { + glGenTextures(n, textures); + genObjects(Textures, n, textures); +} +void GL_MEM_TRACE(glDeleteTextures)(GLsizei n, const GLuint* textures) { + glDeleteTextures(n, textures); + deleteObjects(Textures, n, textures); +} +void GL_MEM_TRACE(glBindTexture)(GLenum target, GLuint texture) { + glBindTexture(target, texture); + bindObject(Textures, texture); +} + +size_t estimate_bytes_per_pixel(GLenum format) { + switch (format) { + case GL_RGB: + return 3; + case GL_RGBA: + return 4; + case GL_LUMINANCE: + case GL_ALPHA: + return 1; + default: + return 4; // overcount + } +} + +void GL_MEM_TRACE(glTexImage2D)(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void* pixels) { + glTexImage2D(target, level, internalformat, width, height, border, format, + type, pixels); + reportAllocation(Textures, width * height * estimate_bytes_per_pixel(format)); +} +void GL_MEM_TRACE(glTexSubImage2D)(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void* pixels) { + glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, + pixels); + reportAllocation(Textures, width * height * estimate_bytes_per_pixel(format)); +} + +// Renderbuffers +void GL_MEM_TRACE(glGenRenderbuffers)(GLsizei n, GLuint* renderbuffers) { + glGenRenderbuffers(n, renderbuffers); + genObjects(Renderbuffers, n, renderbuffers); +} +void GL_MEM_TRACE(glDeleteRenderbuffers)(GLsizei n, + const GLuint* renderbuffers) { + glDeleteRenderbuffers(n, renderbuffers); + deleteObjects(Renderbuffers, n, renderbuffers); +} +void GL_MEM_TRACE(glBindRenderbuffer)(GLenum target, GLuint renderbuffer) { + glBindRenderbuffer(target, renderbuffer); + bindObject(Renderbuffers, renderbuffer); +} +void GL_MEM_TRACE(glRenderbufferStorage)(GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height) { + glRenderbufferStorage(target, internalformat, width, height); + reportAllocation(Renderbuffers, width * height * 4); +} + namespace { void SbGlShaderSource(SbGlUInt32 shader, @@ -27,20 +224,28 @@ void SbGlShaderSource(SbGlUInt32 shader, glShaderSource(shader, count, const_cast(string), length); } +const GLubyte* patch_glGetString(GLenum name) { + if (name == GL_EXTENSIONS) { + static const unsigned char dummy[1] = {'\0'}; + return dummy; + } + return glGetString(name); +} + const SbGlesInterface g_sb_gles_interface = { &glActiveTexture, &glAttachShader, &glBindAttribLocation, - &glBindBuffer, + &GL_MEM_TRACE(glBindBuffer), &glBindFramebuffer, - &glBindRenderbuffer, - &glBindTexture, + &GL_MEM_TRACE(glBindRenderbuffer), + &GL_MEM_TRACE(glBindTexture), &glBlendColor, &glBlendEquation, &glBlendEquationSeparate, &glBlendFunc, &glBlendFuncSeparate, - &glBufferData, + &GL_MEM_TRACE(glBufferData), &glBufferSubData, &glCheckFramebufferStatus, &glClear, @@ -56,12 +261,12 @@ const SbGlesInterface g_sb_gles_interface = { &glCreateProgram, &glCreateShader, &glCullFace, - &glDeleteBuffers, + &GL_MEM_TRACE(glDeleteBuffers), &glDeleteFramebuffers, &glDeleteProgram, - &glDeleteRenderbuffers, + &GL_MEM_TRACE(glDeleteRenderbuffers), &glDeleteShader, - &glDeleteTextures, + &GL_MEM_TRACE(glDeleteTextures), &glDepthFunc, &glDepthMask, &glDepthRangef, @@ -77,11 +282,11 @@ const SbGlesInterface g_sb_gles_interface = { &glFramebufferRenderbuffer, &glFramebufferTexture2D, &glFrontFace, - &glGenBuffers, + &GL_MEM_TRACE(glGenBuffers), &glGenerateMipmap, &glGenFramebuffers, - &glGenRenderbuffers, - &glGenTextures, + &GL_MEM_TRACE(glGenRenderbuffers), + &GL_MEM_TRACE(glGenTextures), &glGetActiveAttrib, &glGetActiveUniform, &glGetAttachedShaders, @@ -99,7 +304,7 @@ const SbGlesInterface g_sb_gles_interface = { &glGetShaderInfoLog, &glGetShaderPrecisionFormat, &glGetShaderSource, - &glGetString, + &patch_glGetString, &glGetTexParameterfv, &glGetTexParameteriv, &glGetUniformfv, @@ -122,7 +327,7 @@ const SbGlesInterface g_sb_gles_interface = { &glPolygonOffset, &glReadPixels, &glReleaseShaderCompiler, - &glRenderbufferStorage, + &GL_MEM_TRACE(glRenderbufferStorage), &glSampleCoverage, &glScissor, &glShaderBinary, @@ -133,12 +338,12 @@ const SbGlesInterface g_sb_gles_interface = { &glStencilMaskSeparate, &glStencilOp, &glStencilOpSeparate, - &glTexImage2D, + &GL_MEM_TRACE(glTexImage2D), &glTexParameterf, &glTexParameterfv, &glTexParameteri, &glTexParameteriv, - &glTexSubImage2D, + &GL_MEM_TRACE(glTexSubImage2D), &glUniform1f, &glUniform1fv, &glUniform1i, diff --git a/starboard/shared/gles/system_gles2.cc b/starboard/shared/gles/system_gles2.cc index a0ccae9c7386..12688a957e3e 100644 --- a/starboard/shared/gles/system_gles2.cc +++ b/starboard/shared/gles/system_gles2.cc @@ -15,24 +15,229 @@ #include #include +#include +#include +#include "starboard/common/log.h" #include "starboard/gles.h" +#define GL_MEM_TRACE(x) trace_##x + +enum Objects { Buffers = 0, Textures = 1, Renderbuffers = 2 }; + +const char* type2str(Objects type) { + switch (type) { + case Buffers: + return "buffers"; + case Textures: + return "textures"; + case Renderbuffers: + return "renderbuffers"; + default: + SB_NOTREACHED(); + } +} + +using MemObjects = std::map; +struct TrackedMemObject { + GLuint active = 0; + MemObjects objects; + size_t total_allocation = 0; +}; + +TrackedMemObject* getObjects() { + static TrackedMemObject objects[3] = { + TrackedMemObject(), + TrackedMemObject(), + TrackedMemObject(), + }; + return objects; +} + +void genObjects(Objects type, GLsizei n, GLuint* objects) { + TrackedMemObject& tracked_object = getObjects()[type]; + MemObjects& map = tracked_object.objects; + for (GLsizei i = 0; i < n; i++) { + GLuint object_id = objects[i]; + auto existing = map.find(object_id); + SB_CHECK(existing == map.end()); + map.insert(std::make_pair(object_id, 0)); + SB_LOG(ERROR) << "GLTRACE: added type:" << type2str(type) + << " object:" << object_id << " p:" << &tracked_object; + } +} +void deleteObjects(Objects type, GLsizei n, const GLuint* objects) { + TrackedMemObject& tracked_object = getObjects()[type]; + MemObjects& map = tracked_object.objects; + for (GLsizei i = 0; i < n; i++) { + GLuint object_id = objects[i]; + auto existing = map.find(object_id); + SB_CHECK(existing != map.end()); + if (existing->second != 0) { + SB_LOG(ERROR) << "GLTRACE: Released alloc for type:" << type2str(type) + << " size: " << existing->second + << " total:" << tracked_object.total_allocation << " (MB:" + << (tracked_object.total_allocation / (1024 * 1024)) << ")"; + } + tracked_object.total_allocation -= existing->second; + map.erase(existing); + } +} +void bindObject(Objects type, GLuint object) { + TrackedMemObject& tracked_object = getObjects()[type]; + MemObjects& map = tracked_object.objects; + tracked_object.active = object; + if (object == 0) + return; + auto existing = map.find(object); + if (existing == map.end()) { + SB_LOG(ERROR) << "GLTRACE: Cannot find object to bind, type:" + << type2str(type) << " object:" << object; + SB_CHECK(existing != map.end()); + } +} +void reportAllocation(Objects type, size_t estimated_allocation) { + TrackedMemObject& tracked_object = getObjects()[type]; + MemObjects& map = tracked_object.objects; + auto existing = map.find(tracked_object.active); + SB_CHECK(existing != map.end()); + auto previous = tracked_object.total_allocation; + // First subtract the previous allocation + tracked_object.total_allocation -= existing->second; + // update and add + existing->second = estimated_allocation; + tracked_object.total_allocation += existing->second; + auto mb_alloc = (tracked_object.total_allocation / (1024 * 1024)); + if (mb_alloc > 0 && previous != tracked_object.total_allocation) { + SB_LOG(ERROR) << "GLTRACE: Alloc for type:" << type2str(type) + << " size: " << estimated_allocation + << " total:" << tracked_object.total_allocation << " (MB:" + << (tracked_object.total_allocation / (1024 * 1024)) << ")"; + } +} + +// Buffers +void GL_MEM_TRACE(glGenBuffers)(GLsizei n, GLuint* buffers) { + glGenBuffers(n, buffers); + genObjects(Buffers, n, buffers); +} +void GL_MEM_TRACE(glDeleteBuffers)(GLsizei n, const GLuint* buffers) { + glDeleteBuffers(n, buffers); + deleteObjects(Buffers, n, buffers); +} +void GL_MEM_TRACE(glBindBuffer)(GLenum target, GLuint buffer) { + glBindBuffer(target, buffer); + bindObject(Buffers, buffer); +} +void GL_MEM_TRACE(glBufferData)(GLenum target, + GLsizeiptr size, + const void* data, + GLenum usage) { + glBufferData(target, size, data, usage); + reportAllocation(Buffers, size); +} + +// Textures +void GL_MEM_TRACE(glGenTextures)(GLsizei n, GLuint* textures) { + glGenTextures(n, textures); + genObjects(Textures, n, textures); +} +void GL_MEM_TRACE(glDeleteTextures)(GLsizei n, const GLuint* textures) { + glDeleteTextures(n, textures); + deleteObjects(Textures, n, textures); +} +void GL_MEM_TRACE(glBindTexture)(GLenum target, GLuint texture) { + glBindTexture(target, texture); + bindObject(Textures, texture); +} + +size_t estimate_bytes_per_pixel(GLenum format) { + switch (format) { + case GL_RGB: + return 3; + case GL_RGBA: + return 4; + case GL_LUMINANCE: + case GL_ALPHA: + return 1; + default: + return 4; // overcount + } +} + +void GL_MEM_TRACE(glTexImage2D)(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void* pixels) { + glTexImage2D(target, level, internalformat, width, height, border, format, + type, pixels); + reportAllocation(Textures, width * height * estimate_bytes_per_pixel(format)); +} +void GL_MEM_TRACE(glTexSubImage2D)(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void* pixels) { + glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, + pixels); + reportAllocation(Textures, width * height * estimate_bytes_per_pixel(format)); +} + +// Renderbuffers +void GL_MEM_TRACE(glGenRenderbuffers)(GLsizei n, GLuint* renderbuffers) { + glGenRenderbuffers(n, renderbuffers); + genObjects(Renderbuffers, n, renderbuffers); +} +void GL_MEM_TRACE(glDeleteRenderbuffers)(GLsizei n, + const GLuint* renderbuffers) { + glDeleteRenderbuffers(n, renderbuffers); + deleteObjects(Renderbuffers, n, renderbuffers); +} +void GL_MEM_TRACE(glBindRenderbuffer)(GLenum target, GLuint renderbuffer) { + glBindRenderbuffer(target, renderbuffer); + bindObject(Renderbuffers, renderbuffer); +} +void GL_MEM_TRACE(glRenderbufferStorage)(GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height) { + glRenderbufferStorage(target, internalformat, width, height); + reportAllocation(Renderbuffers, width * height * 4); +} + +// Disable all extensions +const GLubyte* patch_glGetString(GLenum name) { + if (name == GL_EXTENSIONS) { + static const unsigned char dummy[1] = {'\0'}; + return dummy; + } + return glGetString(name); +} + namespace { const SbGlesInterface g_sb_gles_interface = { &glActiveTexture, &glAttachShader, &glBindAttribLocation, - &glBindBuffer, + &GL_MEM_TRACE(glBindBuffer), &glBindFramebuffer, - &glBindRenderbuffer, - &glBindTexture, + &GL_MEM_TRACE(glBindRenderbuffer), + &GL_MEM_TRACE(glBindTexture), &glBlendColor, &glBlendEquation, &glBlendEquationSeparate, &glBlendFunc, &glBlendFuncSeparate, - &glBufferData, + &GL_MEM_TRACE(glBufferData), &glBufferSubData, &glCheckFramebufferStatus, &glClear, @@ -48,12 +253,12 @@ const SbGlesInterface g_sb_gles_interface = { &glCreateProgram, &glCreateShader, &glCullFace, - &glDeleteBuffers, + &GL_MEM_TRACE(glDeleteBuffers), &glDeleteFramebuffers, &glDeleteProgram, - &glDeleteRenderbuffers, + &GL_MEM_TRACE(glDeleteRenderbuffers), &glDeleteShader, - &glDeleteTextures, + &GL_MEM_TRACE(glDeleteTextures), &glDepthFunc, &glDepthMask, &glDepthRangef, @@ -69,11 +274,11 @@ const SbGlesInterface g_sb_gles_interface = { &glFramebufferRenderbuffer, &glFramebufferTexture2D, &glFrontFace, - &glGenBuffers, + &GL_MEM_TRACE(glGenBuffers), &glGenerateMipmap, &glGenFramebuffers, - &glGenRenderbuffers, - &glGenTextures, + &GL_MEM_TRACE(glGenRenderbuffers), + &GL_MEM_TRACE(glGenTextures), &glGetActiveAttrib, &glGetActiveUniform, &glGetAttachedShaders, @@ -91,7 +296,7 @@ const SbGlesInterface g_sb_gles_interface = { &glGetShaderInfoLog, &glGetShaderPrecisionFormat, &glGetShaderSource, - &glGetString, + &patch_glGetString, &glGetTexParameterfv, &glGetTexParameteriv, &glGetUniformfv, @@ -114,7 +319,7 @@ const SbGlesInterface g_sb_gles_interface = { &glPolygonOffset, &glReadPixels, &glReleaseShaderCompiler, - &glRenderbufferStorage, + &GL_MEM_TRACE(glRenderbufferStorage), &glSampleCoverage, &glScissor, &glShaderBinary, @@ -125,12 +330,12 @@ const SbGlesInterface g_sb_gles_interface = { &glStencilMaskSeparate, &glStencilOp, &glStencilOpSeparate, - &glTexImage2D, + &GL_MEM_TRACE(glTexImage2D), &glTexParameterf, &glTexParameterfv, &glTexParameteri, &glTexParameteriv, - &glTexSubImage2D, + &GL_MEM_TRACE(glTexSubImage2D), &glUniform1f, &glUniform1fv, &glUniform1i, diff --git a/third_party/skia/src/gpu/GrBackendSurface.cpp b/third_party/skia/src/gpu/GrBackendSurface.cpp index fa95520811d5..e55dd2fbb32c 100644 --- a/third_party/skia/src/gpu/GrBackendSurface.cpp +++ b/third_party/skia/src/gpu/GrBackendSurface.cpp @@ -10,6 +10,8 @@ #include "src/gpu/gl/GrGLUtil.h" +#include + #ifdef SK_DAWN #include "include/gpu/dawn/GrDawnTypes.h" #include "src/gpu/dawn/GrDawnUtil.h" @@ -311,7 +313,9 @@ GrBackendTexture::GrBackendTexture(int width, , fHeight(height) , fMipMapped(mipMapped) , fBackend(GrBackendApi::kOpenGL) - , fGLInfo(glInfo, params.release()) {} + , fGLInfo(glInfo, params.release()) { + SB_LOG(WARNING) << "GrBackendTexture::GrBackendTexture :" << glInfo.fID; + } sk_sp GrBackendTexture::getGLTextureParams() const { if (fBackend != GrBackendApi::kOpenGL) {