Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gl/gl_image_egl.h" | 5 #include "ui/gl/gl_image_android_native_buffer.h" |
| 6 | 6 |
| 7 #include "ui/gl/gl_bindings.h" | |
| 8 #include "ui/gl/gl_surface_egl.h" | 7 #include "ui/gl/gl_surface_egl.h" |
| 9 #include "ui/gl/scoped_binders.h" | 8 #include "ui/gl/scoped_binders.h" |
| 10 | 9 |
| 11 namespace gfx { | 10 namespace gfx { |
| 12 | 11 |
| 13 GLImageEGL::GLImageEGL(gfx::Size size) | 12 GLImageAndroidNativeBuffer::GLImageAndroidNativeBuffer(gfx::Size size) |
| 14 : egl_image_(EGL_NO_IMAGE_KHR), | 13 : GLImageEGL(size), |
| 15 size_(size), | |
| 16 release_after_use_(false), | 14 release_after_use_(false), |
| 17 in_use_(false), | 15 in_use_(false), |
| 18 target_(0), | 16 target_(0), |
| 19 egl_image_for_unbind_(EGL_NO_IMAGE_KHR), | 17 egl_image_for_unbind_(EGL_NO_IMAGE_KHR), |
| 20 texture_id_for_unbind_(0) {} | 18 texture_id_for_unbind_(0) {} |
| 21 | 19 |
| 22 GLImageEGL::~GLImageEGL() { Destroy(); } | 20 GLImageAndroidNativeBuffer::~GLImageAndroidNativeBuffer() { Destroy(); } |
| 23 | 21 |
| 24 bool GLImageEGL::Initialize(gfx::GpuMemoryBufferHandle buffer) { | 22 bool GLImageAndroidNativeBuffer::Initialize(gfx::GpuMemoryBufferHandle buffer) { |
| 25 DCHECK(buffer.native_buffer); | 23 DCHECK(buffer.native_buffer); |
| 26 | 24 |
| 27 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; | 25 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; |
| 28 egl_image_ = eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), | 26 return GLImageEGL::Initialize( |
| 29 EGL_NO_CONTEXT, | 27 EGL_NATIVE_BUFFER_ANDROID, buffer.native_buffer, attrs); |
| 30 EGL_NATIVE_BUFFER_ANDROID, | |
| 31 buffer.native_buffer, | |
| 32 attrs); | |
| 33 if (egl_image_ == EGL_NO_IMAGE_KHR) { | |
| 34 EGLint error = eglGetError(); | |
| 35 LOG(ERROR) << "Error creating EGLImage: " << error; | |
| 36 return false; | |
| 37 } | |
| 38 | |
| 39 return true; | |
| 40 } | 28 } |
| 41 | 29 |
| 42 void GLImageEGL::Destroy() { | 30 void GLImageAndroidNativeBuffer::Destroy() { |
| 43 if (egl_image_ != EGL_NO_IMAGE_KHR) { | |
| 44 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_); | |
| 45 egl_image_ = EGL_NO_IMAGE_KHR; | |
| 46 } | |
| 47 | |
| 48 if (egl_image_for_unbind_ != EGL_NO_IMAGE_KHR) { | 31 if (egl_image_for_unbind_ != EGL_NO_IMAGE_KHR) { |
| 49 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), | 32 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), |
| 50 egl_image_for_unbind_); | 33 egl_image_for_unbind_); |
| 51 egl_image_for_unbind_ = EGL_NO_IMAGE_KHR; | 34 egl_image_for_unbind_ = EGL_NO_IMAGE_KHR; |
| 52 } | 35 } |
| 53 | |
| 54 if (texture_id_for_unbind_) { | 36 if (texture_id_for_unbind_) { |
| 55 glDeleteTextures(1, &texture_id_for_unbind_); | 37 glDeleteTextures(1, &texture_id_for_unbind_); |
| 56 texture_id_for_unbind_ = 0; | 38 texture_id_for_unbind_ = 0; |
| 57 } | 39 } |
| 40 | |
| 41 GLImageEGL::Destroy(); | |
| 58 } | 42 } |
| 59 | 43 |
| 60 gfx::Size GLImageEGL::GetSize() { return size_; } | 44 bool GLImageAndroidNativeBuffer::BindTexImage(unsigned target) { |
| 61 | 45 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_); |
| 62 bool GLImageEGL::BindTexImage(unsigned target) { | |
| 63 if (egl_image_ == EGL_NO_IMAGE_KHR) { | |
| 64 LOG(ERROR) << "NULL EGLImage in BindTexImage"; | |
| 65 return false; | |
| 66 } | |
| 67 | 46 |
| 68 if (target == GL_TEXTURE_RECTANGLE_ARB) { | 47 if (target == GL_TEXTURE_RECTANGLE_ARB) { |
| 69 LOG(ERROR) << "EGLImage cannot be bound to TEXTURE_RECTANGLE_ARB target"; | 48 LOG(ERROR) << "EGLImage cannot be bound to TEXTURE_RECTANGLE_ARB target"; |
| 70 return false; | 49 return false; |
| 71 } | 50 } |
| 72 | 51 |
| 73 if (target_ && target_ != target) { | 52 if (target_ && target_ != target) { |
| 74 LOG(ERROR) << "EGLImage can only be bound to one target"; | 53 LOG(ERROR) << "EGLImage can only be bound to one target"; |
| 75 return false; | 54 return false; |
| 76 } | 55 } |
| 77 target_ = target; | 56 target_ = target; |
| 78 | 57 |
| 79 // Defer ImageTargetTexture2D if not currently in use. | 58 // Defer ImageTargetTexture2D if not currently in use. |
| 80 if (!in_use_) | 59 if (!in_use_) |
| 81 return true; | 60 return true; |
| 82 | 61 |
| 83 glEGLImageTargetTexture2DOES(target_, egl_image_); | 62 glEGLImageTargetTexture2DOES(target_, egl_image_); |
| 84 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | 63 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 85 return true; | 64 return true; |
| 86 } | 65 } |
| 87 | 66 |
| 88 void GLImageEGL::ReleaseTexImage(unsigned target) { | 67 void GLImageAndroidNativeBuffer::WillUseTexImage() { |
| 89 // Nothing to do here as image is released after each use or there is no need | |
| 90 // to release image. | |
| 91 } | |
| 92 | |
| 93 void GLImageEGL::WillUseTexImage() { | |
| 94 DCHECK(egl_image_); | 68 DCHECK(egl_image_); |
| 95 DCHECK(!in_use_); | 69 DCHECK(!in_use_); |
| 96 in_use_ = true; | 70 in_use_ = true; |
| 97 glEGLImageTargetTexture2DOES(target_, egl_image_); | 71 glEGLImageTargetTexture2DOES(target_, egl_image_); |
| 98 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | 72 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 99 } | 73 } |
| 100 | 74 |
| 101 void GLImageEGL::DidUseTexImage() { | 75 void GLImageAndroidNativeBuffer::DidUseTexImage() { |
| 102 DCHECK(in_use_); | 76 DCHECK(in_use_); |
| 103 in_use_ = false; | 77 in_use_ = false; |
| 104 | 78 |
| 105 if (!release_after_use_) | 79 if (!release_after_use_) |
| 106 return; | 80 return; |
| 107 | 81 |
| 108 if (egl_image_for_unbind_ == EGL_NO_IMAGE_KHR) { | 82 if (egl_image_for_unbind_ == EGL_NO_IMAGE_KHR) { |
| 109 DCHECK_EQ(0u, texture_id_for_unbind_); | 83 DCHECK_EQ(0u, texture_id_for_unbind_); |
| 110 glGenTextures(1, &texture_id_for_unbind_); | 84 glGenTextures(1, &texture_id_for_unbind_); |
| 111 | 85 |
| 112 { | 86 { |
| 113 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_for_unbind_); | 87 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_for_unbind_); |
| 114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 88 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 89 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 116 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 90 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 117 | 91 |
| 118 char zero[4] = {0, }; | 92 char zero[4] = {0, }; |
| 119 glTexImage2D( | 93 glTexImage2D( |
| 120 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &zero); | 94 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &zero); |
| 121 } | 95 } |
| 122 | 96 |
| 123 EGLint attrs[] = {EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_IMAGE_PRESERVED_KHR, | 97 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; |
|
reveman
2014/03/27 22:52:04
Removing "EGL_GL_TEXTURE_LEVEL_KHR, 0" as that's d
| |
| 124 EGL_TRUE, EGL_NONE}; | |
| 125 // Need to pass current EGL rendering context to eglCreateImageKHR for | 98 // Need to pass current EGL rendering context to eglCreateImageKHR for |
| 126 // target type EGL_GL_TEXTURE_2D_KHR. | 99 // target type EGL_GL_TEXTURE_2D_KHR. |
| 127 egl_image_for_unbind_ = eglCreateImageKHR( | 100 egl_image_for_unbind_ = eglCreateImageKHR( |
| 128 GLSurfaceEGL::GetHardwareDisplay(), | 101 GLSurfaceEGL::GetHardwareDisplay(), |
| 129 eglGetCurrentContext(), | 102 eglGetCurrentContext(), |
| 130 EGL_GL_TEXTURE_2D_KHR, | 103 EGL_GL_TEXTURE_2D_KHR, |
| 131 reinterpret_cast<EGLClientBuffer>(texture_id_for_unbind_), | 104 reinterpret_cast<EGLClientBuffer>(texture_id_for_unbind_), |
| 132 attrs); | 105 attrs); |
| 133 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_for_unbind_) | 106 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_for_unbind_) |
| 134 << "Error creating EGLImage: " << eglGetError(); | 107 << "Error creating EGLImage: " << eglGetError(); |
| 135 } | 108 } |
| 136 | 109 |
| 137 glEGLImageTargetTexture2DOES(target_, egl_image_for_unbind_); | 110 glEGLImageTargetTexture2DOES(target_, egl_image_for_unbind_); |
| 138 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | 111 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 139 } | 112 } |
| 140 | 113 |
| 141 void GLImageEGL::SetReleaseAfterUse() { release_after_use_ = true; } | 114 void GLImageAndroidNativeBuffer::SetReleaseAfterUse() { |
| 115 release_after_use_ = true; | |
| 116 } | |
| 142 | 117 |
| 143 } // namespace gfx | 118 } // namespace gfx |
| OLD | NEW |