Chromium Code Reviews| Index: ui/gl/gl_image_memory.cc |
| diff --git a/ui/gl/gl_image_memory.cc b/ui/gl/gl_image_memory.cc |
| index e5160a6cbec3c4e5e59e43018b36d431209ac0c7..1feb59c2e8bfc9d6d0f0ef2f03eb92cc32602dae 100644 |
| --- a/ui/gl/gl_image_memory.cc |
| +++ b/ui/gl/gl_image_memory.cc |
| @@ -143,6 +143,30 @@ GLsizei SizeInBytes(const Size& size, BufferFormat format) { |
| return static_cast<GLsizei>(stride_in_bytes * size.height()); |
| } |
| +bool GetTextureBindingForTarget(GLenum target, GLenum* binding) { |
| + switch (target) { |
| + case GL_TEXTURE_2D: |
| + *binding = GL_TEXTURE_BINDING_2D; |
| + return true; |
| + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: |
| + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: |
| + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: |
| + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: |
| + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: |
| + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: |
| + *binding = GL_TEXTURE_BINDING_CUBE_MAP; |
| + return true; |
| + case GL_TEXTURE_RECTANGLE_ARB: |
| + *binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; |
| + return true; |
| + case GL_TEXTURE_EXTERNAL_OES: |
| + *binding = GL_TEXTURE_BINDING_EXTERNAL_OES; |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| } // namespace |
| GLImageMemory::GLImageMemory(const Size& size, unsigned internalformat) |
| @@ -152,11 +176,12 @@ GLImageMemory::GLImageMemory(const Size& size, unsigned internalformat) |
| format_(BufferFormat::RGBA_8888), |
| in_use_(false), |
| target_(0), |
| - need_do_bind_tex_image_(false) |
| + need_do_bind_tex_image_(false), |
| + texture_id_(0u), |
| + need_to_free_texture_id_(false) |
| #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ |
| defined(USE_OZONE) |
| , |
| - egl_texture_id_(0u), |
| egl_image_(EGL_NO_IMAGE_KHR) |
| #endif |
| { |
| @@ -166,7 +191,7 @@ GLImageMemory::~GLImageMemory() { |
| #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ |
| defined(USE_OZONE) |
| DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_); |
| - DCHECK_EQ(0u, egl_texture_id_); |
| + DCHECK_IMPLIES(need_to_free_texture_id_, texture_id_ == 0u); |
| #endif |
| } |
| @@ -245,10 +270,10 @@ void GLImageMemory::Destroy(bool have_context) { |
| egl_image_ = EGL_NO_IMAGE_KHR; |
| } |
| - if (egl_texture_id_) { |
| + if (texture_id_ && need_to_free_texture_id_) { |
| if (have_context) |
| - glDeleteTextures(1, &egl_texture_id_); |
| - egl_texture_id_ = 0u; |
| + glDeleteTextures(1, &texture_id_); |
| + texture_id_ = 0u; |
| } |
| #endif |
| memory_ = NULL; |
| @@ -352,11 +377,12 @@ void GLImageMemory::DoBindTexImage(unsigned target) { |
| defined(USE_OZONE) |
| if (target == GL_TEXTURE_EXTERNAL_OES) { |
| if (egl_image_ == EGL_NO_IMAGE_KHR) { |
| - DCHECK_EQ(0u, egl_texture_id_); |
| - glGenTextures(1, &egl_texture_id_); |
| + DCHECK_EQ(0u, texture_id_); |
| + glGenTextures(1, &texture_id_); |
| + need_to_free_texture_id_ = true; |
| { |
| - ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); |
| + ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| @@ -384,16 +410,14 @@ void GLImageMemory::DoBindTexImage(unsigned target) { |
| EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; |
| // Need to pass current EGL rendering context to eglCreateImageKHR for |
| // target type EGL_GL_TEXTURE_2D_KHR. |
| - egl_image_ = |
| - eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), |
| - eglGetCurrentContext(), |
| - EGL_GL_TEXTURE_2D_KHR, |
| - reinterpret_cast<EGLClientBuffer>(egl_texture_id_), |
| - attrs); |
| + egl_image_ = eglCreateImageKHR( |
| + GLSurfaceEGL::GetHardwareDisplay(), eglGetCurrentContext(), |
| + EGL_GL_TEXTURE_2D_KHR, reinterpret_cast<EGLClientBuffer>(texture_id_), |
| + attrs); |
| DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) |
| << "Error creating EGLImage: " << eglGetError(); |
| } else { |
| - ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); |
| + ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_); |
| if (IsCompressedFormat(format_)) { |
| glCompressedTexSubImage2D(GL_TEXTURE_2D, |
| @@ -422,6 +446,27 @@ void GLImageMemory::DoBindTexImage(unsigned target) { |
| } |
| #endif |
| + // Make sure the same image is only ever bound to one texture. |
|
reveman
2015/08/31 17:38:48
I don't think any of this is needed as we will alw
ericrk
2015/08/31 18:31:14
sgtm - added a comment and used the original logic
|
| + GLenum binding; |
| + if (!GetTextureBindingForTarget(target, &binding)) { |
| + LOG(ERROR) << "Trying to bind image to an invalid target"; |
| + return; |
| + } |
| + |
| + GLuint texture_id; |
| + glGetIntegerv(binding, reinterpret_cast<GLint*>(&texture_id)); |
| + if (!texture_id) { |
| + LOG(ERROR) << "Trying to bind image without no texture bound"; |
| + return; |
| + } |
| + |
| + if (texture_id_ && texture_id_ != texture_id) { |
| + LOG(ERROR) << "Image can only be bound to one texture ID"; |
| + return; |
| + } |
| + |
| + texture_id_ = texture_id; |
| + |
| DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); |
| if (IsCompressedFormat(format_)) { |
| glCompressedTexImage2D(target, |
| @@ -446,14 +491,16 @@ void GLImageMemory::DoBindTexImage(unsigned target) { |
| void GLImageMemory::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, |
| uint64_t process_tracing_id, |
| const std::string& dump_name) { |
| - // Log size 0 if |ref_counted_memory_| has been released. |
| - size_t size_in_bytes = memory_ ? SizeInBytes(size_, format_) : 0; |
| + size_t size_in_bytes = texture_id_ ? SizeInBytes(size_, format_) : 0; |
| base::trace_event::MemoryAllocatorDump* dump = |
| - pmd->CreateAllocatorDump(dump_name); |
| + pmd->CreateAllocatorDump(dump_name + "/texture_memory"); |
| dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, |
| base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| static_cast<uint64_t>(size_in_bytes)); |
| + |
| + // No need for a global shared edge here. This object in the GPU process is |
| + // the sole owner of this texture id. |
| } |
| } // namespace gfx |