| 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/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/trace_event/trace_event.h" | 8 #include "base/trace_event/trace_event.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" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 switch (internalformat) { | 21 switch (internalformat) { |
| 22 case GL_RGBA: | 22 case GL_RGBA: |
| 23 return true; | 23 return true; |
| 24 default: | 24 default: |
| 25 return false; | 25 return false; |
| 26 } | 26 } |
| 27 } | 27 } |
| 28 | 28 |
| 29 bool ValidFormat(gfx::GpuMemoryBuffer::Format format) { | 29 bool ValidFormat(gfx::GpuMemoryBuffer::Format format) { |
| 30 switch (format) { | 30 switch (format) { |
| 31 case gfx::GpuMemoryBuffer::ATC: | |
| 32 case gfx::GpuMemoryBuffer::ATCIA: | |
| 33 case gfx::GpuMemoryBuffer::DXT1: | |
| 34 case gfx::GpuMemoryBuffer::DXT5: | |
| 35 case gfx::GpuMemoryBuffer::ETC1: | |
| 36 case gfx::GpuMemoryBuffer::RGBA_8888: | 31 case gfx::GpuMemoryBuffer::RGBA_8888: |
| 37 case gfx::GpuMemoryBuffer::BGRA_8888: | 32 case gfx::GpuMemoryBuffer::BGRA_8888: |
| 38 return true; | 33 return true; |
| 39 case gfx::GpuMemoryBuffer::RGBX_8888: | 34 case gfx::GpuMemoryBuffer::RGBX_8888: |
| 40 return false; | 35 return false; |
| 41 } | 36 } |
| 42 | 37 |
| 43 NOTREACHED(); | 38 NOTREACHED(); |
| 44 return false; | 39 return false; |
| 45 } | 40 } |
| 46 | 41 |
| 47 bool IsCompressedFormat(gfx::GpuMemoryBuffer::Format format) { | |
| 48 switch (format) { | |
| 49 case gfx::GpuMemoryBuffer::ATC: | |
| 50 case gfx::GpuMemoryBuffer::ATCIA: | |
| 51 case gfx::GpuMemoryBuffer::DXT1: | |
| 52 case gfx::GpuMemoryBuffer::DXT5: | |
| 53 case gfx::GpuMemoryBuffer::ETC1: | |
| 54 return true; | |
| 55 case gfx::GpuMemoryBuffer::RGBA_8888: | |
| 56 case gfx::GpuMemoryBuffer::BGRA_8888: | |
| 57 case gfx::GpuMemoryBuffer::RGBX_8888: | |
| 58 return false; | |
| 59 } | |
| 60 | |
| 61 NOTREACHED(); | |
| 62 return false; | |
| 63 } | |
| 64 | |
| 65 GLenum TextureFormat(gfx::GpuMemoryBuffer::Format format) { | 42 GLenum TextureFormat(gfx::GpuMemoryBuffer::Format format) { |
| 66 switch (format) { | 43 switch (format) { |
| 67 case gfx::GpuMemoryBuffer::ATC: | |
| 68 return GL_ATC_RGB_AMD; | |
| 69 case gfx::GpuMemoryBuffer::ATCIA: | |
| 70 return GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD; | |
| 71 case gfx::GpuMemoryBuffer::DXT1: | |
| 72 return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; | |
| 73 case gfx::GpuMemoryBuffer::DXT5: | |
| 74 return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; | |
| 75 case gfx::GpuMemoryBuffer::ETC1: | |
| 76 return GL_ETC1_RGB8_OES; | |
| 77 case gfx::GpuMemoryBuffer::RGBA_8888: | 44 case gfx::GpuMemoryBuffer::RGBA_8888: |
| 78 return GL_RGBA; | 45 return GL_RGBA; |
| 79 case gfx::GpuMemoryBuffer::BGRA_8888: | 46 case gfx::GpuMemoryBuffer::BGRA_8888: |
| 80 return GL_BGRA_EXT; | 47 return GL_BGRA_EXT; |
| 81 case gfx::GpuMemoryBuffer::RGBX_8888: | 48 case gfx::GpuMemoryBuffer::RGBX_8888: |
| 82 NOTREACHED(); | 49 NOTREACHED(); |
| 83 return 0; | 50 return 0; |
| 84 } | 51 } |
| 85 | 52 |
| 86 NOTREACHED(); | 53 NOTREACHED(); |
| 87 return 0; | 54 return 0; |
| 88 } | 55 } |
| 89 | 56 |
| 90 GLenum DataFormat(gfx::GpuMemoryBuffer::Format format) { | 57 GLenum DataFormat(gfx::GpuMemoryBuffer::Format format) { |
| 91 return TextureFormat(format); | 58 return TextureFormat(format); |
| 92 } | 59 } |
| 93 | 60 |
| 94 GLenum DataType(gfx::GpuMemoryBuffer::Format format) { | 61 GLenum DataType(gfx::GpuMemoryBuffer::Format format) { |
| 95 switch (format) { | 62 switch (format) { |
| 96 case gfx::GpuMemoryBuffer::RGBA_8888: | 63 case gfx::GpuMemoryBuffer::RGBA_8888: |
| 97 case gfx::GpuMemoryBuffer::BGRA_8888: | 64 case gfx::GpuMemoryBuffer::BGRA_8888: |
| 98 return GL_UNSIGNED_BYTE; | 65 return GL_UNSIGNED_BYTE; |
| 99 case gfx::GpuMemoryBuffer::ATC: | |
| 100 case gfx::GpuMemoryBuffer::ATCIA: | |
| 101 case gfx::GpuMemoryBuffer::DXT1: | |
| 102 case gfx::GpuMemoryBuffer::DXT5: | |
| 103 case gfx::GpuMemoryBuffer::ETC1: | |
| 104 case gfx::GpuMemoryBuffer::RGBX_8888: | 66 case gfx::GpuMemoryBuffer::RGBX_8888: |
| 105 NOTREACHED(); | 67 NOTREACHED(); |
| 106 return 0; | 68 return 0; |
| 107 } | 69 } |
| 108 | 70 |
| 109 NOTREACHED(); | 71 NOTREACHED(); |
| 110 return 0; | 72 return 0; |
| 111 } | 73 } |
| 112 | 74 |
| 113 GLsizei SizeInBytes(const gfx::Size& size, | |
| 114 gfx::GpuMemoryBuffer::Format format) { | |
| 115 size_t stride_in_bytes = 0; | |
| 116 bool valid_stride = GLImageMemory::StrideInBytes( | |
| 117 size.width(), format, &stride_in_bytes); | |
| 118 DCHECK(valid_stride); | |
| 119 return static_cast<GLsizei>(stride_in_bytes * size.height()); | |
| 120 } | |
| 121 | |
| 122 } // namespace | 75 } // namespace |
| 123 | 76 |
| 124 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat) | 77 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat) |
| 125 : size_(size), | 78 : size_(size), |
| 126 internalformat_(internalformat), | 79 internalformat_(internalformat), |
| 127 memory_(NULL), | 80 memory_(NULL), |
| 128 format_(gfx::GpuMemoryBuffer::RGBA_8888), | 81 format_(gfx::GpuMemoryBuffer::RGBA_8888), |
| 129 in_use_(false), | 82 in_use_(false), |
| 130 target_(0), | 83 target_(0), |
| 131 need_do_bind_tex_image_(false) | 84 need_do_bind_tex_image_(false) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 145 DCHECK_EQ(0u, egl_texture_id_); | 98 DCHECK_EQ(0u, egl_texture_id_); |
| 146 #endif | 99 #endif |
| 147 } | 100 } |
| 148 | 101 |
| 149 // static | 102 // static |
| 150 bool GLImageMemory::StrideInBytes(size_t width, | 103 bool GLImageMemory::StrideInBytes(size_t width, |
| 151 gfx::GpuMemoryBuffer::Format format, | 104 gfx::GpuMemoryBuffer::Format format, |
| 152 size_t* stride_in_bytes) { | 105 size_t* stride_in_bytes) { |
| 153 base::CheckedNumeric<size_t> s = width; | 106 base::CheckedNumeric<size_t> s = width; |
| 154 switch (format) { | 107 switch (format) { |
| 155 case gfx::GpuMemoryBuffer::ATCIA: | |
| 156 case gfx::GpuMemoryBuffer::DXT5: | |
| 157 *stride_in_bytes = width; | |
| 158 return true; | |
| 159 case gfx::GpuMemoryBuffer::ATC: | |
| 160 case gfx::GpuMemoryBuffer::DXT1: | |
| 161 case gfx::GpuMemoryBuffer::ETC1: | |
| 162 DCHECK_EQ(width % 2, 0U); | |
| 163 s /= 2; | |
| 164 if (!s.IsValid()) | |
| 165 return false; | |
| 166 | |
| 167 *stride_in_bytes = s.ValueOrDie(); | |
| 168 return true; | |
| 169 case gfx::GpuMemoryBuffer::RGBA_8888: | 108 case gfx::GpuMemoryBuffer::RGBA_8888: |
| 170 case gfx::GpuMemoryBuffer::BGRA_8888: | 109 case gfx::GpuMemoryBuffer::BGRA_8888: |
| 171 s *= 4; | 110 s *= 4; |
| 172 if (!s.IsValid()) | 111 if (!s.IsValid()) |
| 173 return false; | 112 return false; |
| 174 | 113 |
| 175 *stride_in_bytes = s.ValueOrDie(); | 114 *stride_in_bytes = s.ValueOrDie(); |
| 176 return true; | 115 return true; |
| 177 case gfx::GpuMemoryBuffer::RGBX_8888: | 116 case gfx::GpuMemoryBuffer::RGBX_8888: |
| 178 NOTREACHED(); | 117 NOTREACHED(); |
| 179 return false; | |
| 180 } | |
| 181 | |
| 182 NOTREACHED(); | |
| 183 return false; | |
| 184 } | |
| 185 | |
| 186 // static | |
| 187 bool GLImageMemory::ValidSize(const gfx::Size& size, | |
| 188 gfx::GpuMemoryBuffer::Format format) { | |
| 189 switch (format) { | |
| 190 case gfx::GpuMemoryBuffer::ATC: | |
| 191 case gfx::GpuMemoryBuffer::ATCIA: | |
| 192 case gfx::GpuMemoryBuffer::DXT1: | |
| 193 case gfx::GpuMemoryBuffer::DXT5: | |
| 194 case gfx::GpuMemoryBuffer::ETC1: | |
| 195 // Compressed images must have a width and height that's evenly divisible | |
| 196 // by the block size. | |
| 197 return size.width() % 4 == 0 && size.height() % 4 == 0; | |
| 198 case gfx::GpuMemoryBuffer::RGBA_8888: | |
| 199 case gfx::GpuMemoryBuffer::BGRA_8888: | |
| 200 return true; | |
| 201 case gfx::GpuMemoryBuffer::RGBX_8888: | |
| 202 NOTREACHED(); | |
| 203 return false; | 118 return false; |
| 204 } | 119 } |
| 205 | 120 |
| 206 NOTREACHED(); | 121 NOTREACHED(); |
| 207 return false; | 122 return false; |
| 208 } | 123 } |
| 209 | 124 |
| 210 bool GLImageMemory::Initialize(const unsigned char* memory, | 125 bool GLImageMemory::Initialize(const unsigned char* memory, |
| 211 gfx::GpuMemoryBuffer::Format format) { | 126 gfx::GpuMemoryBuffer::Format format) { |
| 212 if (!ValidInternalFormat(internalformat_)) { | 127 if (!ValidInternalFormat(internalformat_)) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 } | 180 } |
| 266 | 181 |
| 267 bool GLImageMemory::CopyTexImage(unsigned target) { | 182 bool GLImageMemory::CopyTexImage(unsigned target) { |
| 268 TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage"); | 183 TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage"); |
| 269 | 184 |
| 270 // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target. | 185 // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target. |
| 271 if (target == GL_TEXTURE_EXTERNAL_OES) | 186 if (target == GL_TEXTURE_EXTERNAL_OES) |
| 272 return false; | 187 return false; |
| 273 | 188 |
| 274 DCHECK(memory_); | 189 DCHECK(memory_); |
| 275 if (IsCompressedFormat(format_)) { | 190 glTexSubImage2D(target, 0, // level |
| 276 glCompressedTexSubImage2D(target, | 191 0, // x |
| 277 0, // level | 192 0, // y |
| 278 0, // x-offset | 193 size_.width(), size_.height(), DataFormat(format_), |
| 279 0, // y-offset | 194 DataType(format_), memory_); |
| 280 size_.width(), size_.height(), | |
| 281 DataFormat(format_), SizeInBytes(size_, format_), | |
| 282 memory_); | |
| 283 } else { | |
| 284 glTexSubImage2D(target, 0, // level | |
| 285 0, // x | |
| 286 0, // y | |
| 287 size_.width(), size_.height(), DataFormat(format_), | |
| 288 DataType(format_), memory_); | |
| 289 } | |
| 290 | 195 |
| 291 return true; | 196 return true; |
| 292 } | 197 } |
| 293 | 198 |
| 294 void GLImageMemory::WillUseTexImage() { | 199 void GLImageMemory::WillUseTexImage() { |
| 295 DCHECK(!in_use_); | 200 DCHECK(!in_use_); |
| 296 in_use_ = true; | 201 in_use_ = true; |
| 297 | 202 |
| 298 if (!need_do_bind_tex_image_) | 203 if (!need_do_bind_tex_image_) |
| 299 return; | 204 return; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 328 if (egl_image_ == EGL_NO_IMAGE_KHR) { | 233 if (egl_image_ == EGL_NO_IMAGE_KHR) { |
| 329 DCHECK_EQ(0u, egl_texture_id_); | 234 DCHECK_EQ(0u, egl_texture_id_); |
| 330 glGenTextures(1, &egl_texture_id_); | 235 glGenTextures(1, &egl_texture_id_); |
| 331 | 236 |
| 332 { | 237 { |
| 333 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); | 238 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); |
| 334 | 239 |
| 335 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 336 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 241 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 337 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 242 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 338 if (IsCompressedFormat(format_)) { | 243 glTexImage2D(GL_TEXTURE_2D, |
| 339 glCompressedTexImage2D(GL_TEXTURE_2D, | 244 0, // mip level |
| 340 0, // mip level | 245 TextureFormat(format_), |
| 341 TextureFormat(format_), size_.width(), | 246 size_.width(), |
| 342 size_.height(), | 247 size_.height(), |
| 343 0, // border | 248 0, // border |
| 344 SizeInBytes(size_, format_), memory_); | 249 DataFormat(format_), |
| 345 } else { | 250 DataType(format_), |
| 346 glTexImage2D(GL_TEXTURE_2D, | 251 memory_); |
| 347 0, // mip level | |
| 348 TextureFormat(format_), | |
| 349 size_.width(), | |
| 350 size_.height(), | |
| 351 0, // border | |
| 352 DataFormat(format_), | |
| 353 DataType(format_), | |
| 354 memory_); | |
| 355 } | |
| 356 } | 252 } |
| 357 | 253 |
| 358 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; | 254 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; |
| 359 // Need to pass current EGL rendering context to eglCreateImageKHR for | 255 // Need to pass current EGL rendering context to eglCreateImageKHR for |
| 360 // target type EGL_GL_TEXTURE_2D_KHR. | 256 // target type EGL_GL_TEXTURE_2D_KHR. |
| 361 egl_image_ = | 257 egl_image_ = |
| 362 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), | 258 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), |
| 363 eglGetCurrentContext(), | 259 eglGetCurrentContext(), |
| 364 EGL_GL_TEXTURE_2D_KHR, | 260 EGL_GL_TEXTURE_2D_KHR, |
| 365 reinterpret_cast<EGLClientBuffer>(egl_texture_id_), | 261 reinterpret_cast<EGLClientBuffer>(egl_texture_id_), |
| 366 attrs); | 262 attrs); |
| 367 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) | 263 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) |
| 368 << "Error creating EGLImage: " << eglGetError(); | 264 << "Error creating EGLImage: " << eglGetError(); |
| 369 } else { | 265 } else { |
| 370 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); | 266 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); |
| 371 | 267 |
| 372 if (IsCompressedFormat(format_)) { | 268 glTexSubImage2D(GL_TEXTURE_2D, |
| 373 glCompressedTexSubImage2D(GL_TEXTURE_2D, | 269 0, // mip level |
| 374 0, // mip level | 270 0, // x-offset |
| 375 0, // x-offset | 271 0, // y-offset |
| 376 0, // y-offset | 272 size_.width(), |
| 377 size_.width(), size_.height(), | 273 size_.height(), |
| 378 DataFormat(format_), | 274 DataFormat(format_), |
| 379 SizeInBytes(size_, format_), | 275 DataType(format_), |
| 380 memory_); | 276 memory_); |
| 381 } else { | |
| 382 glTexSubImage2D(GL_TEXTURE_2D, | |
| 383 0, // mip level | |
| 384 0, // x-offset | |
| 385 0, // y-offset | |
| 386 size_.width(), | |
| 387 size_.height(), | |
| 388 DataFormat(format_), | |
| 389 DataType(format_), | |
| 390 memory_); | |
| 391 } | |
| 392 } | 277 } |
| 393 | 278 |
| 394 glEGLImageTargetTexture2DOES(target, egl_image_); | 279 glEGLImageTargetTexture2DOES(target, egl_image_); |
| 395 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | 280 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 396 return; | 281 return; |
| 397 } | 282 } |
| 398 #endif | 283 #endif |
| 399 | 284 |
| 400 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); | 285 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); |
| 401 if (IsCompressedFormat(format_)) { | 286 glTexImage2D(target, |
| 402 glCompressedTexImage2D(target, | 287 0, // mip level |
| 403 0, // mip level | 288 TextureFormat(format_), |
| 404 TextureFormat(format_), size_.width(), | 289 size_.width(), |
| 405 size_.height(), | 290 size_.height(), |
| 406 0, // border | 291 0, // border |
| 407 SizeInBytes(size_, format_), memory_); | 292 DataFormat(format_), |
| 408 } else { | 293 DataType(format_), |
| 409 glTexImage2D(target, | 294 memory_); |
| 410 0, // mip level | |
| 411 TextureFormat(format_), | |
| 412 size_.width(), | |
| 413 size_.height(), | |
| 414 0, // border | |
| 415 DataFormat(format_), | |
| 416 DataType(format_), | |
| 417 memory_); | |
| 418 } | |
| 419 } | 295 } |
| 420 | 296 |
| 421 } // namespace gfx | 297 } // namespace gfx |
| OLD | NEW |