Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: ui/gl/gl_image_memory.cc

Issue 916083002: Add support for compressed GPU memory buffers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Compressed format detection in own function and image size check Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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) {
piman 2015/02/19 23:52:04 nit: IsCompressedFormat?
christiank 2015/02/20 08:32:14 Fixed! I originally went with CompressedFormat to
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
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);
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();
118 return false; 179 return false;
119 } 180 }
120 181
121 NOTREACHED(); 182 NOTREACHED();
122 return false; 183 return false;
123 } 184 }
124 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;
204 }
205
206 NOTREACHED();
207 return false;
208 }
209
125 bool GLImageMemory::Initialize(const unsigned char* memory, 210 bool GLImageMemory::Initialize(const unsigned char* memory,
126 gfx::GpuMemoryBuffer::Format format) { 211 gfx::GpuMemoryBuffer::Format format) {
127 if (!ValidInternalFormat(internalformat_)) { 212 if (!ValidInternalFormat(internalformat_)) {
128 LOG(ERROR) << "Invalid internalformat: " << internalformat_; 213 LOG(ERROR) << "Invalid internalformat: " << internalformat_;
129 return false; 214 return false;
130 } 215 }
131 216
132 if (!ValidFormat(format)) { 217 if (!ValidFormat(format)) {
133 LOG(ERROR) << "Invalid format: " << format; 218 LOG(ERROR) << "Invalid format: " << format;
134 return false; 219 return false;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 } 265 }
181 266
182 bool GLImageMemory::CopyTexImage(unsigned target) { 267 bool GLImageMemory::CopyTexImage(unsigned target) {
183 TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage"); 268 TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage");
184 269
185 // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target. 270 // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target.
186 if (target == GL_TEXTURE_EXTERNAL_OES) 271 if (target == GL_TEXTURE_EXTERNAL_OES)
187 return false; 272 return false;
188 273
189 DCHECK(memory_); 274 DCHECK(memory_);
190 glTexSubImage2D(target, 0, // level 275 if (CompressedFormat(format_)) {
191 0, // x 276 glCompressedTexSubImage2D(target,
192 0, // y 277 0, // level
193 size_.width(), size_.height(), DataFormat(format_), 278 0, // x-offset
194 DataType(format_), memory_); 279 0, // y-offset
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 }
195 290
196 return true; 291 return true;
197 } 292 }
198 293
199 void GLImageMemory::WillUseTexImage() { 294 void GLImageMemory::WillUseTexImage() {
200 DCHECK(!in_use_); 295 DCHECK(!in_use_);
201 in_use_ = true; 296 in_use_ = true;
202 297
203 if (!need_do_bind_tex_image_) 298 if (!need_do_bind_tex_image_)
204 return; 299 return;
(...skipping 28 matching lines...) Expand all
233 if (egl_image_ == EGL_NO_IMAGE_KHR) { 328 if (egl_image_ == EGL_NO_IMAGE_KHR) {
234 DCHECK_EQ(0u, egl_texture_id_); 329 DCHECK_EQ(0u, egl_texture_id_);
235 glGenTextures(1, &egl_texture_id_); 330 glGenTextures(1, &egl_texture_id_);
236 331
237 { 332 {
238 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); 333 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
239 334
240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 335 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
241 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 336 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); 337 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
243 glTexImage2D(GL_TEXTURE_2D, 338 if (CompressedFormat(format_)) {
244 0, // mip level 339 glCompressedTexImage2D(GL_TEXTURE_2D,
245 TextureFormat(format_), 340 0, // mip level
246 size_.width(), 341 TextureFormat(format_), size_.width(),
247 size_.height(), 342 size_.height(),
248 0, // border 343 0, // border
249 DataFormat(format_), 344 SizeInBytes(size_, format_), memory_);
250 DataType(format_), 345 } else {
251 memory_); 346 glTexImage2D(GL_TEXTURE_2D,
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 }
252 } 356 }
253 357
254 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; 358 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
255 // Need to pass current EGL rendering context to eglCreateImageKHR for 359 // Need to pass current EGL rendering context to eglCreateImageKHR for
256 // target type EGL_GL_TEXTURE_2D_KHR. 360 // target type EGL_GL_TEXTURE_2D_KHR.
257 egl_image_ = 361 egl_image_ =
258 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), 362 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(),
259 eglGetCurrentContext(), 363 eglGetCurrentContext(),
260 EGL_GL_TEXTURE_2D_KHR, 364 EGL_GL_TEXTURE_2D_KHR,
261 reinterpret_cast<EGLClientBuffer>(egl_texture_id_), 365 reinterpret_cast<EGLClientBuffer>(egl_texture_id_),
262 attrs); 366 attrs);
263 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) 367 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_)
264 << "Error creating EGLImage: " << eglGetError(); 368 << "Error creating EGLImage: " << eglGetError();
265 } else { 369 } else {
266 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); 370 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
267 371
268 glTexSubImage2D(GL_TEXTURE_2D, 372 if (CompressedFormat(format_)) {
269 0, // mip level 373 glCompressedTexSubImage2D(GL_TEXTURE_2D,
270 0, // x-offset 374 0, // mip level
271 0, // y-offset 375 0, // x-offset
272 size_.width(), 376 0, // y-offset
273 size_.height(), 377 size_.width(), size_.height(),
274 DataFormat(format_), 378 DataFormat(format_),
275 DataType(format_), 379 SizeInBytes(size_, format_),
276 memory_); 380 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 }
277 } 392 }
278 393
279 glEGLImageTargetTexture2DOES(target, egl_image_); 394 glEGLImageTargetTexture2DOES(target, egl_image_);
280 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); 395 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
281 return; 396 return;
282 } 397 }
283 #endif 398 #endif
284 399
285 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); 400 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target);
286 glTexImage2D(target, 401 if (CompressedFormat(format_)) {
287 0, // mip level 402 glCompressedTexImage2D(target,
288 TextureFormat(format_), 403 0, // mip level
289 size_.width(), 404 TextureFormat(format_), size_.width(),
290 size_.height(), 405 size_.height(),
291 0, // border 406 0, // border
292 DataFormat(format_), 407 SizeInBytes(size_, format_), memory_);
293 DataType(format_), 408 } else {
294 memory_); 409 glTexImage2D(target,
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 }
295 } 419 }
296 420
297 } // namespace gfx 421 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698