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

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

Issue 1323593003: Log both GL and cpu-side memory in GLImage*Memory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 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"
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 } 136 }
137 137
138 GLsizei SizeInBytes(const Size& size, BufferFormat format) { 138 GLsizei SizeInBytes(const Size& size, BufferFormat format) {
139 size_t stride_in_bytes = 0; 139 size_t stride_in_bytes = 0;
140 bool valid_stride = GLImageMemory::StrideInBytes( 140 bool valid_stride = GLImageMemory::StrideInBytes(
141 size.width(), format, &stride_in_bytes); 141 size.width(), format, &stride_in_bytes);
142 DCHECK(valid_stride); 142 DCHECK(valid_stride);
143 return static_cast<GLsizei>(stride_in_bytes * size.height()); 143 return static_cast<GLsizei>(stride_in_bytes * size.height());
144 } 144 }
145 145
146 bool GetTextureBindingForTarget(GLenum target, GLenum* binding) {
147 switch (target) {
148 case GL_TEXTURE_2D:
149 *binding = GL_TEXTURE_BINDING_2D;
150 return true;
151 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
152 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
153 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
154 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
155 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
156 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
157 *binding = GL_TEXTURE_BINDING_CUBE_MAP;
158 return true;
159 case GL_TEXTURE_RECTANGLE_ARB:
160 *binding = GL_TEXTURE_BINDING_RECTANGLE_ARB;
161 return true;
162 case GL_TEXTURE_EXTERNAL_OES:
163 *binding = GL_TEXTURE_BINDING_EXTERNAL_OES;
164 return true;
165 }
166
167 return false;
168 }
169
146 } // namespace 170 } // namespace
147 171
148 GLImageMemory::GLImageMemory(const Size& size, unsigned internalformat) 172 GLImageMemory::GLImageMemory(const Size& size, unsigned internalformat)
149 : size_(size), 173 : size_(size),
150 internalformat_(internalformat), 174 internalformat_(internalformat),
151 memory_(NULL), 175 memory_(NULL),
152 format_(BufferFormat::RGBA_8888), 176 format_(BufferFormat::RGBA_8888),
153 in_use_(false), 177 in_use_(false),
154 target_(0), 178 target_(0),
155 need_do_bind_tex_image_(false) 179 need_do_bind_tex_image_(false),
180 texture_id_(0u),
181 need_to_free_texture_id_(false)
156 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ 182 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
157 defined(USE_OZONE) 183 defined(USE_OZONE)
158 , 184 ,
159 egl_texture_id_(0u),
160 egl_image_(EGL_NO_IMAGE_KHR) 185 egl_image_(EGL_NO_IMAGE_KHR)
161 #endif 186 #endif
162 { 187 {
163 } 188 }
164 189
165 GLImageMemory::~GLImageMemory() { 190 GLImageMemory::~GLImageMemory() {
166 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ 191 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
167 defined(USE_OZONE) 192 defined(USE_OZONE)
168 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_); 193 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_);
169 DCHECK_EQ(0u, egl_texture_id_); 194 DCHECK_IMPLIES(need_to_free_texture_id_, texture_id_ == 0u);
170 #endif 195 #endif
171 } 196 }
172 197
173 // static 198 // static
174 bool GLImageMemory::StrideInBytes(size_t width, 199 bool GLImageMemory::StrideInBytes(size_t width,
175 BufferFormat format, 200 BufferFormat format,
176 size_t* stride_in_bytes) { 201 size_t* stride_in_bytes) {
177 base::CheckedNumeric<size_t> checked_stride = width; 202 base::CheckedNumeric<size_t> checked_stride = width;
178 switch (format) { 203 switch (format) {
179 case BufferFormat::ATCIA: 204 case BufferFormat::ATCIA:
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 } 263 }
239 264
240 void GLImageMemory::Destroy(bool have_context) { 265 void GLImageMemory::Destroy(bool have_context) {
241 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ 266 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
242 defined(USE_OZONE) 267 defined(USE_OZONE)
243 if (egl_image_ != EGL_NO_IMAGE_KHR) { 268 if (egl_image_ != EGL_NO_IMAGE_KHR) {
244 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_); 269 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_);
245 egl_image_ = EGL_NO_IMAGE_KHR; 270 egl_image_ = EGL_NO_IMAGE_KHR;
246 } 271 }
247 272
248 if (egl_texture_id_) { 273 if (texture_id_ && need_to_free_texture_id_) {
249 if (have_context) 274 if (have_context)
250 glDeleteTextures(1, &egl_texture_id_); 275 glDeleteTextures(1, &texture_id_);
251 egl_texture_id_ = 0u; 276 texture_id_ = 0u;
252 } 277 }
253 #endif 278 #endif
254 memory_ = NULL; 279 memory_ = NULL;
255 } 280 }
256 281
257 Size GLImageMemory::GetSize() { 282 Size GLImageMemory::GetSize() {
258 return size_; 283 return size_;
259 } 284 }
260 285
261 unsigned GLImageMemory::GetInternalFormat() { 286 unsigned GLImageMemory::GetInternalFormat() {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 TRACE_EVENT0("gpu", "GLImageMemory::DoBindTexImage"); 370 TRACE_EVENT0("gpu", "GLImageMemory::DoBindTexImage");
346 371
347 DCHECK(need_do_bind_tex_image_); 372 DCHECK(need_do_bind_tex_image_);
348 need_do_bind_tex_image_ = false; 373 need_do_bind_tex_image_ = false;
349 374
350 DCHECK(memory_); 375 DCHECK(memory_);
351 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ 376 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
352 defined(USE_OZONE) 377 defined(USE_OZONE)
353 if (target == GL_TEXTURE_EXTERNAL_OES) { 378 if (target == GL_TEXTURE_EXTERNAL_OES) {
354 if (egl_image_ == EGL_NO_IMAGE_KHR) { 379 if (egl_image_ == EGL_NO_IMAGE_KHR) {
355 DCHECK_EQ(0u, egl_texture_id_); 380 DCHECK_EQ(0u, texture_id_);
356 glGenTextures(1, &egl_texture_id_); 381 glGenTextures(1, &texture_id_);
382 need_to_free_texture_id_ = true;
357 383
358 { 384 {
359 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); 385 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_);
360 386
361 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 387 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
362 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 388 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
363 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 389 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
364 if (IsCompressedFormat(format_)) { 390 if (IsCompressedFormat(format_)) {
365 glCompressedTexImage2D(GL_TEXTURE_2D, 391 glCompressedTexImage2D(GL_TEXTURE_2D,
366 0, // mip level 392 0, // mip level
367 TextureFormat(format_), size_.width(), 393 TextureFormat(format_), size_.width(),
368 size_.height(), 394 size_.height(),
369 0, // border 395 0, // border
370 SizeInBytes(size_, format_), memory_); 396 SizeInBytes(size_, format_), memory_);
371 } else { 397 } else {
372 glTexImage2D(GL_TEXTURE_2D, 398 glTexImage2D(GL_TEXTURE_2D,
373 0, // mip level 399 0, // mip level
374 TextureFormat(format_), 400 TextureFormat(format_),
375 size_.width(), 401 size_.width(),
376 size_.height(), 402 size_.height(),
377 0, // border 403 0, // border
378 DataFormat(format_), 404 DataFormat(format_),
379 DataType(format_), 405 DataType(format_),
380 memory_); 406 memory_);
381 } 407 }
382 } 408 }
383 409
384 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; 410 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
385 // Need to pass current EGL rendering context to eglCreateImageKHR for 411 // Need to pass current EGL rendering context to eglCreateImageKHR for
386 // target type EGL_GL_TEXTURE_2D_KHR. 412 // target type EGL_GL_TEXTURE_2D_KHR.
387 egl_image_ = 413 egl_image_ = eglCreateImageKHR(
388 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), 414 GLSurfaceEGL::GetHardwareDisplay(), eglGetCurrentContext(),
389 eglGetCurrentContext(), 415 EGL_GL_TEXTURE_2D_KHR, reinterpret_cast<EGLClientBuffer>(texture_id_),
390 EGL_GL_TEXTURE_2D_KHR, 416 attrs);
391 reinterpret_cast<EGLClientBuffer>(egl_texture_id_),
392 attrs);
393 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) 417 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_)
394 << "Error creating EGLImage: " << eglGetError(); 418 << "Error creating EGLImage: " << eglGetError();
395 } else { 419 } else {
396 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); 420 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_);
397 421
398 if (IsCompressedFormat(format_)) { 422 if (IsCompressedFormat(format_)) {
399 glCompressedTexSubImage2D(GL_TEXTURE_2D, 423 glCompressedTexSubImage2D(GL_TEXTURE_2D,
400 0, // mip level 424 0, // mip level
401 0, // x-offset 425 0, // x-offset
402 0, // y-offset 426 0, // y-offset
403 size_.width(), size_.height(), 427 size_.width(), size_.height(),
404 DataFormat(format_), 428 DataFormat(format_),
405 SizeInBytes(size_, format_), memory_); 429 SizeInBytes(size_, format_), memory_);
406 } else { 430 } else {
407 glTexSubImage2D(GL_TEXTURE_2D, 431 glTexSubImage2D(GL_TEXTURE_2D,
408 0, // mip level 432 0, // mip level
409 0, // x-offset 433 0, // x-offset
410 0, // y-offset 434 0, // y-offset
411 size_.width(), 435 size_.width(),
412 size_.height(), 436 size_.height(),
413 DataFormat(format_), 437 DataFormat(format_),
414 DataType(format_), 438 DataType(format_),
415 memory_); 439 memory_);
416 } 440 }
417 } 441 }
418 442
419 glEGLImageTargetTexture2DOES(target, egl_image_); 443 glEGLImageTargetTexture2DOES(target, egl_image_);
420 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); 444 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
421 return; 445 return;
422 } 446 }
423 #endif 447 #endif
424 448
449 // Make sure the same image is only ever bound to one texture.
reveman 2015/08/31 17:38:48 I don't think any of this is needed as we will alw
ericrk 2015/08/31 18:31:14 sgtm - added a comment and used the original logic
450 GLenum binding;
451 if (!GetTextureBindingForTarget(target, &binding)) {
452 LOG(ERROR) << "Trying to bind image to an invalid target";
453 return;
454 }
455
456 GLuint texture_id;
457 glGetIntegerv(binding, reinterpret_cast<GLint*>(&texture_id));
458 if (!texture_id) {
459 LOG(ERROR) << "Trying to bind image without no texture bound";
460 return;
461 }
462
463 if (texture_id_ && texture_id_ != texture_id) {
464 LOG(ERROR) << "Image can only be bound to one texture ID";
465 return;
466 }
467
468 texture_id_ = texture_id;
469
425 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); 470 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target);
426 if (IsCompressedFormat(format_)) { 471 if (IsCompressedFormat(format_)) {
427 glCompressedTexImage2D(target, 472 glCompressedTexImage2D(target,
428 0, // mip level 473 0, // mip level
429 TextureFormat(format_), size_.width(), 474 TextureFormat(format_), size_.width(),
430 size_.height(), 475 size_.height(),
431 0, // border 476 0, // border
432 SizeInBytes(size_, format_), memory_); 477 SizeInBytes(size_, format_), memory_);
433 } else { 478 } else {
434 glTexImage2D(target, 479 glTexImage2D(target,
435 0, // mip level 480 0, // mip level
436 TextureFormat(format_), 481 TextureFormat(format_),
437 size_.width(), 482 size_.width(),
438 size_.height(), 483 size_.height(),
439 0, // border 484 0, // border
440 DataFormat(format_), 485 DataFormat(format_),
441 DataType(format_), 486 DataType(format_),
442 memory_); 487 memory_);
443 } 488 }
444 } 489 }
445 490
446 void GLImageMemory::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, 491 void GLImageMemory::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
447 uint64_t process_tracing_id, 492 uint64_t process_tracing_id,
448 const std::string& dump_name) { 493 const std::string& dump_name) {
449 // Log size 0 if |ref_counted_memory_| has been released. 494 size_t size_in_bytes = texture_id_ ? SizeInBytes(size_, format_) : 0;
450 size_t size_in_bytes = memory_ ? SizeInBytes(size_, format_) : 0;
451 495
452 base::trace_event::MemoryAllocatorDump* dump = 496 base::trace_event::MemoryAllocatorDump* dump =
453 pmd->CreateAllocatorDump(dump_name); 497 pmd->CreateAllocatorDump(dump_name + "/texture_memory");
454 dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, 498 dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
455 base::trace_event::MemoryAllocatorDump::kUnitsBytes, 499 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
456 static_cast<uint64_t>(size_in_bytes)); 500 static_cast<uint64_t>(size_in_bytes));
501
502 // No need for a global shared edge here. This object in the GPU process is
503 // the sole owner of this texture id.
457 } 504 }
458 505
459 } // namespace gfx 506 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698