| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 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_memory.h" | 5 #include "ui/gl/gl_image_memory.h" |
| 6 | 6 |
| 7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "ui/gl/gl_bindings.h" | 9 #include "ui/gl/gl_bindings.h" |
| 10 #include "ui/gl/scoped_binders.h" | 10 #include "ui/gl/scoped_binders.h" |
| 11 | 11 |
| 12 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | 12 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ |
| 13 defined(USE_OZONE) | 13 defined(USE_OZONE) |
| 14 #include "ui/gl/gl_surface_egl.h" | 14 #include "ui/gl/gl_surface_egl.h" |
| 15 #endif | 15 #endif |
| 16 | 16 |
| 17 namespace gfx { | 17 namespace gfx { |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 bool ValidFormat(unsigned internalformat) { | 20 bool ValidInternalFormat(unsigned internalformat) { |
| 21 switch (internalformat) { | 21 switch (internalformat) { |
| 22 case GL_BGRA8_EXT: | 22 case GL_RGBA: |
| 23 case GL_RGBA8_OES: | |
| 24 return true; | 23 return true; |
| 25 default: | 24 default: |
| 26 return false; | 25 return false; |
| 27 } | 26 } |
| 28 } | 27 } |
| 29 | 28 |
| 30 GLenum TextureFormat(unsigned internalformat) { | 29 GLenum TextureFormat(gfx::GpuMemoryBuffer::Format format) { |
| 31 switch (internalformat) { | 30 switch (format) { |
| 32 case GL_BGRA8_EXT: | 31 case gfx::GpuMemoryBuffer::RGBA_8888: |
| 32 return GL_RGBA; |
| 33 case gfx::GpuMemoryBuffer::BGRA_8888: |
| 33 return GL_BGRA_EXT; | 34 return GL_BGRA_EXT; |
| 34 case GL_RGBA8_OES: | 35 case gfx::GpuMemoryBuffer::RGBX_8888: |
| 35 return GL_RGBA; | 36 break; |
| 36 default: | |
| 37 NOTREACHED(); | |
| 38 return 0; | |
| 39 } | 37 } |
| 38 |
| 39 NOTREACHED(); |
| 40 return 0; |
| 40 } | 41 } |
| 41 | 42 |
| 42 GLenum DataFormat(unsigned internalformat) { | 43 GLenum DataFormat(gfx::GpuMemoryBuffer::Format format) { |
| 43 return TextureFormat(internalformat); | 44 return TextureFormat(format); |
| 44 } | 45 } |
| 45 | 46 |
| 46 GLenum DataType(unsigned internalformat) { | 47 GLenum DataType(gfx::GpuMemoryBuffer::Format format) { |
| 47 switch (internalformat) { | 48 switch (format) { |
| 48 case GL_BGRA8_EXT: | 49 case gfx::GpuMemoryBuffer::RGBA_8888: |
| 49 case GL_RGBA8_OES: | 50 case gfx::GpuMemoryBuffer::BGRA_8888: |
| 50 return GL_UNSIGNED_BYTE; | 51 return GL_UNSIGNED_BYTE; |
| 51 default: | 52 case gfx::GpuMemoryBuffer::RGBX_8888: |
| 52 NOTREACHED(); | 53 break; |
| 53 return 0; | |
| 54 } | 54 } |
| 55 } | |
| 56 | 55 |
| 57 int BytesPerPixel(unsigned internalformat) { | 56 NOTREACHED(); |
| 58 switch (internalformat) { | 57 return 0; |
| 59 case GL_BGRA8_EXT: | |
| 60 case GL_RGBA8_OES: | |
| 61 return 4; | |
| 62 default: | |
| 63 NOTREACHED(); | |
| 64 return 0; | |
| 65 } | |
| 66 } | 58 } |
| 67 | 59 |
| 68 } // namespace | 60 } // namespace |
| 69 | 61 |
| 70 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat) | 62 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat) |
| 71 : memory_(NULL), | 63 : size_(size), |
| 72 size_(size), | |
| 73 internalformat_(internalformat), | 64 internalformat_(internalformat), |
| 65 memory_(NULL), |
| 66 format_(gfx::GpuMemoryBuffer::RGBA_8888), |
| 74 in_use_(false), | 67 in_use_(false), |
| 75 target_(0), | 68 target_(0), |
| 76 need_do_bind_tex_image_(false) | 69 need_do_bind_tex_image_(false) |
| 77 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | 70 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ |
| 78 defined(USE_OZONE) | 71 defined(USE_OZONE) |
| 79 , | 72 , |
| 80 egl_texture_id_(0u), | 73 egl_texture_id_(0u), |
| 81 egl_image_(EGL_NO_IMAGE_KHR) | 74 egl_image_(EGL_NO_IMAGE_KHR) |
| 82 #endif | 75 #endif |
| 83 { | 76 { |
| 84 } | 77 } |
| 85 | 78 |
| 86 GLImageMemory::~GLImageMemory() { | 79 GLImageMemory::~GLImageMemory() { |
| 87 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | 80 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ |
| 88 defined(USE_OZONE) | 81 defined(USE_OZONE) |
| 89 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_); | 82 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_); |
| 90 DCHECK_EQ(0u, egl_texture_id_); | 83 DCHECK_EQ(0u, egl_texture_id_); |
| 91 #endif | 84 #endif |
| 92 } | 85 } |
| 93 | 86 |
| 94 bool GLImageMemory::Initialize(const unsigned char* memory) { | 87 // static |
| 95 if (!ValidFormat(internalformat_)) { | 88 size_t GLImageMemory::BytesPerPixel(gfx::GpuMemoryBuffer::Format format) { |
| 96 DVLOG(0) << "Invalid format: " << internalformat_; | 89 switch (format) { |
| 90 case gfx::GpuMemoryBuffer::RGBA_8888: |
| 91 case gfx::GpuMemoryBuffer::BGRA_8888: |
| 92 return 4; |
| 93 case gfx::GpuMemoryBuffer::RGBX_8888: |
| 94 break; |
| 95 } |
| 96 |
| 97 NOTREACHED(); |
| 98 return 0; |
| 99 } |
| 100 |
| 101 bool GLImageMemory::Initialize(const unsigned char* memory, |
| 102 gfx::GpuMemoryBuffer::Format format) { |
| 103 if (!ValidInternalFormat(internalformat_)) { |
| 104 DVLOG(0) << "Invalid internalformat: " << internalformat_; |
| 97 return false; | 105 return false; |
| 98 } | 106 } |
| 99 | 107 |
| 100 DCHECK(memory); | 108 DCHECK(memory); |
| 101 DCHECK(!memory_); | 109 DCHECK(!memory_); |
| 102 memory_ = memory; | 110 memory_ = memory; |
| 111 format_ = format; |
| 103 return true; | 112 return true; |
| 104 } | 113 } |
| 105 | 114 |
| 106 void GLImageMemory::Destroy(bool have_context) { | 115 void GLImageMemory::Destroy(bool have_context) { |
| 107 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | 116 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ |
| 108 defined(USE_OZONE) | 117 defined(USE_OZONE) |
| 109 if (egl_image_ != EGL_NO_IMAGE_KHR) { | 118 if (egl_image_ != EGL_NO_IMAGE_KHR) { |
| 110 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_); | 119 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_); |
| 111 egl_image_ = EGL_NO_IMAGE_KHR; | 120 egl_image_ = EGL_NO_IMAGE_KHR; |
| 112 } | 121 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 bool GLImageMemory::CopyTexImage(unsigned target) { | 153 bool GLImageMemory::CopyTexImage(unsigned target) { |
| 145 TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage"); | 154 TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage"); |
| 146 | 155 |
| 147 // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target. | 156 // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target. |
| 148 if (target == GL_TEXTURE_EXTERNAL_OES) | 157 if (target == GL_TEXTURE_EXTERNAL_OES) |
| 149 return false; | 158 return false; |
| 150 | 159 |
| 151 DCHECK(memory_); | 160 DCHECK(memory_); |
| 152 glTexImage2D(target, | 161 glTexImage2D(target, |
| 153 0, // mip level | 162 0, // mip level |
| 154 TextureFormat(internalformat_), | 163 TextureFormat(format_), |
| 155 size_.width(), | 164 size_.width(), |
| 156 size_.height(), | 165 size_.height(), |
| 157 0, // border | 166 0, // border |
| 158 DataFormat(internalformat_), | 167 DataFormat(format_), |
| 159 DataType(internalformat_), | 168 DataType(format_), |
| 160 memory_); | 169 memory_); |
| 161 | 170 |
| 162 return true; | 171 return true; |
| 163 } | 172 } |
| 164 | 173 |
| 165 void GLImageMemory::WillUseTexImage() { | 174 void GLImageMemory::WillUseTexImage() { |
| 166 DCHECK(!in_use_); | 175 DCHECK(!in_use_); |
| 167 in_use_ = true; | 176 in_use_ = true; |
| 168 | 177 |
| 169 if (!need_do_bind_tex_image_) | 178 if (!need_do_bind_tex_image_) |
| 170 return; | 179 return; |
| 171 | 180 |
| 172 DCHECK(target_); | 181 DCHECK(target_); |
| 173 DoBindTexImage(target_); | 182 DoBindTexImage(target_); |
| 174 } | 183 } |
| 175 | 184 |
| 176 void GLImageMemory::DidUseTexImage() { | 185 void GLImageMemory::DidUseTexImage() { |
| 177 DCHECK(in_use_); | 186 DCHECK(in_use_); |
| 178 in_use_ = false; | 187 in_use_ = false; |
| 179 } | 188 } |
| 180 | 189 |
| 181 bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | 190 bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, |
| 182 int z_order, | 191 int z_order, |
| 183 OverlayTransform transform, | 192 OverlayTransform transform, |
| 184 const Rect& bounds_rect, | 193 const Rect& bounds_rect, |
| 185 const RectF& crop_rect) { | 194 const RectF& crop_rect) { |
| 186 return false; | 195 return false; |
| 187 } | 196 } |
| 188 | 197 |
| 189 bool GLImageMemory::HasValidFormat() const { | |
| 190 return ValidFormat(internalformat_); | |
| 191 } | |
| 192 | |
| 193 size_t GLImageMemory::Bytes() const { | |
| 194 return size_.GetArea() * BytesPerPixel(internalformat_); | |
| 195 } | |
| 196 | |
| 197 void GLImageMemory::DoBindTexImage(unsigned target) { | 198 void GLImageMemory::DoBindTexImage(unsigned target) { |
| 198 TRACE_EVENT0("gpu", "GLImageMemory::DoBindTexImage"); | 199 TRACE_EVENT0("gpu", "GLImageMemory::DoBindTexImage"); |
| 199 | 200 |
| 200 DCHECK(need_do_bind_tex_image_); | 201 DCHECK(need_do_bind_tex_image_); |
| 201 need_do_bind_tex_image_ = false; | 202 need_do_bind_tex_image_ = false; |
| 202 | 203 |
| 203 DCHECK(memory_); | 204 DCHECK(memory_); |
| 204 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | 205 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ |
| 205 defined(USE_OZONE) | 206 defined(USE_OZONE) |
| 206 if (target == GL_TEXTURE_EXTERNAL_OES) { | 207 if (target == GL_TEXTURE_EXTERNAL_OES) { |
| 207 if (egl_image_ == EGL_NO_IMAGE_KHR) { | 208 if (egl_image_ == EGL_NO_IMAGE_KHR) { |
| 208 DCHECK_EQ(0u, egl_texture_id_); | 209 DCHECK_EQ(0u, egl_texture_id_); |
| 209 glGenTextures(1, &egl_texture_id_); | 210 glGenTextures(1, &egl_texture_id_); |
| 210 | 211 |
| 211 { | 212 { |
| 212 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); | 213 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); |
| 213 | 214 |
| 214 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 215 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 215 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 216 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 216 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 217 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 217 glTexImage2D(GL_TEXTURE_2D, | 218 glTexImage2D(GL_TEXTURE_2D, |
| 218 0, // mip level | 219 0, // mip level |
| 219 TextureFormat(internalformat_), | 220 TextureFormat(format_), |
| 220 size_.width(), | 221 size_.width(), |
| 221 size_.height(), | 222 size_.height(), |
| 222 0, // border | 223 0, // border |
| 223 DataFormat(internalformat_), | 224 DataFormat(format_), |
| 224 DataType(internalformat_), | 225 DataType(format_), |
| 225 memory_); | 226 memory_); |
| 226 } | 227 } |
| 227 | 228 |
| 228 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; | 229 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; |
| 229 // Need to pass current EGL rendering context to eglCreateImageKHR for | 230 // Need to pass current EGL rendering context to eglCreateImageKHR for |
| 230 // target type EGL_GL_TEXTURE_2D_KHR. | 231 // target type EGL_GL_TEXTURE_2D_KHR. |
| 231 egl_image_ = | 232 egl_image_ = |
| 232 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), | 233 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), |
| 233 eglGetCurrentContext(), | 234 eglGetCurrentContext(), |
| 234 EGL_GL_TEXTURE_2D_KHR, | 235 EGL_GL_TEXTURE_2D_KHR, |
| 235 reinterpret_cast<EGLClientBuffer>(egl_texture_id_), | 236 reinterpret_cast<EGLClientBuffer>(egl_texture_id_), |
| 236 attrs); | 237 attrs); |
| 237 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) | 238 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) |
| 238 << "Error creating EGLImage: " << eglGetError(); | 239 << "Error creating EGLImage: " << eglGetError(); |
| 239 } else { | 240 } else { |
| 240 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); | 241 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); |
| 241 | 242 |
| 242 glTexSubImage2D(GL_TEXTURE_2D, | 243 glTexSubImage2D(GL_TEXTURE_2D, |
| 243 0, // mip level | 244 0, // mip level |
| 244 0, // x-offset | 245 0, // x-offset |
| 245 0, // y-offset | 246 0, // y-offset |
| 246 size_.width(), | 247 size_.width(), |
| 247 size_.height(), | 248 size_.height(), |
| 248 DataFormat(internalformat_), | 249 DataFormat(format_), |
| 249 DataType(internalformat_), | 250 DataType(format_), |
| 250 memory_); | 251 memory_); |
| 251 } | 252 } |
| 252 | 253 |
| 253 glEGLImageTargetTexture2DOES(target, egl_image_); | 254 glEGLImageTargetTexture2DOES(target, egl_image_); |
| 254 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | 255 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 255 return; | 256 return; |
| 256 } | 257 } |
| 257 #endif | 258 #endif |
| 258 | 259 |
| 259 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); | 260 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); |
| 260 glTexImage2D(target, | 261 glTexImage2D(target, |
| 261 0, // mip level | 262 0, // mip level |
| 262 TextureFormat(internalformat_), | 263 TextureFormat(format_), |
| 263 size_.width(), | 264 size_.width(), |
| 264 size_.height(), | 265 size_.height(), |
| 265 0, // border | 266 0, // border |
| 266 DataFormat(internalformat_), | 267 DataFormat(format_), |
| 267 DataType(internalformat_), | 268 DataType(format_), |
| 268 memory_); | 269 memory_); |
| 269 } | 270 } |
| 270 | 271 |
| 271 } // namespace gfx | 272 } // namespace gfx |
| OLD | NEW |