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 |