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

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

Issue 1051503003: Add R_8 GPU memory buffers format. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix validation problem in StrideInBytes. Deals with GL_RED/GL_LUMINANCE. Created 5 years, 8 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"
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 ValidInternalFormat(unsigned internalformat) { 20 bool ValidateFormats(gfx::GpuMemoryBuffer::Format format,
reveman 2015/04/01 13:14:33 Please make this function consistent with the gl_i
Daniele Castagna 2015/04/01 21:58:34 Done.
21 switch (internalformat) { 21 unsigned internalformat) {
22 case GL_RGBA:
23 return true;
24 default:
25 return false;
26 }
27 }
28
29 bool ValidFormat(gfx::GpuMemoryBuffer::Format format) {
30 switch (format) { 22 switch (format) {
31 case gfx::GpuMemoryBuffer::ATC: 23 case gfx::GpuMemoryBuffer::ATC:
32 case gfx::GpuMemoryBuffer::ATCIA: 24 case gfx::GpuMemoryBuffer::ATCIA:
33 case gfx::GpuMemoryBuffer::DXT1: 25 case gfx::GpuMemoryBuffer::DXT1:
34 case gfx::GpuMemoryBuffer::DXT5: 26 case gfx::GpuMemoryBuffer::DXT5:
35 case gfx::GpuMemoryBuffer::ETC1: 27 case gfx::GpuMemoryBuffer::ETC1:
36 case gfx::GpuMemoryBuffer::RGBA_8888: 28 case gfx::GpuMemoryBuffer::RGBA_8888:
37 case gfx::GpuMemoryBuffer::BGRA_8888: 29 case gfx::GpuMemoryBuffer::BGRA_8888:
30 if (internalformat != GL_RGBA) {
31 LOG(ERROR) << "Invalid internal format " << internalformat
32 << "for the specified format: " << format;
33 return false;
34 }
35 return true;
36 case gfx::GpuMemoryBuffer::R_8:
37 if (internalformat != GL_LUMINANCE && internalformat != GL_R8) {
38 LOG(ERROR) << "Invalid internal format " << internalformat
39 << "for the specified format: " << format;
40 }
38 return true; 41 return true;
39 case gfx::GpuMemoryBuffer::RGBX_8888: 42 case gfx::GpuMemoryBuffer::RGBX_8888:
43 LOG(ERROR) << "Invalid format: " << format;
40 return false; 44 return false;
41 } 45 }
42
43 NOTREACHED(); 46 NOTREACHED();
44 return false; 47 return false;
45 } 48 }
46 49
47 bool IsCompressedFormat(gfx::GpuMemoryBuffer::Format format) { 50 bool IsCompressedFormat(gfx::GpuMemoryBuffer::Format format) {
48 switch (format) { 51 switch (format) {
49 case gfx::GpuMemoryBuffer::ATC: 52 case gfx::GpuMemoryBuffer::ATC:
50 case gfx::GpuMemoryBuffer::ATCIA: 53 case gfx::GpuMemoryBuffer::ATCIA:
51 case gfx::GpuMemoryBuffer::DXT1: 54 case gfx::GpuMemoryBuffer::DXT1:
52 case gfx::GpuMemoryBuffer::DXT5: 55 case gfx::GpuMemoryBuffer::DXT5:
53 case gfx::GpuMemoryBuffer::ETC1: 56 case gfx::GpuMemoryBuffer::ETC1:
54 return true; 57 return true;
58 case gfx::GpuMemoryBuffer::R_8:
55 case gfx::GpuMemoryBuffer::RGBA_8888: 59 case gfx::GpuMemoryBuffer::RGBA_8888:
56 case gfx::GpuMemoryBuffer::BGRA_8888: 60 case gfx::GpuMemoryBuffer::BGRA_8888:
57 case gfx::GpuMemoryBuffer::RGBX_8888: 61 case gfx::GpuMemoryBuffer::RGBX_8888:
58 return false; 62 return false;
59 } 63 }
60 64
61 NOTREACHED(); 65 NOTREACHED();
62 return false; 66 return false;
63 } 67 }
64 68
65 GLenum TextureFormat(gfx::GpuMemoryBuffer::Format format) { 69 GLenum TextureFormat(gfx::GpuMemoryBuffer::Format format,
70 unsigned internalformat) {
66 switch (format) { 71 switch (format) {
reveman 2015/04/01 13:14:33 can you move this switch (format) statement into a
Daniele Castagna 2015/04/01 21:58:34 Split in two functions TextureFormat and InternalT
67 case gfx::GpuMemoryBuffer::ATC: 72 case gfx::GpuMemoryBuffer::ATC:
68 return GL_ATC_RGB_AMD; 73 return GL_ATC_RGB_AMD;
69 case gfx::GpuMemoryBuffer::ATCIA: 74 case gfx::GpuMemoryBuffer::ATCIA:
70 return GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD; 75 return GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
71 case gfx::GpuMemoryBuffer::DXT1: 76 case gfx::GpuMemoryBuffer::DXT1:
72 return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; 77 return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
73 case gfx::GpuMemoryBuffer::DXT5: 78 case gfx::GpuMemoryBuffer::DXT5:
74 return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; 79 return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
75 case gfx::GpuMemoryBuffer::ETC1: 80 case gfx::GpuMemoryBuffer::ETC1:
76 return GL_ETC1_RGB8_OES; 81 return GL_ETC1_RGB8_OES;
82 case gfx::GpuMemoryBuffer::R_8:
83 DCHECK(internalformat == GL_R8 || internalformat == GL_LUMINANCE);
84 return internalformat;
77 case gfx::GpuMemoryBuffer::RGBA_8888: 85 case gfx::GpuMemoryBuffer::RGBA_8888:
78 return GL_RGBA; 86 return GL_RGBA;
79 case gfx::GpuMemoryBuffer::BGRA_8888: 87 case gfx::GpuMemoryBuffer::BGRA_8888:
80 return GL_BGRA_EXT; 88 return GL_BGRA_EXT;
81 case gfx::GpuMemoryBuffer::RGBX_8888: 89 case gfx::GpuMemoryBuffer::RGBX_8888:
82 NOTREACHED(); 90 NOTREACHED();
83 return 0; 91 return 0;
84 } 92 }
85 93
86 NOTREACHED(); 94 NOTREACHED();
87 return 0; 95 return 0;
88 } 96 }
89 97
90 GLenum DataFormat(gfx::GpuMemoryBuffer::Format format) { 98 GLenum DataFormat(gfx::GpuMemoryBuffer::Format format,
91 return TextureFormat(format); 99 unsigned internalformat) {
reveman 2015/04/01 13:14:33 hm, I'm not a fan of passing internalformat to thi
Daniele Castagna 2015/04/01 21:58:35 I'm afraid DataFormat needs to know about internal
100 GLenum data_format = TextureFormat(format, internalformat);
101 return data_format == GL_R8 ? GL_RED : data_format;
92 } 102 }
93 103
94 GLenum DataType(gfx::GpuMemoryBuffer::Format format) { 104 GLenum DataType(gfx::GpuMemoryBuffer::Format format) {
95 switch (format) { 105 switch (format) {
96 case gfx::GpuMemoryBuffer::RGBA_8888: 106 case gfx::GpuMemoryBuffer::RGBA_8888:
97 case gfx::GpuMemoryBuffer::BGRA_8888: 107 case gfx::GpuMemoryBuffer::BGRA_8888:
108 case gfx::GpuMemoryBuffer::R_8:
98 return GL_UNSIGNED_BYTE; 109 return GL_UNSIGNED_BYTE;
99 case gfx::GpuMemoryBuffer::ATC: 110 case gfx::GpuMemoryBuffer::ATC:
100 case gfx::GpuMemoryBuffer::ATCIA: 111 case gfx::GpuMemoryBuffer::ATCIA:
101 case gfx::GpuMemoryBuffer::DXT1: 112 case gfx::GpuMemoryBuffer::DXT1:
102 case gfx::GpuMemoryBuffer::DXT5: 113 case gfx::GpuMemoryBuffer::DXT5:
103 case gfx::GpuMemoryBuffer::ETC1: 114 case gfx::GpuMemoryBuffer::ETC1:
104 case gfx::GpuMemoryBuffer::RGBX_8888: 115 case gfx::GpuMemoryBuffer::RGBX_8888:
105 NOTREACHED(); 116 NOTREACHED();
106 return 0; 117 return 0;
107 } 118 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 151
141 GLImageMemory::~GLImageMemory() { 152 GLImageMemory::~GLImageMemory() {
142 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ 153 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
143 defined(USE_OZONE) 154 defined(USE_OZONE)
144 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_); 155 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_);
145 DCHECK_EQ(0u, egl_texture_id_); 156 DCHECK_EQ(0u, egl_texture_id_);
146 #endif 157 #endif
147 } 158 }
148 159
149 // static 160 // static
150 bool GLImageMemory::StrideInBytes(size_t width, 161 bool GLImageMemory::StrideInBytes(size_t width,
reveman 2015/04/01 13:14:33 Just make sure this function is consistent with Gp
Daniele Castagna 2015/04/01 21:58:35 If by "make sure this function is consistent" you
151 gfx::GpuMemoryBuffer::Format format, 162 gfx::GpuMemoryBuffer::Format format,
152 size_t* stride_in_bytes) { 163 size_t* stride_in_bytes) {
153 base::CheckedNumeric<size_t> s = width; 164 base::CheckedNumeric<size_t> checked_stride = width;
154 switch (format) { 165 switch (format) {
155 case gfx::GpuMemoryBuffer::ATCIA: 166 case GpuMemoryBuffer::R_8:
156 case gfx::GpuMemoryBuffer::DXT5: 167 checked_stride = (checked_stride + 3) % 4;
157 *stride_in_bytes = width; 168 break;
158 return true; 169 case GpuMemoryBuffer::ATCIA:
159 case gfx::GpuMemoryBuffer::ATC: 170 case GpuMemoryBuffer::DXT5: // 'checked_stride' is the same as 'width'.
160 case gfx::GpuMemoryBuffer::DXT1: 171 break;
161 case gfx::GpuMemoryBuffer::ETC1: 172 case GpuMemoryBuffer::ATC:
173 case GpuMemoryBuffer::DXT1:
174 case GpuMemoryBuffer::ETC1:
162 DCHECK_EQ(width % 2, 0U); 175 DCHECK_EQ(width % 2, 0U);
163 s /= 2; 176 checked_stride /= 2;
164 if (!s.IsValid()) 177 break;
165 return false; 178 case GpuMemoryBuffer::RGBA_8888:
166 179 case GpuMemoryBuffer::RGBX_8888:
167 *stride_in_bytes = s.ValueOrDie(); 180 case GpuMemoryBuffer::BGRA_8888:
168 return true; 181 checked_stride *= 4;
169 case gfx::GpuMemoryBuffer::RGBA_8888: 182 break;
170 case gfx::GpuMemoryBuffer::BGRA_8888:
171 s *= 4;
172 if (!s.IsValid())
173 return false;
174
175 *stride_in_bytes = s.ValueOrDie();
176 return true;
177 case gfx::GpuMemoryBuffer::RGBX_8888:
178 NOTREACHED();
179 return false;
180 } 183 }
181 184 if (!checked_stride.IsValid())
182 NOTREACHED(); 185 return false;
183 return false; 186 *stride_in_bytes = checked_stride.ValueOrDie();
187 return true;
184 } 188 }
185 189
186 bool GLImageMemory::Initialize(const unsigned char* memory, 190 bool GLImageMemory::Initialize(const unsigned char* memory,
187 gfx::GpuMemoryBuffer::Format format) { 191 gfx::GpuMemoryBuffer::Format format) {
188 if (!ValidInternalFormat(internalformat_)) { 192 if (!ValidateFormats(format, internalformat_)) {
reveman 2015/04/01 13:14:33 Please make this function consistent with GLImageL
Daniele Castagna 2015/04/01 21:58:34 Done.
189 LOG(ERROR) << "Invalid internalformat: " << internalformat_;
190 return false; 193 return false;
191 } 194 }
192 195
193 if (!ValidFormat(format)) {
194 LOG(ERROR) << "Invalid format: " << format;
195 return false;
196 }
197
198 DCHECK(memory); 196 DCHECK(memory);
199 DCHECK(!memory_); 197 DCHECK(!memory_);
200 DCHECK_IMPLIES(IsCompressedFormat(format), size_.width() % 4 == 0); 198 DCHECK_IMPLIES(IsCompressedFormat(format), size_.width() % 4 == 0);
201 DCHECK_IMPLIES(IsCompressedFormat(format), size_.height() % 4 == 0); 199 DCHECK_IMPLIES(IsCompressedFormat(format), size_.height() % 4 == 0);
202 memory_ = memory; 200 memory_ = memory;
203 format_ = format; 201 format_ = format;
204 return true; 202 return true;
205 } 203 }
206 204
207 void GLImageMemory::Destroy(bool have_context) { 205 void GLImageMemory::Destroy(bool have_context) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 if (target == GL_TEXTURE_EXTERNAL_OES) 247 if (target == GL_TEXTURE_EXTERNAL_OES)
250 return false; 248 return false;
251 249
252 DCHECK(memory_); 250 DCHECK(memory_);
253 if (IsCompressedFormat(format_)) { 251 if (IsCompressedFormat(format_)) {
254 glCompressedTexSubImage2D(target, 252 glCompressedTexSubImage2D(target,
255 0, // level 253 0, // level
256 0, // x-offset 254 0, // x-offset
257 0, // y-offset 255 0, // y-offset
258 size_.width(), size_.height(), 256 size_.width(), size_.height(),
259 DataFormat(format_), SizeInBytes(size_, format_), 257 DataFormat(format_, internalformat_),
260 memory_); 258 SizeInBytes(size_, format_), memory_);
261 } else { 259 } else {
262 glTexSubImage2D(target, 0, // level 260 glTexSubImage2D(target, 0, // level
263 0, // x 261 0, // x
264 0, // y 262 0, // y
265 size_.width(), size_.height(), DataFormat(format_), 263 size_.width(), size_.height(),
266 DataType(format_), memory_); 264 DataFormat(format_, internalformat_), DataType(format_),
265 memory_);
267 } 266 }
268 267
269 return true; 268 return true;
270 } 269 }
271 270
272 void GLImageMemory::WillUseTexImage() { 271 void GLImageMemory::WillUseTexImage() {
273 DCHECK(!in_use_); 272 DCHECK(!in_use_);
274 in_use_ = true; 273 in_use_ = true;
275 274
276 if (!need_do_bind_tex_image_) 275 if (!need_do_bind_tex_image_)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 308
310 { 309 {
311 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); 310 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
312 311
313 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 312 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 313 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
315 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
316 if (IsCompressedFormat(format_)) { 315 if (IsCompressedFormat(format_)) {
317 glCompressedTexImage2D(GL_TEXTURE_2D, 316 glCompressedTexImage2D(GL_TEXTURE_2D,
318 0, // mip level 317 0, // mip level
319 TextureFormat(format_), size_.width(), 318 TextureFormat(format_, internalformat_),
320 size_.height(), 319 size_.width(), size_.height(),
321 0, // border 320 0, // border
322 SizeInBytes(size_, format_), memory_); 321 SizeInBytes(size_, format_), memory_);
323 } else { 322 } else {
324 glTexImage2D(GL_TEXTURE_2D, 323 glTexImage2D(GL_TEXTURE_2D,
325 0, // mip level 324 0, // mip level
326 TextureFormat(format_), 325 TextureFormat(format_, internalformat_), size_.width(),
327 size_.width(),
328 size_.height(), 326 size_.height(),
329 0, // border 327 0, // border
330 DataFormat(format_), 328 DataFormat(format_, internalformat_), DataType(format_),
331 DataType(format_),
332 memory_); 329 memory_);
333 } 330 }
334 } 331 }
335 332
336 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; 333 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
337 // Need to pass current EGL rendering context to eglCreateImageKHR for 334 // Need to pass current EGL rendering context to eglCreateImageKHR for
338 // target type EGL_GL_TEXTURE_2D_KHR. 335 // target type EGL_GL_TEXTURE_2D_KHR.
339 egl_image_ = 336 egl_image_ =
340 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), 337 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(),
341 eglGetCurrentContext(), 338 eglGetCurrentContext(),
342 EGL_GL_TEXTURE_2D_KHR, 339 EGL_GL_TEXTURE_2D_KHR,
343 reinterpret_cast<EGLClientBuffer>(egl_texture_id_), 340 reinterpret_cast<EGLClientBuffer>(egl_texture_id_),
344 attrs); 341 attrs);
345 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) 342 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_)
346 << "Error creating EGLImage: " << eglGetError(); 343 << "Error creating EGLImage: " << eglGetError();
347 } else { 344 } else {
348 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); 345 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
349 346
350 if (IsCompressedFormat(format_)) { 347 if (IsCompressedFormat(format_)) {
351 glCompressedTexSubImage2D(GL_TEXTURE_2D, 348 glCompressedTexSubImage2D(GL_TEXTURE_2D,
352 0, // mip level 349 0, // mip level
353 0, // x-offset 350 0, // x-offset
354 0, // y-offset 351 0, // y-offset
355 size_.width(), size_.height(), 352 size_.width(), size_.height(),
356 DataFormat(format_), 353 DataFormat(format_, internalformat_),
357 SizeInBytes(size_, format_), 354 SizeInBytes(size_, format_), memory_);
358 memory_);
359 } else { 355 } else {
360 glTexSubImage2D(GL_TEXTURE_2D, 356 glTexSubImage2D(GL_TEXTURE_2D,
361 0, // mip level 357 0, // mip level
362 0, // x-offset 358 0, // x-offset
363 0, // y-offset 359 0, // y-offset
364 size_.width(), 360 size_.width(), size_.height(),
365 size_.height(), 361 DataFormat(format_, internalformat_), DataType(format_),
366 DataFormat(format_),
367 DataType(format_),
368 memory_); 362 memory_);
369 } 363 }
370 } 364 }
371 365
372 glEGLImageTargetTexture2DOES(target, egl_image_); 366 glEGLImageTargetTexture2DOES(target, egl_image_);
373 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); 367 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
374 return; 368 return;
375 } 369 }
376 #endif 370 #endif
377 371
378 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); 372 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target);
379 if (IsCompressedFormat(format_)) { 373 if (IsCompressedFormat(format_)) {
380 glCompressedTexImage2D(target, 374 glCompressedTexImage2D(target,
381 0, // mip level 375 0, // mip level
382 TextureFormat(format_), size_.width(), 376 TextureFormat(format_, internalformat_),
383 size_.height(), 377 size_.width(), size_.height(),
384 0, // border 378 0, // border
385 SizeInBytes(size_, format_), memory_); 379 SizeInBytes(size_, format_), memory_);
386 } else { 380 } else {
387 glTexImage2D(target, 381 glTexImage2D(
388 0, // mip level 382 target,
389 TextureFormat(format_), 383 0, // mip level
390 size_.width(), 384 TextureFormat(format_, internalformat_), size_.width(), size_.height(),
391 size_.height(), 385 0, // border
392 0, // border 386 DataFormat(format_, internalformat_), DataType(format_), memory_);
393 DataFormat(format_),
394 DataType(format_),
395 memory_);
396 } 387 }
397 } 388 }
398 389
399 } // namespace gfx 390 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698