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

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

Issue 1415723006: ui: Add RGBX_8888 buffer format. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 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
« no previous file with comments | « ui/gl/gl_image_memory.h ('k') | ui/gl/gl_image_ozone_native_pixmap.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/gfx/buffer_format_util.h"
9 #include "ui/gl/gl_bindings.h" 10 #include "ui/gl/gl_bindings.h"
10 11
11 namespace gfx { 12 namespace gfx {
12 namespace { 13 namespace {
13 14
14 bool ValidInternalFormat(unsigned internalformat) { 15 bool ValidInternalFormat(unsigned internalformat) {
15 switch (internalformat) { 16 switch (internalformat) {
16 case GL_ATC_RGB_AMD: 17 case GL_ATC_RGB_AMD:
17 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: 18 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
18 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 19 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
19 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 20 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
20 case GL_ETC1_RGB8_OES: 21 case GL_ETC1_RGB8_OES:
21 case GL_R8: 22 case GL_R8:
23 case GL_RGB:
22 case GL_RGBA: 24 case GL_RGBA:
23 case GL_BGRA_EXT: 25 case GL_BGRA_EXT:
24 return true; 26 return true;
25 default: 27 default:
26 return false; 28 return false;
27 } 29 }
28 } 30 }
29 31
30 bool ValidFormat(BufferFormat format) { 32 bool ValidFormat(BufferFormat format) {
31 switch (format) { 33 switch (format) {
32 case BufferFormat::ATC: 34 case BufferFormat::ATC:
33 case BufferFormat::ATCIA: 35 case BufferFormat::ATCIA:
34 case BufferFormat::DXT1: 36 case BufferFormat::DXT1:
35 case BufferFormat::DXT5: 37 case BufferFormat::DXT5:
36 case BufferFormat::ETC1: 38 case BufferFormat::ETC1:
37 case BufferFormat::R_8: 39 case BufferFormat::R_8:
38 case BufferFormat::RGBA_4444: 40 case BufferFormat::RGBA_4444:
41 case BufferFormat::RGBX_8888:
39 case BufferFormat::RGBA_8888: 42 case BufferFormat::RGBA_8888:
43 case BufferFormat::BGRX_8888:
40 case BufferFormat::BGRA_8888: 44 case BufferFormat::BGRA_8888:
41 return true; 45 return true;
42 case BufferFormat::BGRX_8888:
43 case BufferFormat::YUV_420: 46 case BufferFormat::YUV_420:
44 case BufferFormat::YUV_420_BIPLANAR: 47 case BufferFormat::YUV_420_BIPLANAR:
45 case BufferFormat::UYVY_422: 48 case BufferFormat::UYVY_422:
46 return false; 49 return false;
47 } 50 }
48 51
49 NOTREACHED(); 52 NOTREACHED();
50 return false; 53 return false;
51 } 54 }
52 55
53 bool IsCompressedFormat(BufferFormat format) { 56 bool IsCompressedFormat(BufferFormat format) {
54 switch (format) { 57 switch (format) {
55 case BufferFormat::ATC: 58 case BufferFormat::ATC:
56 case BufferFormat::ATCIA: 59 case BufferFormat::ATCIA:
57 case BufferFormat::DXT1: 60 case BufferFormat::DXT1:
58 case BufferFormat::DXT5: 61 case BufferFormat::DXT5:
59 case BufferFormat::ETC1: 62 case BufferFormat::ETC1:
60 return true; 63 return true;
61 case BufferFormat::R_8: 64 case BufferFormat::R_8:
62 case BufferFormat::RGBA_4444: 65 case BufferFormat::RGBA_4444:
66 case BufferFormat::RGBX_8888:
63 case BufferFormat::RGBA_8888: 67 case BufferFormat::RGBA_8888:
68 case BufferFormat::BGRX_8888:
64 case BufferFormat::BGRA_8888: 69 case BufferFormat::BGRA_8888:
65 case BufferFormat::BGRX_8888:
66 case BufferFormat::YUV_420: 70 case BufferFormat::YUV_420:
67 case BufferFormat::YUV_420_BIPLANAR: 71 case BufferFormat::YUV_420_BIPLANAR:
68 case BufferFormat::UYVY_422: 72 case BufferFormat::UYVY_422:
69 return false; 73 return false;
70 } 74 }
71 75
72 NOTREACHED(); 76 NOTREACHED();
73 return false; 77 return false;
74 } 78 }
75 79
76 GLenum TextureFormat(BufferFormat format) { 80 GLenum TextureFormat(BufferFormat format) {
77 switch (format) { 81 switch (format) {
78 case BufferFormat::ATC: 82 case BufferFormat::ATC:
79 return GL_ATC_RGB_AMD; 83 return GL_ATC_RGB_AMD;
80 case BufferFormat::ATCIA: 84 case BufferFormat::ATCIA:
81 return GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD; 85 return GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
82 case BufferFormat::DXT1: 86 case BufferFormat::DXT1:
83 return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; 87 return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
84 case BufferFormat::DXT5: 88 case BufferFormat::DXT5:
85 return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; 89 return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
86 case BufferFormat::ETC1: 90 case BufferFormat::ETC1:
87 return GL_ETC1_RGB8_OES; 91 return GL_ETC1_RGB8_OES;
88 case BufferFormat::R_8: 92 case BufferFormat::R_8:
89 return GL_RED; 93 return GL_RED;
90 case BufferFormat::RGBA_4444: 94 case BufferFormat::RGBA_4444:
91 case BufferFormat::RGBA_8888: 95 case BufferFormat::RGBA_8888:
92 return GL_RGBA; 96 return GL_RGBA;
93 case BufferFormat::BGRA_8888: 97 case BufferFormat::BGRA_8888:
94 return GL_BGRA_EXT; 98 return GL_BGRA_EXT;
99 case BufferFormat::RGBX_8888:
95 case BufferFormat::BGRX_8888: 100 case BufferFormat::BGRX_8888:
101 return GL_RGB;
96 case BufferFormat::YUV_420: 102 case BufferFormat::YUV_420:
97 case BufferFormat::YUV_420_BIPLANAR: 103 case BufferFormat::YUV_420_BIPLANAR:
98 case BufferFormat::UYVY_422: 104 case BufferFormat::UYVY_422:
99 NOTREACHED(); 105 NOTREACHED();
100 return 0; 106 return 0;
101 } 107 }
102 108
103 NOTREACHED(); 109 NOTREACHED();
104 return 0; 110 return 0;
105 } 111 }
106 112
107 GLenum DataFormat(BufferFormat format) { 113 GLenum DataFormat(BufferFormat format) {
108 return TextureFormat(format); 114 switch (format) {
115 case BufferFormat::RGBX_8888:
116 return GL_RGBA;
117 case BufferFormat::BGRX_8888:
118 return GL_BGRA_EXT;
119 case BufferFormat::RGBA_4444:
120 case BufferFormat::RGBA_8888:
121 case BufferFormat::BGRA_8888:
122 case BufferFormat::R_8:
123 case BufferFormat::ATC:
124 case BufferFormat::ATCIA:
125 case BufferFormat::DXT1:
126 case BufferFormat::DXT5:
127 case BufferFormat::ETC1:
128 case BufferFormat::YUV_420:
129 case BufferFormat::YUV_420_BIPLANAR:
130 case BufferFormat::UYVY_422:
131 return TextureFormat(format);
132 }
133
134 NOTREACHED();
135 return 0;
109 } 136 }
110 137
111 GLenum DataType(BufferFormat format) { 138 GLenum DataType(BufferFormat format) {
112 switch (format) { 139 switch (format) {
113 case BufferFormat::RGBA_4444: 140 case BufferFormat::RGBA_4444:
114 return GL_UNSIGNED_SHORT_4_4_4_4; 141 return GL_UNSIGNED_SHORT_4_4_4_4;
115 case BufferFormat::RGBA_8888: 142 case BufferFormat::RGBA_8888:
116 case BufferFormat::BGRA_8888: 143 case BufferFormat::BGRA_8888:
117 case BufferFormat::R_8: 144 case BufferFormat::R_8:
118 return GL_UNSIGNED_BYTE; 145 return GL_UNSIGNED_BYTE;
146 case BufferFormat::RGBX_8888:
147 return GL_UNSIGNED_INT_8_8_8_8;
148 case BufferFormat::BGRX_8888:
149 return GL_UNSIGNED_INT_8_8_8_8_REV;
piman 2015/10/23 00:52:44 Hmm, I'm not sure what the expectation is here. Th
reveman 2015/10/23 13:44:43 Yea, that made no sense. Thanks for noticing. Late
119 case BufferFormat::ATC: 150 case BufferFormat::ATC:
120 case BufferFormat::ATCIA: 151 case BufferFormat::ATCIA:
121 case BufferFormat::DXT1: 152 case BufferFormat::DXT1:
122 case BufferFormat::DXT5: 153 case BufferFormat::DXT5:
123 case BufferFormat::ETC1: 154 case BufferFormat::ETC1:
124 case BufferFormat::BGRX_8888:
125 case BufferFormat::YUV_420: 155 case BufferFormat::YUV_420:
126 case BufferFormat::YUV_420_BIPLANAR: 156 case BufferFormat::YUV_420_BIPLANAR:
127 case BufferFormat::UYVY_422: 157 case BufferFormat::UYVY_422:
128 NOTREACHED(); 158 NOTREACHED();
129 return 0; 159 return 0;
130 } 160 }
131 161
132 NOTREACHED(); 162 NOTREACHED();
133 return 0; 163 return 0;
134 } 164 }
135 165
136 GLsizei SizeInBytes(const Size& size, BufferFormat format) { 166 template <typename F>
137 size_t stride_in_bytes = 0; 167 scoped_ptr<uint8_t[]> GLES2RGBData(const Size& size,
138 bool valid_stride = GLImageMemory::StrideInBytes( 168 BufferFormat format,
139 size.width(), format, &stride_in_bytes); 169 const uint8_t* data,
140 DCHECK(valid_stride); 170 F const& data_to_rgb,
141 return static_cast<GLsizei>(stride_in_bytes * size.height()); 171 GLenum* data_format,
172 GLenum* data_type) {
173 TRACE_EVENT2("gpu", "GLES2RGBData", "width", size.width(), "height",
174 size.height());
175
176 // Four-byte row alignment as specified by glPixelStorei with argument
177 // GL_UNPACK_ALIGNMENT set to 4.
178 size_t gles2_rgb_data_stride = (size.width() * 3 + 3) & ~3;
179 scoped_ptr<uint8_t[]> gles2_rgb_data(
180 new uint8_t[gles2_rgb_data_stride * size.height()]);
181 size_t data_stride = RowSizeForBufferFormat(size.width(), format, 0);
182
183 for (int y = 0; y < size.height(); ++y) {
184 for (int x = 0; x < size.width(); ++x) {
185 data_to_rgb(&data[y * data_stride + x * 4],
186 &gles2_rgb_data[y * gles2_rgb_data_stride + x * 3]);
187 }
188 }
189
190 *data_format = GL_RGB;
191 *data_type = GL_UNSIGNED_BYTE;
192 return gles2_rgb_data.Pass();
193 }
194
195 scoped_ptr<uint8_t[]> GLES2Data(const Size& size,
196 BufferFormat format,
197 const uint8_t* data,
198 GLenum* data_format,
199 GLenum* data_type) {
200 switch (format) {
201 case BufferFormat::RGBX_8888:
202 return GLES2RGBData(size, format,
203 data, [](const uint8_t* src, uint8_t* dst) {
204 dst[0] = src[0];
205 dst[1] = src[1];
206 dst[2] = src[2];
207 }, data_format, data_type);
208 case BufferFormat::BGRX_8888:
209 return GLES2RGBData(size, format,
210 data, [](const uint8_t* src, uint8_t* dst) {
211 dst[0] = src[2];
212 dst[1] = src[1];
213 dst[2] = src[0];
214 }, data_format, data_type);
215 case BufferFormat::RGBA_4444:
216 case BufferFormat::RGBA_8888:
217 case BufferFormat::BGRA_8888:
218 case BufferFormat::R_8:
219 case BufferFormat::ATC:
220 case BufferFormat::ATCIA:
221 case BufferFormat::DXT1:
222 case BufferFormat::DXT5:
223 case BufferFormat::ETC1:
224 case BufferFormat::YUV_420:
225 case BufferFormat::YUV_420_BIPLANAR:
226 case BufferFormat::UYVY_422:
227 // No data conversion needed.
228 return nullptr;
229 }
230
231 NOTREACHED();
232 return 0;
142 } 233 }
143 234
144 } // namespace 235 } // namespace
145 236
146 GLImageMemory::GLImageMemory(const Size& size, unsigned internalformat) 237 GLImageMemory::GLImageMemory(const Size& size, unsigned internalformat)
147 : size_(size), 238 : size_(size),
148 internalformat_(internalformat), 239 internalformat_(internalformat),
149 memory_(nullptr), 240 memory_(nullptr),
150 format_(BufferFormat::RGBA_8888) {} 241 format_(BufferFormat::RGBA_8888) {}
151 242
152 GLImageMemory::~GLImageMemory() { 243 GLImageMemory::~GLImageMemory() {
153 DCHECK(!memory_); 244 DCHECK(!memory_);
154 } 245 }
155 246
156 // static
157 bool GLImageMemory::StrideInBytes(size_t width,
158 BufferFormat format,
159 size_t* stride_in_bytes) {
160 base::CheckedNumeric<size_t> checked_stride = width;
161 switch (format) {
162 case BufferFormat::ATCIA:
163 case BufferFormat::DXT5:
164 *stride_in_bytes = width;
165 return true;
166 case BufferFormat::ATC:
167 case BufferFormat::DXT1:
168 case BufferFormat::ETC1:
169 DCHECK_EQ(width % 2, 0u);
170 *stride_in_bytes = width / 2;
171 return true;
172 case BufferFormat::R_8:
173 checked_stride += 3;
174 if (!checked_stride.IsValid())
175 return false;
176 *stride_in_bytes = checked_stride.ValueOrDie() & ~0x3;
177 return true;
178 case BufferFormat::RGBA_4444:
179 checked_stride *= 2;
180 if (!checked_stride.IsValid())
181 return false;
182 *stride_in_bytes = checked_stride.ValueOrDie();
183 return true;
184 case BufferFormat::RGBA_8888:
185 case BufferFormat::BGRA_8888:
186 checked_stride *= 4;
187 if (!checked_stride.IsValid())
188 return false;
189 *stride_in_bytes = checked_stride.ValueOrDie();
190 return true;
191 case BufferFormat::BGRX_8888:
192 case BufferFormat::YUV_420:
193 case BufferFormat::YUV_420_BIPLANAR:
194 case BufferFormat::UYVY_422:
195 NOTREACHED();
196 return false;
197 }
198
199 NOTREACHED();
200 return false;
201 }
202
203 bool GLImageMemory::Initialize(const unsigned char* memory, 247 bool GLImageMemory::Initialize(const unsigned char* memory,
204 BufferFormat format) { 248 BufferFormat format) {
205 if (!ValidInternalFormat(internalformat_)) { 249 if (!ValidInternalFormat(internalformat_)) {
206 LOG(ERROR) << "Invalid internalformat: " << internalformat_; 250 LOG(ERROR) << "Invalid internalformat: " << internalformat_;
207 return false; 251 return false;
208 } 252 }
209 253
210 if (!ValidFormat(format)) { 254 if (!ValidFormat(format)) {
211 LOG(ERROR) << "Invalid format: " << static_cast<int>(format); 255 LOG(ERROR) << "Invalid format: " << static_cast<int>(format);
212 return false; 256 return false;
(...skipping 27 matching lines...) Expand all
240 bool GLImageMemory::CopyTexImage(unsigned target) { 284 bool GLImageMemory::CopyTexImage(unsigned target) {
241 TRACE_EVENT2("gpu", "GLImageMemory::CopyTexImage", "width", size_.width(), 285 TRACE_EVENT2("gpu", "GLImageMemory::CopyTexImage", "width", size_.width(),
242 "height", size_.height()); 286 "height", size_.height());
243 287
244 // GL_TEXTURE_EXTERNAL_OES is not a supported target. 288 // GL_TEXTURE_EXTERNAL_OES is not a supported target.
245 if (target == GL_TEXTURE_EXTERNAL_OES) 289 if (target == GL_TEXTURE_EXTERNAL_OES)
246 return false; 290 return false;
247 291
248 if (IsCompressedFormat(format_)) { 292 if (IsCompressedFormat(format_)) {
249 glCompressedTexImage2D(target, 0, TextureFormat(format_), size_.width(), 293 glCompressedTexImage2D(target, 0, TextureFormat(format_), size_.width(),
250 size_.height(), 0, SizeInBytes(size_, format_), 294 size_.height(), 0,
251 memory_); 295 BufferSizeForBufferFormat(size_, format_), memory_);
252 } else { 296 } else {
297 GLenum data_format = DataFormat(format_);
298 GLenum data_type = DataType(format_);
299 // Note: Conversion of data to a GLES2 supported format is not necessary
300 // when using full OpenGL and additional data types are available. To keep
301 // things simple, always convert to GLES2 supported format for now.
302 scoped_ptr<uint8_t[]> gles2_data =
303 GLES2Data(size_, format_, memory_, &data_format, &data_type);
304
253 glTexImage2D(target, 0, TextureFormat(format_), size_.width(), 305 glTexImage2D(target, 0, TextureFormat(format_), size_.width(),
254 size_.height(), 0, DataFormat(format_), DataType(format_), 306 size_.height(), 0, data_format, data_type,
255 memory_); 307 gles2_data ? gles2_data.get() : memory_);
256 } 308 }
257 309
258 return true; 310 return true;
259 } 311 }
260 312
261 bool GLImageMemory::CopyTexSubImage(unsigned target, 313 bool GLImageMemory::CopyTexSubImage(unsigned target,
262 const Point& offset, 314 const Point& offset,
263 const Rect& rect) { 315 const Rect& rect) {
264 TRACE_EVENT2("gpu", "GLImageMemory::CopyTexSubImage", "width", rect.width(), 316 TRACE_EVENT2("gpu", "GLImageMemory::CopyTexSubImage", "width", rect.width(),
265 "height", rect.height()); 317 "height", rect.height());
266 318
267 // GL_TEXTURE_EXTERNAL_OES is not a supported target. 319 // GL_TEXTURE_EXTERNAL_OES is not a supported target.
268 if (target == GL_TEXTURE_EXTERNAL_OES) 320 if (target == GL_TEXTURE_EXTERNAL_OES)
269 return false; 321 return false;
270 322
271 // Sub width is not supported. 323 // Sub width is not supported.
272 if (rect.width() != size_.width()) 324 if (rect.width() != size_.width())
273 return false; 325 return false;
274 326
275 // Height must be a multiple of 4 if compressed. 327 // Height must be a multiple of 4 if compressed.
276 if (IsCompressedFormat(format_) && rect.height() % 4) 328 if (IsCompressedFormat(format_) && rect.height() % 4)
277 return false; 329 return false;
278 330
279 size_t stride_in_bytes = 0; 331 const uint8_t* data =
280 bool rv = StrideInBytes(size_.width(), format_, &stride_in_bytes); 332 memory_ + rect.y() * RowSizeForBufferFormat(size_.width(), format_, 0);
281 DCHECK(rv);
282 DCHECK(memory_);
283 const unsigned char* data = memory_ + rect.y() * stride_in_bytes;
284 if (IsCompressedFormat(format_)) { 333 if (IsCompressedFormat(format_)) {
285 glCompressedTexSubImage2D(target, 0, offset.x(), offset.y(), rect.width(), 334 glCompressedTexSubImage2D(target, 0, offset.x(), offset.y(), rect.width(),
286 rect.height(), DataFormat(format_), 335 rect.height(), DataFormat(format_),
287 SizeInBytes(rect.size(), format_), data); 336 BufferSizeForBufferFormat(rect.size(), format_),
337 data);
288 } else { 338 } else {
339 GLenum data_format = DataFormat(format_);
340 GLenum data_type = DataType(format_);
341 scoped_ptr<uint8_t[]> gles2_data =
342 GLES2Data(rect.size(), format_, data, &data_format, &data_type);
343
289 glTexSubImage2D(target, 0, offset.x(), offset.y(), rect.width(), 344 glTexSubImage2D(target, 0, offset.x(), offset.y(), rect.width(),
290 rect.height(), DataFormat(format_), DataType(format_), 345 rect.height(), data_format, data_type,
291 data); 346 gles2_data ? gles2_data.get() : data);
292 } 347 }
293 348
294 return true; 349 return true;
295 } 350 }
296 351
297 bool GLImageMemory::ScheduleOverlayPlane(AcceleratedWidget widget, 352 bool GLImageMemory::ScheduleOverlayPlane(AcceleratedWidget widget,
298 int z_order, 353 int z_order,
299 OverlayTransform transform, 354 OverlayTransform transform,
300 const Rect& bounds_rect, 355 const Rect& bounds_rect,
301 const RectF& crop_rect) { 356 const RectF& crop_rect) {
302 return false; 357 return false;
303 } 358 }
304 359
360 // static
361 unsigned GLImageMemory::GetInternalFormatForTesting(BufferFormat format) {
362 DCHECK(ValidFormat(format));
363 return TextureFormat(format);
364 }
365
305 } // namespace gfx 366 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gl/gl_image_memory.h ('k') | ui/gl/gl_image_ozone_native_pixmap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698