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

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: Address reveman@'s comments. 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 ValidFormat(unsigned internalformat, gfx::GpuMemoryBuffer::Format format) {
reveman 2015/04/01 23:38:55 why not two levels of switch statements like GLIma
Daniele Castagna 2015/04/03 01:08:15 Done.
21 switch (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) { 21 switch (format) {
31 case gfx::GpuMemoryBuffer::ATC: 22 case gfx::GpuMemoryBuffer::ATC:
32 case gfx::GpuMemoryBuffer::ATCIA: 23 case gfx::GpuMemoryBuffer::ATCIA:
33 case gfx::GpuMemoryBuffer::DXT1: 24 case gfx::GpuMemoryBuffer::DXT1:
34 case gfx::GpuMemoryBuffer::DXT5: 25 case gfx::GpuMemoryBuffer::DXT5:
35 case gfx::GpuMemoryBuffer::ETC1: 26 case gfx::GpuMemoryBuffer::ETC1:
36 case gfx::GpuMemoryBuffer::RGBA_8888: 27 case gfx::GpuMemoryBuffer::RGBA_8888:
37 case gfx::GpuMemoryBuffer::BGRA_8888: 28 case gfx::GpuMemoryBuffer::BGRA_8888:
29 if (internalformat != GL_RGBA) {
30 LOG(ERROR) << "Invalid internal format " << internalformat
reveman 2015/04/01 23:38:55 I prefer if you keep logging in GLImageMemory::Ini
Daniele Castagna 2015/04/03 01:08:15 Done. In this way the error message can't be as s
31 << "for the specified format: " << format;
32 return false;
33 }
34 return true;
35 case gfx::GpuMemoryBuffer::R_8:
36 if (internalformat != GL_LUMINANCE && internalformat != GL_R8) {
37 LOG(ERROR) << "Invalid internal format " << internalformat
38 << "for the specified format: " << format;
39 }
38 return true; 40 return true;
39 case gfx::GpuMemoryBuffer::RGBX_8888: 41 case gfx::GpuMemoryBuffer::RGBX_8888:
42 LOG(ERROR) << "Invalid format: " << format;
40 return false; 43 return false;
41 } 44 }
42
43 NOTREACHED(); 45 NOTREACHED();
44 return false; 46 return false;
45 } 47 }
46 48
47 bool IsCompressedFormat(gfx::GpuMemoryBuffer::Format format) { 49 bool IsCompressedFormat(gfx::GpuMemoryBuffer::Format format) {
48 switch (format) { 50 switch (format) {
49 case gfx::GpuMemoryBuffer::ATC: 51 case gfx::GpuMemoryBuffer::ATC:
50 case gfx::GpuMemoryBuffer::ATCIA: 52 case gfx::GpuMemoryBuffer::ATCIA:
51 case gfx::GpuMemoryBuffer::DXT1: 53 case gfx::GpuMemoryBuffer::DXT1:
52 case gfx::GpuMemoryBuffer::DXT5: 54 case gfx::GpuMemoryBuffer::DXT5:
53 case gfx::GpuMemoryBuffer::ETC1: 55 case gfx::GpuMemoryBuffer::ETC1:
54 return true; 56 return true;
57 case gfx::GpuMemoryBuffer::R_8:
55 case gfx::GpuMemoryBuffer::RGBA_8888: 58 case gfx::GpuMemoryBuffer::RGBA_8888:
56 case gfx::GpuMemoryBuffer::BGRA_8888: 59 case gfx::GpuMemoryBuffer::BGRA_8888:
57 case gfx::GpuMemoryBuffer::RGBX_8888: 60 case gfx::GpuMemoryBuffer::RGBX_8888:
58 return false; 61 return false;
59 } 62 }
60 63
61 NOTREACHED(); 64 NOTREACHED();
62 return false; 65 return false;
63 } 66 }
64 67
65 GLenum TextureFormat(gfx::GpuMemoryBuffer::Format format) { 68 GLenum TextureFormat(gfx::GpuMemoryBuffer::Format format) {
66 switch (format) { 69 switch (format) {
67 case gfx::GpuMemoryBuffer::ATC: 70 case gfx::GpuMemoryBuffer::ATC:
68 return GL_ATC_RGB_AMD; 71 return GL_ATC_RGB_AMD;
69 case gfx::GpuMemoryBuffer::ATCIA: 72 case gfx::GpuMemoryBuffer::ATCIA:
70 return GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD; 73 return GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
71 case gfx::GpuMemoryBuffer::DXT1: 74 case gfx::GpuMemoryBuffer::DXT1:
72 return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; 75 return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
73 case gfx::GpuMemoryBuffer::DXT5: 76 case gfx::GpuMemoryBuffer::DXT5:
74 return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; 77 return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
75 case gfx::GpuMemoryBuffer::ETC1: 78 case gfx::GpuMemoryBuffer::ETC1:
76 return GL_ETC1_RGB8_OES; 79 return GL_ETC1_RGB8_OES;
77 case gfx::GpuMemoryBuffer::RGBA_8888: 80 case gfx::GpuMemoryBuffer::RGBA_8888:
78 return GL_RGBA; 81 return GL_RGBA;
79 case gfx::GpuMemoryBuffer::BGRA_8888: 82 case gfx::GpuMemoryBuffer::BGRA_8888:
80 return GL_BGRA_EXT; 83 return GL_BGRA_EXT;
84 case gfx::GpuMemoryBuffer::R_8:
81 case gfx::GpuMemoryBuffer::RGBX_8888: 85 case gfx::GpuMemoryBuffer::RGBX_8888:
82 NOTREACHED(); 86 NOTREACHED();
83 return 0; 87 return 0;
84 } 88 }
85 89 NOTREACHED();
reveman 2015/04/01 23:38:55 heh, you don't like my use of blank lines? fine, I
Daniele Castagna 2015/04/03 01:08:15 As discussed on IM, I was trying to minimize verti
90 return 0;
91 }
92 GLenum InternalTextureFormat(unsigned internalformat,
93 gfx::GpuMemoryBuffer::Format format) {
94 switch (internalformat) {
95 case GL_RGB:
96 case GL_RGBA:
97 return TextureFormat(format);
98 case GL_LUMINANCE:
99 case GL_R8:
100 return internalformat;
101 }
86 NOTREACHED(); 102 NOTREACHED();
87 return 0; 103 return 0;
88 } 104 }
89 105
90 GLenum DataFormat(gfx::GpuMemoryBuffer::Format format) { 106 GLenum DataFormat(unsigned internalformat,
reveman 2015/04/01 23:38:55 hm, I think the need for internalformat here is a
Daniele Castagna 2015/04/03 01:08:15 LUMINANCE and LUMINANCE_ALPHA have been deprecated
91 return TextureFormat(format); 107 gfx::GpuMemoryBuffer::Format format) {
108 GLenum data_format = InternalTextureFormat(internalformat, format);
reveman 2015/04/01 23:38:55 If we add gfx::GpuMemoryBuffer::L_8 then we can us
Daniele Castagna 2015/04/03 01:08:15 See previous comment.
109 return data_format == GL_R8 ? GL_RED : data_format;
92 } 110 }
93 111
94 GLenum DataType(gfx::GpuMemoryBuffer::Format format) { 112 GLenum DataType(gfx::GpuMemoryBuffer::Format format) {
95 switch (format) { 113 switch (format) {
96 case gfx::GpuMemoryBuffer::RGBA_8888: 114 case gfx::GpuMemoryBuffer::RGBA_8888:
97 case gfx::GpuMemoryBuffer::BGRA_8888: 115 case gfx::GpuMemoryBuffer::BGRA_8888:
116 case gfx::GpuMemoryBuffer::R_8:
98 return GL_UNSIGNED_BYTE; 117 return GL_UNSIGNED_BYTE;
99 case gfx::GpuMemoryBuffer::ATC: 118 case gfx::GpuMemoryBuffer::ATC:
100 case gfx::GpuMemoryBuffer::ATCIA: 119 case gfx::GpuMemoryBuffer::ATCIA:
101 case gfx::GpuMemoryBuffer::DXT1: 120 case gfx::GpuMemoryBuffer::DXT1:
102 case gfx::GpuMemoryBuffer::DXT5: 121 case gfx::GpuMemoryBuffer::DXT5:
103 case gfx::GpuMemoryBuffer::ETC1: 122 case gfx::GpuMemoryBuffer::ETC1:
104 case gfx::GpuMemoryBuffer::RGBX_8888: 123 case gfx::GpuMemoryBuffer::RGBX_8888:
105 NOTREACHED(); 124 NOTREACHED();
106 return 0; 125 return 0;
107 } 126 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 defined(USE_OZONE) 162 defined(USE_OZONE)
144 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_); 163 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_);
145 DCHECK_EQ(0u, egl_texture_id_); 164 DCHECK_EQ(0u, egl_texture_id_);
146 #endif 165 #endif
147 } 166 }
148 167
149 // static 168 // static
150 bool GLImageMemory::StrideInBytes(size_t width, 169 bool GLImageMemory::StrideInBytes(size_t width,
151 gfx::GpuMemoryBuffer::Format format, 170 gfx::GpuMemoryBuffer::Format format,
152 size_t* stride_in_bytes) { 171 size_t* stride_in_bytes) {
153 base::CheckedNumeric<size_t> s = width; 172 base::CheckedNumeric<size_t> checked_stride = width;
154 switch (format) { 173 switch (format) {
155 case gfx::GpuMemoryBuffer::ATCIA: 174 case GpuMemoryBuffer::R_8:
156 case gfx::GpuMemoryBuffer::DXT5: 175 checked_stride += 3;
176 if (!checked_stride.IsValid())
177 return false;
178 *stride_in_bytes = checked_stride.ValueOrDie() & ~0x3;
179 return true;
180 case GpuMemoryBuffer::ATCIA:
181 case GpuMemoryBuffer::DXT5:
157 *stride_in_bytes = width; 182 *stride_in_bytes = width;
158 return true; 183 return true;
159 case gfx::GpuMemoryBuffer::ATC: 184 case GpuMemoryBuffer::ATC:
160 case gfx::GpuMemoryBuffer::DXT1: 185 case GpuMemoryBuffer::DXT1:
161 case gfx::GpuMemoryBuffer::ETC1: 186 case GpuMemoryBuffer::ETC1:
162 DCHECK_EQ(width % 2, 0U); 187 DCHECK_EQ(width % 2, 0u);
163 s /= 2; 188 *stride_in_bytes = width / 2;
164 if (!s.IsValid()) 189 return true;
190 case GpuMemoryBuffer::RGBA_8888:
191 case GpuMemoryBuffer::RGBX_8888:
192 case GpuMemoryBuffer::BGRA_8888:
193 checked_stride *= 4;
194 if (!checked_stride.IsValid())
165 return false; 195 return false;
166 196 *stride_in_bytes = checked_stride.ValueOrDie();
167 *stride_in_bytes = s.ValueOrDie();
168 return true; 197 return true;
169 case gfx::GpuMemoryBuffer::RGBA_8888:
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 } 198 }
181
182 NOTREACHED(); 199 NOTREACHED();
183 return false; 200 return false;
184 } 201 }
185 202
186 bool GLImageMemory::Initialize(const unsigned char* memory, 203 bool GLImageMemory::Initialize(const unsigned char* memory,
187 gfx::GpuMemoryBuffer::Format format) { 204 gfx::GpuMemoryBuffer::Format format) {
188 if (!ValidInternalFormat(internalformat_)) { 205 if (!ValidFormat(internalformat_, format)) {
189 LOG(ERROR) << "Invalid internalformat: " << internalformat_;
190 return false; 206 return false;
191 } 207 }
192 208
193 if (!ValidFormat(format)) {
194 LOG(ERROR) << "Invalid format: " << format;
195 return false;
196 }
197
198 DCHECK(memory); 209 DCHECK(memory);
199 DCHECK(!memory_); 210 DCHECK(!memory_);
200 DCHECK_IMPLIES(IsCompressedFormat(format), size_.width() % 4 == 0); 211 DCHECK_IMPLIES(IsCompressedFormat(format), size_.width() % 4 == 0);
201 DCHECK_IMPLIES(IsCompressedFormat(format), size_.height() % 4 == 0); 212 DCHECK_IMPLIES(IsCompressedFormat(format), size_.height() % 4 == 0);
202 memory_ = memory; 213 memory_ = memory;
203 format_ = format; 214 format_ = format;
204 return true; 215 return true;
205 } 216 }
206 217
207 void GLImageMemory::Destroy(bool have_context) { 218 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) 260 if (target == GL_TEXTURE_EXTERNAL_OES)
250 return false; 261 return false;
251 262
252 DCHECK(memory_); 263 DCHECK(memory_);
253 if (IsCompressedFormat(format_)) { 264 if (IsCompressedFormat(format_)) {
254 glCompressedTexSubImage2D(target, 265 glCompressedTexSubImage2D(target,
255 0, // level 266 0, // level
256 0, // x-offset 267 0, // x-offset
257 0, // y-offset 268 0, // y-offset
258 size_.width(), size_.height(), 269 size_.width(), size_.height(),
259 DataFormat(format_), SizeInBytes(size_, format_), 270 DataFormat(internalformat_, format_),
260 memory_); 271 SizeInBytes(size_, format_), memory_);
261 } else { 272 } else {
262 glTexSubImage2D(target, 0, // level 273 glTexSubImage2D(target, 0, // level
263 0, // x 274 0, // x
264 0, // y 275 0, // y
265 size_.width(), size_.height(), DataFormat(format_), 276 size_.width(), size_.height(),
266 DataType(format_), memory_); 277 DataFormat(internalformat_, format_), DataType(format_),
278 memory_);
267 } 279 }
268 280
269 return true; 281 return true;
270 } 282 }
271 283
272 void GLImageMemory::WillUseTexImage() { 284 void GLImageMemory::WillUseTexImage() {
273 DCHECK(!in_use_); 285 DCHECK(!in_use_);
274 in_use_ = true; 286 in_use_ = true;
275 287
276 if (!need_do_bind_tex_image_) 288 if (!need_do_bind_tex_image_)
(...skipping 30 matching lines...) Expand all
307 DCHECK_EQ(0u, egl_texture_id_); 319 DCHECK_EQ(0u, egl_texture_id_);
308 glGenTextures(1, &egl_texture_id_); 320 glGenTextures(1, &egl_texture_id_);
309 321
310 { 322 {
311 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); 323 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
312 324
313 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 325 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 326 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); 327 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
316 if (IsCompressedFormat(format_)) { 328 if (IsCompressedFormat(format_)) {
317 glCompressedTexImage2D(GL_TEXTURE_2D, 329 glCompressedTexImage2D(
318 0, // mip level 330 GL_TEXTURE_2D,
319 TextureFormat(format_), size_.width(), 331 0, // mip level
320 size_.height(), 332 InternalTextureFormat(internalformat_, format_), size_.width(),
321 0, // border 333 size_.height(),
322 SizeInBytes(size_, format_), memory_); 334 0, // border
335 SizeInBytes(size_, format_), memory_);
323 } else { 336 } else {
324 glTexImage2D(GL_TEXTURE_2D, 337 glTexImage2D(GL_TEXTURE_2D,
325 0, // mip level 338 0, // mip level
326 TextureFormat(format_), 339 InternalTextureFormat(internalformat_, format_),
327 size_.width(), 340 size_.width(), size_.height(),
328 size_.height(),
329 0, // border 341 0, // border
330 DataFormat(format_), 342 DataFormat(internalformat_, format_), DataType(format_),
331 DataType(format_),
332 memory_); 343 memory_);
333 } 344 }
334 } 345 }
335 346
336 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; 347 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
337 // Need to pass current EGL rendering context to eglCreateImageKHR for 348 // Need to pass current EGL rendering context to eglCreateImageKHR for
338 // target type EGL_GL_TEXTURE_2D_KHR. 349 // target type EGL_GL_TEXTURE_2D_KHR.
339 egl_image_ = 350 egl_image_ =
340 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), 351 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(),
341 eglGetCurrentContext(), 352 eglGetCurrentContext(),
342 EGL_GL_TEXTURE_2D_KHR, 353 EGL_GL_TEXTURE_2D_KHR,
343 reinterpret_cast<EGLClientBuffer>(egl_texture_id_), 354 reinterpret_cast<EGLClientBuffer>(egl_texture_id_),
344 attrs); 355 attrs);
345 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) 356 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_)
346 << "Error creating EGLImage: " << eglGetError(); 357 << "Error creating EGLImage: " << eglGetError();
347 } else { 358 } else {
348 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); 359 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
349 360
350 if (IsCompressedFormat(format_)) { 361 if (IsCompressedFormat(format_)) {
351 glCompressedTexSubImage2D(GL_TEXTURE_2D, 362 glCompressedTexSubImage2D(GL_TEXTURE_2D,
352 0, // mip level 363 0, // mip level
353 0, // x-offset 364 0, // x-offset
354 0, // y-offset 365 0, // y-offset
355 size_.width(), size_.height(), 366 size_.width(), size_.height(),
356 DataFormat(format_), 367 DataFormat(internalformat_, format_),
357 SizeInBytes(size_, format_), 368 SizeInBytes(size_, format_), memory_);
358 memory_);
359 } else { 369 } else {
360 glTexSubImage2D(GL_TEXTURE_2D, 370 glTexSubImage2D(GL_TEXTURE_2D,
361 0, // mip level 371 0, // mip level
362 0, // x-offset 372 0, // x-offset
363 0, // y-offset 373 0, // y-offset
364 size_.width(), 374 size_.width(), size_.height(),
365 size_.height(), 375 DataFormat(internalformat_, format_), DataType(format_),
366 DataFormat(format_),
367 DataType(format_),
368 memory_); 376 memory_);
369 } 377 }
370 } 378 }
371 379
372 glEGLImageTargetTexture2DOES(target, egl_image_); 380 glEGLImageTargetTexture2DOES(target, egl_image_);
373 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); 381 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
374 return; 382 return;
375 } 383 }
376 #endif 384 #endif
377 385
378 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); 386 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target);
379 if (IsCompressedFormat(format_)) { 387 if (IsCompressedFormat(format_)) {
380 glCompressedTexImage2D(target, 388 glCompressedTexImage2D(target,
381 0, // mip level 389 0, // mip level
382 TextureFormat(format_), size_.width(), 390 InternalTextureFormat(internalformat_, format_),
383 size_.height(), 391 size_.width(), size_.height(),
384 0, // border 392 0, // border
385 SizeInBytes(size_, format_), memory_); 393 SizeInBytes(size_, format_), memory_);
386 } else { 394 } else {
387 glTexImage2D(target, 395 glTexImage2D(target,
388 0, // mip level 396 0, // mip level
389 TextureFormat(format_), 397 InternalTextureFormat(internalformat_, format_), size_.width(),
390 size_.width(),
391 size_.height(), 398 size_.height(),
392 0, // border 399 0, // border
393 DataFormat(format_), 400 DataFormat(internalformat_, format_), DataType(format_),
394 DataType(format_),
395 memory_); 401 memory_);
396 } 402 }
397 } 403 }
398 404
399 } // namespace gfx 405 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698