 Chromium Code Reviews
 Chromium Code Reviews Issue 916083002:
  Add support for compressed GPU memory buffers.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 916083002:
  Add support for compressed GPU memory buffers.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| 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: | |
| 31 case gfx::GpuMemoryBuffer::RGBA_8888: | 36 case gfx::GpuMemoryBuffer::RGBA_8888: | 
| 32 case gfx::GpuMemoryBuffer::BGRA_8888: | 37 case gfx::GpuMemoryBuffer::BGRA_8888: | 
| 33 return true; | 38 return true; | 
| 34 case gfx::GpuMemoryBuffer::RGBX_8888: | 39 case gfx::GpuMemoryBuffer::RGBX_8888: | 
| 35 return false; | 40 return false; | 
| 36 } | 41 } | 
| 37 | 42 | 
| 38 NOTREACHED(); | 43 NOTREACHED(); | 
| 39 return false; | 44 return false; | 
| 40 } | 45 } | 
| 41 | 46 | 
| 47 bool CompressedFormat(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 | |
| 42 GLenum TextureFormat(gfx::GpuMemoryBuffer::Format format) { | 65 GLenum TextureFormat(gfx::GpuMemoryBuffer::Format format) { | 
| 43 switch (format) { | 66 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; | |
| 44 case gfx::GpuMemoryBuffer::RGBA_8888: | 77 case gfx::GpuMemoryBuffer::RGBA_8888: | 
| 45 return GL_RGBA; | 78 return GL_RGBA; | 
| 46 case gfx::GpuMemoryBuffer::BGRA_8888: | 79 case gfx::GpuMemoryBuffer::BGRA_8888: | 
| 47 return GL_BGRA_EXT; | 80 return GL_BGRA_EXT; | 
| 48 case gfx::GpuMemoryBuffer::RGBX_8888: | 81 case gfx::GpuMemoryBuffer::RGBX_8888: | 
| 49 NOTREACHED(); | 82 NOTREACHED(); | 
| 50 return 0; | 83 return 0; | 
| 51 } | 84 } | 
| 52 | 85 | 
| 53 NOTREACHED(); | 86 NOTREACHED(); | 
| 54 return 0; | 87 return 0; | 
| 55 } | 88 } | 
| 56 | 89 | 
| 57 GLenum DataFormat(gfx::GpuMemoryBuffer::Format format) { | 90 GLenum DataFormat(gfx::GpuMemoryBuffer::Format format) { | 
| 58 return TextureFormat(format); | 91 return TextureFormat(format); | 
| 59 } | 92 } | 
| 60 | 93 | 
| 61 GLenum DataType(gfx::GpuMemoryBuffer::Format format) { | 94 GLenum DataType(gfx::GpuMemoryBuffer::Format format) { | 
| 62 switch (format) { | 95 switch (format) { | 
| 63 case gfx::GpuMemoryBuffer::RGBA_8888: | 96 case gfx::GpuMemoryBuffer::RGBA_8888: | 
| 64 case gfx::GpuMemoryBuffer::BGRA_8888: | 97 case gfx::GpuMemoryBuffer::BGRA_8888: | 
| 65 return GL_UNSIGNED_BYTE; | 98 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: | |
| 66 case gfx::GpuMemoryBuffer::RGBX_8888: | 104 case gfx::GpuMemoryBuffer::RGBX_8888: | 
| 67 NOTREACHED(); | 105 NOTREACHED(); | 
| 68 return 0; | 106 return 0; | 
| 69 } | 107 } | 
| 70 | 108 | 
| 71 NOTREACHED(); | 109 NOTREACHED(); | 
| 72 return 0; | 110 return 0; | 
| 73 } | 111 } | 
| 74 | 112 | 
| 113 size_t 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 stride_in_bytes * size.height(); | |
| 120 } | |
| 121 | |
| 75 } // namespace | 122 } // namespace | 
| 76 | 123 | 
| 77 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat) | 124 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat) | 
| 78 : size_(size), | 125 : size_(size), | 
| 79 internalformat_(internalformat), | 126 internalformat_(internalformat), | 
| 80 memory_(NULL), | 127 memory_(NULL), | 
| 81 format_(gfx::GpuMemoryBuffer::RGBA_8888), | 128 format_(gfx::GpuMemoryBuffer::RGBA_8888), | 
| 82 in_use_(false), | 129 in_use_(false), | 
| 83 target_(0), | 130 target_(0), | 
| 84 need_do_bind_tex_image_(false) | 131 need_do_bind_tex_image_(false) | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 98 DCHECK_EQ(0u, egl_texture_id_); | 145 DCHECK_EQ(0u, egl_texture_id_); | 
| 99 #endif | 146 #endif | 
| 100 } | 147 } | 
| 101 | 148 | 
| 102 // static | 149 // static | 
| 103 bool GLImageMemory::StrideInBytes(size_t width, | 150 bool GLImageMemory::StrideInBytes(size_t width, | 
| 104 gfx::GpuMemoryBuffer::Format format, | 151 gfx::GpuMemoryBuffer::Format format, | 
| 105 size_t* stride_in_bytes) { | 152 size_t* stride_in_bytes) { | 
| 106 base::CheckedNumeric<size_t> s = width; | 153 base::CheckedNumeric<size_t> s = width; | 
| 107 switch (format) { | 154 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); | |
| 
piman
2015/02/14 00:50:21
Hmm, this needs to be validated somewhere, we can'
 
christiank
2015/02/18 14:38:25
We only plan on supporting compressed textures tha
 
reveman
2015/02/18 16:10:30
Could we have SizeInBytes in gl_image_shared_memor
 
reveman
2015/02/18 16:10:30
Could we have SizeInBytes in gl_image_shared_memor
 
christiank
2015/02/19 10:56:56
Sure, sounds good to me. I have now added size che
 | |
| 163 s /= 2; | |
| 164 if (!s.IsValid()) | |
| 165 return false; | |
| 166 | |
| 167 *stride_in_bytes = s.ValueOrDie(); | |
| 168 return true; | |
| 108 case gfx::GpuMemoryBuffer::RGBA_8888: | 169 case gfx::GpuMemoryBuffer::RGBA_8888: | 
| 109 case gfx::GpuMemoryBuffer::BGRA_8888: | 170 case gfx::GpuMemoryBuffer::BGRA_8888: | 
| 110 s *= 4; | 171 s *= 4; | 
| 111 if (!s.IsValid()) | 172 if (!s.IsValid()) | 
| 112 return false; | 173 return false; | 
| 113 | 174 | 
| 114 *stride_in_bytes = s.ValueOrDie(); | 175 *stride_in_bytes = s.ValueOrDie(); | 
| 115 return true; | 176 return true; | 
| 116 case gfx::GpuMemoryBuffer::RGBX_8888: | 177 case gfx::GpuMemoryBuffer::RGBX_8888: | 
| 117 NOTREACHED(); | 178 NOTREACHED(); | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 } | 241 } | 
| 181 | 242 | 
| 182 bool GLImageMemory::CopyTexImage(unsigned target) { | 243 bool GLImageMemory::CopyTexImage(unsigned target) { | 
| 183 TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage"); | 244 TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage"); | 
| 184 | 245 | 
| 185 // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target. | 246 // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target. | 
| 186 if (target == GL_TEXTURE_EXTERNAL_OES) | 247 if (target == GL_TEXTURE_EXTERNAL_OES) | 
| 187 return false; | 248 return false; | 
| 188 | 249 | 
| 189 DCHECK(memory_); | 250 DCHECK(memory_); | 
| 190 glTexSubImage2D(target, 0, // level | 251 if (CompressedFormat(format_)) { | 
| 191 0, // x | 252 glCompressedTexSubImage2D(target, | 
| 192 0, // y | 253 0, // level | 
| 193 size_.width(), size_.height(), DataFormat(format_), | 254 0, // x-offset | 
| 194 DataType(format_), memory_); | 255 0, // y-offset | 
| 256 size_.width(), size_.height(), | |
| 
piman
2015/02/14 00:50:21
For the SubImage case, we definitely need width an
 
christiank
2015/02/18 14:38:25
Adding a check in GpuCommandBufferStub::OnCreateIm
 
reveman
2015/02/18 16:10:30
Yes, or a check in SizeInBytes if we go that way.
 | |
| 257 DataFormat(format_), SizeInBytes(size_, format_), | |
| 258 memory_); | |
| 259 } else { | |
| 260 glTexSubImage2D(target, 0, // level | |
| 261 0, // x | |
| 262 0, // y | |
| 263 size_.width(), size_.height(), DataFormat(format_), | |
| 264 DataType(format_), memory_); | |
| 265 } | |
| 195 | 266 | 
| 196 return true; | 267 return true; | 
| 197 } | 268 } | 
| 198 | 269 | 
| 199 void GLImageMemory::WillUseTexImage() { | 270 void GLImageMemory::WillUseTexImage() { | 
| 200 DCHECK(!in_use_); | 271 DCHECK(!in_use_); | 
| 201 in_use_ = true; | 272 in_use_ = true; | 
| 202 | 273 | 
| 203 if (!need_do_bind_tex_image_) | 274 if (!need_do_bind_tex_image_) | 
| 204 return; | 275 return; | 
| (...skipping 28 matching lines...) Expand all Loading... | |
| 233 if (egl_image_ == EGL_NO_IMAGE_KHR) { | 304 if (egl_image_ == EGL_NO_IMAGE_KHR) { | 
| 234 DCHECK_EQ(0u, egl_texture_id_); | 305 DCHECK_EQ(0u, egl_texture_id_); | 
| 235 glGenTextures(1, &egl_texture_id_); | 306 glGenTextures(1, &egl_texture_id_); | 
| 236 | 307 | 
| 237 { | 308 { | 
| 238 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); | 309 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); | 
| 239 | 310 | 
| 240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 311 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 
| 241 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 312 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 
| 242 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 313 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 
| 243 glTexImage2D(GL_TEXTURE_2D, | 314 if (CompressedFormat(format_)) { | 
| 244 0, // mip level | 315 glCompressedTexImage2D(GL_TEXTURE_2D, | 
| 245 TextureFormat(format_), | 316 0, // mip level | 
| 246 size_.width(), | 317 TextureFormat(format_), size_.width(), | 
| 247 size_.height(), | 318 size_.height(), | 
| 248 0, // border | 319 0, // border | 
| 249 DataFormat(format_), | 320 SizeInBytes(size_, format_), memory_); | 
| 250 DataType(format_), | 321 } else { | 
| 251 memory_); | 322 glTexImage2D(GL_TEXTURE_2D, | 
| 323 0, // mip level | |
| 324 TextureFormat(format_), | |
| 325 size_.width(), | |
| 326 size_.height(), | |
| 327 0, // border | |
| 328 DataFormat(format_), | |
| 329 DataType(format_), | |
| 330 memory_); | |
| 331 } | |
| 252 } | 332 } | 
| 253 | 333 | 
| 254 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; | 334 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; | 
| 255 // Need to pass current EGL rendering context to eglCreateImageKHR for | 335 // Need to pass current EGL rendering context to eglCreateImageKHR for | 
| 256 // target type EGL_GL_TEXTURE_2D_KHR. | 336 // target type EGL_GL_TEXTURE_2D_KHR. | 
| 257 egl_image_ = | 337 egl_image_ = | 
| 258 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), | 338 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), | 
| 259 eglGetCurrentContext(), | 339 eglGetCurrentContext(), | 
| 260 EGL_GL_TEXTURE_2D_KHR, | 340 EGL_GL_TEXTURE_2D_KHR, | 
| 261 reinterpret_cast<EGLClientBuffer>(egl_texture_id_), | 341 reinterpret_cast<EGLClientBuffer>(egl_texture_id_), | 
| 262 attrs); | 342 attrs); | 
| 263 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) | 343 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) | 
| 264 << "Error creating EGLImage: " << eglGetError(); | 344 << "Error creating EGLImage: " << eglGetError(); | 
| 265 } else { | 345 } else { | 
| 266 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); | 346 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); | 
| 267 | 347 | 
| 268 glTexSubImage2D(GL_TEXTURE_2D, | 348 if (CompressedFormat(format_)) { | 
| 269 0, // mip level | 349 glCompressedTexSubImage2D(GL_TEXTURE_2D, | 
| 270 0, // x-offset | 350 0, // mip level | 
| 271 0, // y-offset | 351 0, // x-offset | 
| 272 size_.width(), | 352 0, // y-offset | 
| 273 size_.height(), | 353 size_.width(), size_.height(), | 
| 274 DataFormat(format_), | 354 DataFormat(format_), | 
| 275 DataType(format_), | 355 SizeInBytes(size_, format_), | 
| 276 memory_); | 356 memory_); | 
| 357 } else { | |
| 358 glTexSubImage2D(GL_TEXTURE_2D, | |
| 359 0, // mip level | |
| 360 0, // x-offset | |
| 361 0, // y-offset | |
| 362 size_.width(), | |
| 363 size_.height(), | |
| 364 DataFormat(format_), | |
| 365 DataType(format_), | |
| 366 memory_); | |
| 367 } | |
| 277 } | 368 } | 
| 278 | 369 | 
| 279 glEGLImageTargetTexture2DOES(target, egl_image_); | 370 glEGLImageTargetTexture2DOES(target, egl_image_); | 
| 280 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | 371 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | 
| 281 return; | 372 return; | 
| 282 } | 373 } | 
| 283 #endif | 374 #endif | 
| 284 | 375 | 
| 285 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); | 376 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); | 
| 286 glTexImage2D(target, | 377 if (CompressedFormat(format_)) { | 
| 287 0, // mip level | 378 glCompressedTexImage2D(target, | 
| 288 TextureFormat(format_), | 379 0, // mip level | 
| 289 size_.width(), | 380 TextureFormat(format_), size_.width(), | 
| 290 size_.height(), | 381 size_.height(), | 
| 291 0, // border | 382 0, // border | 
| 292 DataFormat(format_), | 383 SizeInBytes(size_, format_), memory_); | 
| 293 DataType(format_), | 384 } else { | 
| 294 memory_); | 385 glTexImage2D(target, | 
| 386 0, // mip level | |
| 387 TextureFormat(format_), | |
| 388 size_.width(), | |
| 389 size_.height(), | |
| 390 0, // border | |
| 391 DataFormat(format_), | |
| 392 DataType(format_), | |
| 393 memory_); | |
| 394 } | |
| 295 } | 395 } | 
| 296 | 396 | 
| 297 } // namespace gfx | 397 } // namespace gfx | 
| OLD | NEW |