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 |