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

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

Issue 1403283007: Re-land: ui: Add custom stride support to GLImageMemory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more missing static_casts Created 5 years, 1 month 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_ref_counted_memory.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/numerics/safe_conversions.h"
8 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
9 #include "ui/gfx/buffer_format_util.h" 10 #include "ui/gfx/buffer_format_util.h"
10 #include "ui/gl/gl_bindings.h" 11 #include "ui/gl/gl_bindings.h"
11 #include "ui/gl/gl_context.h" 12 #include "ui/gl/gl_context.h"
12 #include "ui/gl/gl_version_info.h" 13 #include "ui/gl/gl_version_info.h"
13 14
14 using gfx::BufferFormat; 15 using gfx::BufferFormat;
15 16
16 namespace gl { 17 namespace gl {
17 namespace { 18 namespace {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 case BufferFormat::DXT1: 65 case BufferFormat::DXT1:
65 case BufferFormat::DXT5: 66 case BufferFormat::DXT5:
66 case BufferFormat::ETC1: 67 case BufferFormat::ETC1:
67 return true; 68 return true;
68 case BufferFormat::R_8: 69 case BufferFormat::R_8:
69 case BufferFormat::RGBA_4444: 70 case BufferFormat::RGBA_4444:
70 case BufferFormat::RGBX_8888: 71 case BufferFormat::RGBX_8888:
71 case BufferFormat::RGBA_8888: 72 case BufferFormat::RGBA_8888:
72 case BufferFormat::BGRX_8888: 73 case BufferFormat::BGRX_8888:
73 case BufferFormat::BGRA_8888: 74 case BufferFormat::BGRA_8888:
75 return false;
74 case BufferFormat::YUV_420: 76 case BufferFormat::YUV_420:
75 case BufferFormat::YUV_420_BIPLANAR: 77 case BufferFormat::YUV_420_BIPLANAR:
76 case BufferFormat::UYVY_422: 78 case BufferFormat::UYVY_422:
79 NOTREACHED();
77 return false; 80 return false;
78 } 81 }
79 82
80 NOTREACHED(); 83 NOTREACHED();
81 return false; 84 return false;
82 } 85 }
83 86
84 GLenum TextureFormat(BufferFormat format) { 87 GLenum TextureFormat(BufferFormat format) {
85 switch (format) { 88 switch (format) {
86 case BufferFormat::ATC: 89 case BufferFormat::ATC:
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 return GL_BGRA_EXT; 125 return GL_BGRA_EXT;
123 case BufferFormat::RGBA_4444: 126 case BufferFormat::RGBA_4444:
124 case BufferFormat::RGBA_8888: 127 case BufferFormat::RGBA_8888:
125 case BufferFormat::BGRA_8888: 128 case BufferFormat::BGRA_8888:
126 case BufferFormat::R_8: 129 case BufferFormat::R_8:
127 case BufferFormat::ATC: 130 case BufferFormat::ATC:
128 case BufferFormat::ATCIA: 131 case BufferFormat::ATCIA:
129 case BufferFormat::DXT1: 132 case BufferFormat::DXT1:
130 case BufferFormat::DXT5: 133 case BufferFormat::DXT5:
131 case BufferFormat::ETC1: 134 case BufferFormat::ETC1:
135 return TextureFormat(format);
132 case BufferFormat::YUV_420: 136 case BufferFormat::YUV_420:
133 case BufferFormat::YUV_420_BIPLANAR: 137 case BufferFormat::YUV_420_BIPLANAR:
134 case BufferFormat::UYVY_422: 138 case BufferFormat::UYVY_422:
135 return TextureFormat(format); 139 NOTREACHED();
140 return 0;
136 } 141 }
137 142
138 NOTREACHED(); 143 NOTREACHED();
139 return 0; 144 return 0;
140 } 145 }
141 146
142 GLenum DataType(BufferFormat format) { 147 GLenum DataType(BufferFormat format) {
143 switch (format) { 148 switch (format) {
144 case BufferFormat::RGBA_4444: 149 case BufferFormat::RGBA_4444:
145 return GL_UNSIGNED_SHORT_4_4_4_4; 150 return GL_UNSIGNED_SHORT_4_4_4_4;
(...skipping 12 matching lines...) Expand all
158 case BufferFormat::YUV_420_BIPLANAR: 163 case BufferFormat::YUV_420_BIPLANAR:
159 case BufferFormat::UYVY_422: 164 case BufferFormat::UYVY_422:
160 NOTREACHED(); 165 NOTREACHED();
161 return 0; 166 return 0;
162 } 167 }
163 168
164 NOTREACHED(); 169 NOTREACHED();
165 return 0; 170 return 0;
166 } 171 }
167 172
173 GLint DataRowLength(size_t stride, BufferFormat format) {
174 switch (format) {
175 case BufferFormat::RGBA_4444:
176 return base::checked_cast<GLint>(stride) / 2;
177 case BufferFormat::RGBX_8888:
178 case BufferFormat::RGBA_8888:
179 case BufferFormat::BGRX_8888:
180 case BufferFormat::BGRA_8888:
181 return base::checked_cast<GLint>(stride) / 4;
182 case BufferFormat::R_8:
183 return base::checked_cast<GLint>(stride);
184 case BufferFormat::ATC:
185 case BufferFormat::ATCIA:
186 case BufferFormat::DXT1:
187 case BufferFormat::DXT5:
188 case BufferFormat::ETC1:
189 case BufferFormat::YUV_420:
190 case BufferFormat::YUV_420_BIPLANAR:
191 case BufferFormat::UYVY_422:
192 NOTREACHED();
193 return 0;
194 }
195
196 NOTREACHED();
197 return 0;
198 }
199
168 template <typename F> 200 template <typename F>
169 scoped_ptr<uint8_t[]> GLES2RGBData(const gfx::Size& size, 201 scoped_ptr<uint8_t[]> GLES2RGBData(const gfx::Size& size,
170 BufferFormat format, 202 BufferFormat format,
203 size_t stride,
171 const uint8_t* data, 204 const uint8_t* data,
172 F const& data_to_rgb, 205 F const& data_to_rgb,
173 GLenum* data_format, 206 GLenum* data_format,
174 GLenum* data_type) { 207 GLenum* data_type,
208 GLint* data_row_length) {
175 TRACE_EVENT2("gpu", "GLES2RGBData", "width", size.width(), "height", 209 TRACE_EVENT2("gpu", "GLES2RGBData", "width", size.width(), "height",
176 size.height()); 210 size.height());
177 211
178 // Four-byte row alignment as specified by glPixelStorei with argument 212 // Four-byte row alignment as specified by glPixelStorei with argument
179 // GL_UNPACK_ALIGNMENT set to 4. 213 // GL_UNPACK_ALIGNMENT set to 4.
180 size_t gles2_rgb_data_stride = (size.width() * 3 + 3) & ~3; 214 size_t gles2_rgb_data_stride = (size.width() * 3 + 3) & ~3;
181 scoped_ptr<uint8_t[]> gles2_rgb_data( 215 scoped_ptr<uint8_t[]> gles2_rgb_data(
182 new uint8_t[gles2_rgb_data_stride * size.height()]); 216 new uint8_t[gles2_rgb_data_stride * size.height()]);
183 size_t data_stride = RowSizeForBufferFormat(size.width(), format, 0);
184 217
185 for (int y = 0; y < size.height(); ++y) { 218 for (int y = 0; y < size.height(); ++y) {
186 for (int x = 0; x < size.width(); ++x) { 219 for (int x = 0; x < size.width(); ++x) {
187 data_to_rgb(&data[y * data_stride + x * 4], 220 data_to_rgb(&data[y * stride + x * 4],
188 &gles2_rgb_data[y * gles2_rgb_data_stride + x * 3]); 221 &gles2_rgb_data[y * gles2_rgb_data_stride + x * 3]);
189 } 222 }
190 } 223 }
191 224
192 *data_format = GL_RGB; 225 *data_format = GL_RGB;
193 *data_type = GL_UNSIGNED_BYTE; 226 *data_type = GL_UNSIGNED_BYTE;
227 *data_row_length = size.width();
194 return gles2_rgb_data.Pass(); 228 return gles2_rgb_data.Pass();
195 } 229 }
196 230
197 scoped_ptr<uint8_t[]> GLES2Data(const gfx::Size& size, 231 scoped_ptr<uint8_t[]> GLES2Data(const gfx::Size& size,
198 BufferFormat format, 232 BufferFormat format,
233 size_t stride,
199 const uint8_t* data, 234 const uint8_t* data,
200 GLenum* data_format, 235 GLenum* data_format,
201 GLenum* data_type) { 236 GLenum* data_type,
237 GLint* data_row_length) {
238 TRACE_EVENT2("gpu", "GLES2Data", "width", size.width(), "height",
239 size.height());
240
202 switch (format) { 241 switch (format) {
203 case BufferFormat::RGBX_8888: 242 case BufferFormat::RGBX_8888:
204 return GLES2RGBData(size, format, 243 return GLES2RGBData(size, format, stride,
205 data, [](const uint8_t* src, uint8_t* dst) { 244 data, [](const uint8_t* src, uint8_t* dst) {
206 dst[0] = src[0]; 245 dst[0] = src[0];
207 dst[1] = src[1]; 246 dst[1] = src[1];
208 dst[2] = src[2]; 247 dst[2] = src[2];
209 }, data_format, data_type); 248 }, data_format, data_type, data_row_length);
210 case BufferFormat::BGRX_8888: 249 case BufferFormat::BGRX_8888:
211 return GLES2RGBData(size, format, 250 return GLES2RGBData(size, format, stride,
212 data, [](const uint8_t* src, uint8_t* dst) { 251 data, [](const uint8_t* src, uint8_t* dst) {
213 dst[0] = src[2]; 252 dst[0] = src[2];
214 dst[1] = src[1]; 253 dst[1] = src[1];
215 dst[2] = src[0]; 254 dst[2] = src[0];
216 }, data_format, data_type); 255 }, data_format, data_type, data_row_length);
217 case BufferFormat::RGBA_4444: 256 case BufferFormat::RGBA_4444:
218 case BufferFormat::RGBA_8888: 257 case BufferFormat::RGBA_8888:
219 case BufferFormat::BGRA_8888: 258 case BufferFormat::BGRA_8888:
220 case BufferFormat::R_8: 259 case BufferFormat::R_8: {
260 size_t gles2_data_stride =
261 RowSizeForBufferFormat(size.width(), format, 0);
262 if (stride == gles2_data_stride)
263 return nullptr; // No data conversion needed
264
265 scoped_ptr<uint8_t[]> gles2_data(
266 new uint8_t[gles2_data_stride * size.height()]);
267 for (int y = 0; y < size.height(); ++y) {
268 memcpy(&gles2_data[y * gles2_data_stride], &data[y * stride],
269 gles2_data_stride);
270 }
271 *data_row_length = size.width();
272 return gles2_data.Pass();
273 }
221 case BufferFormat::ATC: 274 case BufferFormat::ATC:
222 case BufferFormat::ATCIA: 275 case BufferFormat::ATCIA:
223 case BufferFormat::DXT1: 276 case BufferFormat::DXT1:
224 case BufferFormat::DXT5: 277 case BufferFormat::DXT5:
225 case BufferFormat::ETC1: 278 case BufferFormat::ETC1:
279 return nullptr; // No data conversion needed
226 case BufferFormat::YUV_420: 280 case BufferFormat::YUV_420:
227 case BufferFormat::YUV_420_BIPLANAR: 281 case BufferFormat::YUV_420_BIPLANAR:
228 case BufferFormat::UYVY_422: 282 case BufferFormat::UYVY_422:
229 // No data conversion needed. 283 NOTREACHED();
230 return nullptr; 284 return nullptr;
231 } 285 }
232 286
233 NOTREACHED(); 287 NOTREACHED();
234 return 0; 288 return nullptr;
235 } 289 }
236 290
237 } // namespace 291 } // namespace
238 292
239 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat) 293 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat)
240 : size_(size), 294 : size_(size),
241 internalformat_(internalformat), 295 internalformat_(internalformat),
242 memory_(nullptr), 296 memory_(nullptr),
243 format_(BufferFormat::RGBA_8888) {} 297 format_(BufferFormat::RGBA_8888),
298 stride_(0) {}
244 299
245 GLImageMemory::~GLImageMemory() { 300 GLImageMemory::~GLImageMemory() {
246 DCHECK(!memory_); 301 DCHECK(!memory_);
247 } 302 }
248 303
249 bool GLImageMemory::Initialize(const unsigned char* memory, 304 bool GLImageMemory::Initialize(const unsigned char* memory,
250 BufferFormat format) { 305 BufferFormat format,
306 size_t stride) {
251 if (!ValidInternalFormat(internalformat_)) { 307 if (!ValidInternalFormat(internalformat_)) {
252 LOG(ERROR) << "Invalid internalformat: " << internalformat_; 308 LOG(ERROR) << "Invalid internalformat: " << internalformat_;
253 return false; 309 return false;
254 } 310 }
255 311
256 if (!ValidFormat(format)) { 312 if (!ValidFormat(format)) {
257 LOG(ERROR) << "Invalid format: " << static_cast<int>(format); 313 LOG(ERROR) << "Invalid format: " << static_cast<int>(format);
258 return false; 314 return false;
259 } 315 }
260 316
317 if (stride < RowSizeForBufferFormat(size_.width(), format, 0) || stride & 3) {
318 LOG(ERROR) << "Invalid stride: " << stride;
319 return false;
320 }
321
261 DCHECK(memory); 322 DCHECK(memory);
262 DCHECK(!memory_); 323 DCHECK(!memory_);
263 DCHECK(!IsCompressedFormat(format) || size_.width() % 4 == 0); 324 DCHECK(!IsCompressedFormat(format) || size_.width() % 4 == 0);
264 DCHECK(!IsCompressedFormat(format) || size_.height() % 4 == 0); 325 DCHECK(!IsCompressedFormat(format) || size_.height() % 4 == 0);
265 memory_ = memory; 326 memory_ = memory;
266 format_ = format; 327 format_ = format;
328 stride_ = stride;
267 return true; 329 return true;
268 } 330 }
269 331
270 void GLImageMemory::Destroy(bool have_context) { 332 void GLImageMemory::Destroy(bool have_context) {
271 memory_ = nullptr; 333 memory_ = nullptr;
272 } 334 }
273 335
274 gfx::Size GLImageMemory::GetSize() { 336 gfx::Size GLImageMemory::GetSize() {
275 return size_; 337 return size_;
276 } 338 }
(...skipping 13 matching lines...) Expand all
290 // GL_TEXTURE_EXTERNAL_OES is not a supported target. 352 // GL_TEXTURE_EXTERNAL_OES is not a supported target.
291 if (target == GL_TEXTURE_EXTERNAL_OES) 353 if (target == GL_TEXTURE_EXTERNAL_OES)
292 return false; 354 return false;
293 355
294 if (IsCompressedFormat(format_)) { 356 if (IsCompressedFormat(format_)) {
295 glCompressedTexImage2D( 357 glCompressedTexImage2D(
296 target, 0, TextureFormat(format_), size_.width(), size_.height(), 0, 358 target, 0, TextureFormat(format_), size_.width(), size_.height(), 0,
297 static_cast<GLsizei>(BufferSizeForBufferFormat(size_, format_)), 359 static_cast<GLsizei>(BufferSizeForBufferFormat(size_, format_)),
298 memory_); 360 memory_);
299 } else { 361 } else {
300 scoped_ptr<uint8_t[]> gles2_data;
301 GLenum data_format = DataFormat(format_); 362 GLenum data_format = DataFormat(format_);
302 GLenum data_type = DataType(format_); 363 GLenum data_type = DataType(format_);
364 GLint data_row_length = DataRowLength(stride_, format_);
365 scoped_ptr<uint8_t[]> gles2_data;
303 366
304 if (gfx::GLContext::GetCurrent()->GetVersionInfo()->is_es) 367 if (gfx::GLContext::GetCurrent()->GetVersionInfo()->is_es) {
305 gles2_data = GLES2Data(size_, format_, memory_, &data_format, &data_type); 368 gles2_data = GLES2Data(size_, format_, stride_, memory_, &data_format,
369 &data_type, &data_row_length);
370 }
371
372 if (data_row_length != size_.width())
373 glPixelStorei(GL_UNPACK_ROW_LENGTH, data_row_length);
306 374
307 glTexImage2D(target, 0, TextureFormat(format_), size_.width(), 375 glTexImage2D(target, 0, TextureFormat(format_), size_.width(),
308 size_.height(), 0, data_format, data_type, 376 size_.height(), 0, data_format, data_type,
309 gles2_data ? gles2_data.get() : memory_); 377 gles2_data ? gles2_data.get() : memory_);
378
379 if (data_row_length != size_.width())
380 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
310 } 381 }
311 382
312 return true; 383 return true;
313 } 384 }
314 385
315 bool GLImageMemory::CopyTexSubImage(unsigned target, 386 bool GLImageMemory::CopyTexSubImage(unsigned target,
316 const gfx::Point& offset, 387 const gfx::Point& offset,
317 const gfx::Rect& rect) { 388 const gfx::Rect& rect) {
318 TRACE_EVENT2("gpu", "GLImageMemory::CopyTexSubImage", "width", rect.width(), 389 TRACE_EVENT2("gpu", "GLImageMemory::CopyTexSubImage", "width", rect.width(),
319 "height", rect.height()); 390 "height", rect.height());
320 391
321 // GL_TEXTURE_EXTERNAL_OES is not a supported target. 392 // GL_TEXTURE_EXTERNAL_OES is not a supported target.
322 if (target == GL_TEXTURE_EXTERNAL_OES) 393 if (target == GL_TEXTURE_EXTERNAL_OES)
323 return false; 394 return false;
324 395
325 // Sub width is not supported. 396 // Sub width is not supported.
326 if (rect.width() != size_.width()) 397 if (rect.width() != size_.width())
327 return false; 398 return false;
328 399
329 // Height must be a multiple of 4 if compressed. 400 const uint8_t* data = memory_ + rect.y() * stride_;
330 if (IsCompressedFormat(format_) && rect.height() % 4) 401 if (IsCompressedFormat(format_)) {
331 return false; 402 // Height must be a multiple of 4.
403 if (rect.height() % 4)
404 return false;
332 405
333 const uint8_t* data =
334 memory_ + rect.y() * RowSizeForBufferFormat(size_.width(), format_, 0);
335 if (IsCompressedFormat(format_)) {
336 glCompressedTexSubImage2D( 406 glCompressedTexSubImage2D(
337 target, 0, offset.x(), offset.y(), rect.width(), rect.height(), 407 target, 0, offset.x(), offset.y(), rect.width(), rect.height(),
338 DataFormat(format_), 408 DataFormat(format_),
339 static_cast<GLsizei>(BufferSizeForBufferFormat(rect.size(), format_)), 409 static_cast<GLsizei>(BufferSizeForBufferFormat(rect.size(), format_)),
340 data); 410 data);
341 } else { 411 } else {
342 GLenum data_format = DataFormat(format_); 412 GLenum data_format = DataFormat(format_);
343 GLenum data_type = DataType(format_); 413 GLenum data_type = DataType(format_);
414 GLint data_row_length = DataRowLength(stride_, format_);
344 scoped_ptr<uint8_t[]> gles2_data; 415 scoped_ptr<uint8_t[]> gles2_data;
345 416
346 if (gfx::GLContext::GetCurrent()->GetVersionInfo()->is_es) { 417 if (gfx::GLContext::GetCurrent()->GetVersionInfo()->is_es) {
347 gles2_data = 418 gles2_data = GLES2Data(rect.size(), format_, stride_, data, &data_format,
348 GLES2Data(rect.size(), format_, data, &data_format, &data_type); 419 &data_type, &data_row_length);
349 } 420 }
350 421
422 if (data_row_length != rect.width())
423 glPixelStorei(GL_UNPACK_ROW_LENGTH, data_row_length);
424
351 glTexSubImage2D(target, 0, offset.x(), offset.y(), rect.width(), 425 glTexSubImage2D(target, 0, offset.x(), offset.y(), rect.width(),
352 rect.height(), data_format, data_type, 426 rect.height(), data_format, data_type,
353 gles2_data ? gles2_data.get() : data); 427 gles2_data ? gles2_data.get() : data);
428
429 if (data_row_length != rect.width())
430 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
354 } 431 }
355 432
356 return true; 433 return true;
357 } 434 }
358 435
359 bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, 436 bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
360 int z_order, 437 int z_order,
361 gfx::OverlayTransform transform, 438 gfx::OverlayTransform transform,
362 const gfx::Rect& bounds_rect, 439 const gfx::Rect& bounds_rect,
363 const gfx::RectF& crop_rect) { 440 const gfx::RectF& crop_rect) {
364 return false; 441 return false;
365 } 442 }
366 443
367 // static 444 // static
368 unsigned GLImageMemory::GetInternalFormatForTesting(BufferFormat format) { 445 unsigned GLImageMemory::GetInternalFormatForTesting(BufferFormat format) {
369 DCHECK(ValidFormat(format)); 446 DCHECK(ValidFormat(format));
370 return TextureFormat(format); 447 return TextureFormat(format);
371 } 448 }
372 449
373 } // namespace gl 450 } // namespace gl
OLDNEW
« no previous file with comments | « ui/gl/gl_image_memory.h ('k') | ui/gl/gl_image_ref_counted_memory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698