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

Side by Side Diff: cc/output/gl_renderer.cc

Issue 2612023002: cc: Implement overdraw feedback debugging feature. (Closed)
Patch Set: tracing support Created 3 years, 11 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 2010 The Chromium Authors. All rights reserved. 1 // Copyright 2010 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 "cc/output/gl_renderer.h" 5 #include "cc/output/gl_renderer.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <limits> 11 #include <limits>
12 #include <memory> 12 #include <memory>
13 #include <set> 13 #include <set>
14 #include <string> 14 #include <string>
15 #include <vector> 15 #include <vector>
16 16
17 #include "base/barrier_closure.h"
17 #include "base/feature_list.h" 18 #include "base/feature_list.h"
18 #include "base/logging.h" 19 #include "base/logging.h"
19 #include "base/macros.h" 20 #include "base/macros.h"
20 #include "base/memory/ptr_util.h" 21 #include "base/memory/ptr_util.h"
21 #include "base/strings/string_split.h" 22 #include "base/strings/string_split.h"
22 #include "base/strings/string_util.h" 23 #include "base/strings/string_util.h"
23 #include "base/strings/stringprintf.h" 24 #include "base/strings/stringprintf.h"
24 #include "base/threading/thread_task_runner_handle.h" 25 #include "base/threading/thread_task_runner_handle.h"
25 #include "base/trace_event/trace_event.h" 26 #include "base/trace_event/trace_event.h"
26 #include "build/build_config.h" 27 #include "build/build_config.h"
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 }; 364 };
364 365
365 gpu::gles2::GLES2Interface* gl_; 366 gpu::gles2::GLES2Interface* gl_;
366 unsigned query_id_; 367 unsigned query_id_;
367 bool is_pending_; 368 bool is_pending_;
368 base::WeakPtrFactory<SyncQuery> weak_ptr_factory_; 369 base::WeakPtrFactory<SyncQuery> weak_ptr_factory_;
369 370
370 DISALLOW_COPY_AND_ASSIGN(SyncQuery); 371 DISALLOW_COPY_AND_ASSIGN(SyncQuery);
371 }; 372 };
372 373
374 struct GLRenderer::PendingOverdrawQuery {
375 explicit PendingOverdrawQuery(unsigned query) : query(query) {}
376
377 base::CancelableClosure overdraw_callback;
378 const unsigned query;
379
380 private:
381 DISALLOW_COPY_AND_ASSIGN(PendingOverdrawQuery);
382 };
383
373 GLRenderer::GLRenderer(const RendererSettings* settings, 384 GLRenderer::GLRenderer(const RendererSettings* settings,
374 OutputSurface* output_surface, 385 OutputSurface* output_surface,
375 ResourceProvider* resource_provider, 386 ResourceProvider* resource_provider,
376 TextureMailboxDeleter* texture_mailbox_deleter, 387 TextureMailboxDeleter* texture_mailbox_deleter,
377 int highp_threshold_min) 388 int highp_threshold_min)
378 : DirectRenderer(settings, output_surface, resource_provider), 389 : DirectRenderer(settings, output_surface, resource_provider),
379 offscreen_framebuffer_id_(0), 390 offscreen_framebuffer_id_(0),
380 shared_geometry_quad_(QuadVertexRect()), 391 shared_geometry_quad_(QuadVertexRect()),
381 gl_(output_surface->context_provider()->ContextGL()), 392 gl_(output_surface->context_provider()->ContextGL()),
382 context_support_(output_surface->context_provider()->ContextSupport()), 393 context_support_(output_surface->context_provider()->ContextSupport()),
(...skipping 25 matching lines...) Expand all
408 } 419 }
409 420
410 GLRenderer::~GLRenderer() { 421 GLRenderer::~GLRenderer() {
411 while (!pending_async_read_pixels_.empty()) { 422 while (!pending_async_read_pixels_.empty()) {
412 PendingAsyncReadPixels* pending_read = 423 PendingAsyncReadPixels* pending_read =
413 pending_async_read_pixels_.back().get(); 424 pending_async_read_pixels_.back().get();
414 pending_read->finished_read_pixels_callback.Cancel(); 425 pending_read->finished_read_pixels_callback.Cancel();
415 pending_async_read_pixels_.pop_back(); 426 pending_async_read_pixels_.pop_back();
416 } 427 }
417 428
429 while (!pending_overdraw_queries_.empty()) {
430 PendingOverdrawQuery* pending_query =
431 pending_overdraw_queries_.back().get();
432 pending_query->overdraw_callback.Cancel();
433 pending_overdraw_queries_.pop_back();
434 }
435
418 CleanupSharedObjects(); 436 CleanupSharedObjects();
419 437
420 if (context_visibility_) { 438 if (context_visibility_) {
421 auto* context_provider = output_surface_->context_provider(); 439 auto* context_provider = output_surface_->context_provider();
422 auto* cache_controller = context_provider->CacheController(); 440 auto* cache_controller = context_provider->CacheController();
423 cache_controller->ClientBecameNotVisible(std::move(context_visibility_)); 441 cache_controller->ClientBecameNotVisible(std::move(context_visibility_));
424 } 442 }
425 } 443 }
426 444
427 bool GLRenderer::CanPartialSwap() { 445 bool GLRenderer::CanPartialSwap() {
446 bool overdraw_tracing_enabled;
447 TRACE_EVENT_CATEGORY_GROUP_ENABLED(
448 TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"),
449 &overdraw_tracing_enabled);
450 // Overdraw tracing requires fullscreen updates.
451 if (overdraw_tracing_enabled)
452 return false;
428 auto* context_provider = output_surface_->context_provider(); 453 auto* context_provider = output_surface_->context_provider();
429 return context_provider->ContextCapabilities().post_sub_buffer; 454 return context_provider->ContextCapabilities().post_sub_buffer;
430 } 455 }
431 456
432 void GLRenderer::DidChangeVisibility() { 457 void GLRenderer::DidChangeVisibility() {
433 if (visible_) { 458 if (visible_) {
434 output_surface_->EnsureBackbuffer(); 459 output_surface_->EnsureBackbuffer();
435 } else { 460 } else {
436 TRACE_EVENT0("cc", "GLRenderer::DidChangeVisibility dropping resources"); 461 TRACE_EVENT0("cc", "GLRenderer::DidChangeVisibility dropping resources");
437 ReleaseRenderPassTextures(); 462 ReleaseRenderPassTextures();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 } 513 }
489 514
490 void GLRenderer::ClearFramebuffer(DrawingFrame* frame) { 515 void GLRenderer::ClearFramebuffer(DrawingFrame* frame) {
491 // On DEBUG builds, opaque render passes are cleared to blue to easily see 516 // On DEBUG builds, opaque render passes are cleared to blue to easily see
492 // regions that were not drawn on the screen. 517 // regions that were not drawn on the screen.
493 if (frame->current_render_pass->has_transparent_background) 518 if (frame->current_render_pass->has_transparent_background)
494 gl_->ClearColor(0, 0, 0, 0); 519 gl_->ClearColor(0, 0, 0, 0);
495 else 520 else
496 gl_->ClearColor(0, 0, 1, 1); 521 gl_->ClearColor(0, 0, 1, 1);
497 522
498 bool always_clear = false; 523 gl_->ClearStencil(0);
524
525 bool always_clear = overdraw_feedback_;
499 #ifndef NDEBUG 526 #ifndef NDEBUG
500 always_clear = true; 527 always_clear = true;
501 #endif 528 #endif
502 if (always_clear || frame->current_render_pass->has_transparent_background) { 529 if (always_clear || frame->current_render_pass->has_transparent_background) {
503 GLbitfield clear_bits = GL_COLOR_BUFFER_BIT; 530 GLbitfield clear_bits = GL_COLOR_BUFFER_BIT;
504 if (always_clear) 531 if (always_clear)
505 clear_bits |= GL_STENCIL_BUFFER_BIT; 532 clear_bits |= GL_STENCIL_BUFFER_BIT;
506 gl_->Clear(clear_bits); 533 gl_->Clear(clear_bits);
507 } 534 }
508 } 535 }
(...skipping 2247 matching lines...) Expand 10 before | Expand all | Expand 10 after
2756 } 2783 }
2757 } 2784 }
2758 2785
2759 void GLRenderer::FinishDrawingFrame(DrawingFrame* frame) { 2786 void GLRenderer::FinishDrawingFrame(DrawingFrame* frame) {
2760 if (use_sync_query_) { 2787 if (use_sync_query_) {
2761 DCHECK(current_sync_query_); 2788 DCHECK(current_sync_query_);
2762 current_sync_query_->End(); 2789 current_sync_query_->End();
2763 pending_sync_queries_.push_back(std::move(current_sync_query_)); 2790 pending_sync_queries_.push_back(std::move(current_sync_query_));
2764 } 2791 }
2765 2792
2793 swap_buffer_rect_.Union(frame->root_damage_rect);
2794 if (overdraw_feedback_)
2795 FlushOverdrawFeedback(frame, swap_buffer_rect_);
2796
2766 current_framebuffer_lock_ = nullptr; 2797 current_framebuffer_lock_ = nullptr;
2767 swap_buffer_rect_.Union(frame->root_damage_rect);
2768 2798
2769 gl_->Disable(GL_BLEND); 2799 gl_->Disable(GL_BLEND);
2770 blend_shadow_ = false; 2800 blend_shadow_ = false;
2771 2801
2772 ScheduleCALayers(frame); 2802 ScheduleCALayers(frame);
2773 ScheduleOverlays(frame); 2803 ScheduleOverlays(frame);
2774 } 2804 }
2775 2805
2776 void GLRenderer::FinishDrawingQuadList() { 2806 void GLRenderer::FinishDrawingQuadList() {
2777 FlushTextureQuadCache(SHARED_BINDING); 2807 FlushTextureQuadCache(SHARED_BINDING);
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
2995 void GLRenderer::GetFramebufferPixelsAsync( 3025 void GLRenderer::GetFramebufferPixelsAsync(
2996 const DrawingFrame* frame, 3026 const DrawingFrame* frame,
2997 const gfx::Rect& rect, 3027 const gfx::Rect& rect,
2998 std::unique_ptr<CopyOutputRequest> request) { 3028 std::unique_ptr<CopyOutputRequest> request) {
2999 DCHECK(!request->IsEmpty()); 3029 DCHECK(!request->IsEmpty());
3000 if (request->IsEmpty()) 3030 if (request->IsEmpty())
3001 return; 3031 return;
3002 if (rect.IsEmpty()) 3032 if (rect.IsEmpty())
3003 return; 3033 return;
3004 3034
3035 if (overdraw_feedback_)
3036 FlushOverdrawFeedback(frame, rect);
3037
3005 gfx::Rect window_rect = MoveFromDrawToWindowSpace(frame, rect); 3038 gfx::Rect window_rect = MoveFromDrawToWindowSpace(frame, rect);
3006 DCHECK_GE(window_rect.x(), 0); 3039 DCHECK_GE(window_rect.x(), 0);
3007 DCHECK_GE(window_rect.y(), 0); 3040 DCHECK_GE(window_rect.y(), 0);
3008 DCHECK_LE(window_rect.right(), current_surface_size_.width()); 3041 DCHECK_LE(window_rect.right(), current_surface_size_.width());
3009 DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); 3042 DCHECK_LE(window_rect.bottom(), current_surface_size_.height());
3010 3043
3011 if (!request->force_bitmap_result()) { 3044 if (!request->force_bitmap_result()) {
3012 bool own_mailbox = !request->has_texture_mailbox(); 3045 bool own_mailbox = !request->has_texture_mailbox();
3013 3046
3014 GLuint texture_id = 0; 3047 GLuint texture_id = 0;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
3195 gl_->CopyTexImage2D(GL_TEXTURE_2D, 0, format, window_rect.x(), 3228 gl_->CopyTexImage2D(GL_TEXTURE_2D, 0, format, window_rect.x(),
3196 window_rect.y(), window_rect.width(), 3229 window_rect.y(), window_rect.width(),
3197 window_rect.height(), 0); 3230 window_rect.height(), 0);
3198 gl_->BindTexture(GL_TEXTURE_2D, 0); 3231 gl_->BindTexture(GL_TEXTURE_2D, 0);
3199 } 3232 }
3200 3233
3201 void GLRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) { 3234 void GLRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) {
3202 current_framebuffer_lock_ = nullptr; 3235 current_framebuffer_lock_ = nullptr;
3203 output_surface_->BindFramebuffer(); 3236 output_surface_->BindFramebuffer();
3204 3237
3205 if (output_surface_->HasExternalStencilTest()) { 3238 if (overdraw_feedback_) {
3239 SetupOverdrawFeedback();
3240 SetStencilEnabled(true);
3241 } else if (output_surface_->HasExternalStencilTest()) {
3206 output_surface_->ApplyExternalStencil(); 3242 output_surface_->ApplyExternalStencil();
3207 SetStencilEnabled(true); 3243 SetStencilEnabled(true);
3208 } else { 3244 } else {
3209 SetStencilEnabled(false); 3245 SetStencilEnabled(false);
3210 } 3246 }
3211 } 3247 }
3212 3248
3213 bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame, 3249 bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame,
3214 const ScopedResource* texture) { 3250 const ScopedResource* texture) {
3215 DCHECK(texture->id()); 3251 DCHECK(texture->id());
3216 3252
3217 // Explicitly release lock, otherwise we can crash when try to lock 3253 // Explicitly release lock, otherwise we can crash when try to lock
3218 // same texture again. 3254 // same texture again.
3219 current_framebuffer_lock_ = nullptr; 3255 current_framebuffer_lock_ = nullptr;
3220 3256
3221 SetStencilEnabled(false);
3222 gl_->BindFramebuffer(GL_FRAMEBUFFER, offscreen_framebuffer_id_); 3257 gl_->BindFramebuffer(GL_FRAMEBUFFER, offscreen_framebuffer_id_);
3223 current_framebuffer_lock_ = 3258 current_framebuffer_lock_ =
3224 base::MakeUnique<ResourceProvider::ScopedWriteLockGL>( 3259 base::MakeUnique<ResourceProvider::ScopedWriteLockGL>(
3225 resource_provider_, texture->id(), false); 3260 resource_provider_, texture->id(), false);
3226 current_framebuffer_format_ = texture->format(); 3261 current_framebuffer_format_ = texture->format();
3227 unsigned texture_id = current_framebuffer_lock_->texture_id(); 3262 unsigned texture_id = current_framebuffer_lock_->texture_id();
3228 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 3263 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
3229 texture_id, 0); 3264 texture_id, 0);
3265 if (overdraw_feedback_) {
3266 if (texture->size() != offscreen_stencil_renderbuffer_size_) {
3267 gl_->BindRenderbuffer(GL_RENDERBUFFER,
3268 offscreen_stencil_renderbuffer_id_);
3269 gl_->RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
3270 texture->size().width(),
3271 texture->size().height());
3272 gl_->BindRenderbuffer(GL_RENDERBUFFER, 0);
3273 offscreen_stencil_renderbuffer_size_ = texture->size();
3274 }
3275 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
3276 GL_RENDERBUFFER,
3277 offscreen_stencil_renderbuffer_id_);
3278 }
3230 3279
3231 DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) == 3280 DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) ==
3232 GL_FRAMEBUFFER_COMPLETE || 3281 GL_FRAMEBUFFER_COMPLETE ||
3233 IsContextLost()); 3282 IsContextLost());
3283
3284 if (overdraw_feedback_) {
3285 SetupOverdrawFeedback();
3286 SetStencilEnabled(true);
3287 } else {
3288 SetStencilEnabled(false);
3289 }
3234 return true; 3290 return true;
3235 } 3291 }
3236 3292
3237 void GLRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) { 3293 void GLRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) {
3238 EnsureScissorTestEnabled(); 3294 EnsureScissorTestEnabled();
3239 3295
3240 // Don't unnecessarily ask the context to change the scissor, because it 3296 // Don't unnecessarily ask the context to change the scissor, because it
3241 // may cause undesired GPU pipeline flushes. 3297 // may cause undesired GPU pipeline flushes.
3242 if (scissor_rect == scissor_rect_) 3298 if (scissor_rect == scissor_rect_)
3243 return; 3299 return;
(...skipping 10 matching lines...) Expand all
3254 current_window_space_viewport_.width(), 3310 current_window_space_viewport_.width(),
3255 current_window_space_viewport_.height()); 3311 current_window_space_viewport_.height());
3256 } 3312 }
3257 3313
3258 void GLRenderer::InitializeSharedObjects() { 3314 void GLRenderer::InitializeSharedObjects() {
3259 TRACE_EVENT0("cc", "GLRenderer::InitializeSharedObjects"); 3315 TRACE_EVENT0("cc", "GLRenderer::InitializeSharedObjects");
3260 3316
3261 // Create an FBO for doing offscreen rendering. 3317 // Create an FBO for doing offscreen rendering.
3262 gl_->GenFramebuffers(1, &offscreen_framebuffer_id_); 3318 gl_->GenFramebuffers(1, &offscreen_framebuffer_id_);
3263 3319
3320 // Create a stencil buffer for doing offscreen rendering.
3321 gl_->GenRenderbuffers(1, &offscreen_stencil_renderbuffer_id_);
Daniele Castagna 2017/01/09 18:53:06 Why not if (overdraw_feedback_) ?
reveman 2017/01/10 23:52:00 Done. By deferring this until needed.
3322
3264 shared_geometry_ = 3323 shared_geometry_ =
3265 base::MakeUnique<StaticGeometryBinding>(gl_, QuadVertexRect()); 3324 base::MakeUnique<StaticGeometryBinding>(gl_, QuadVertexRect());
3266 clipped_geometry_ = base::MakeUnique<DynamicGeometryBinding>(gl_); 3325 clipped_geometry_ = base::MakeUnique<DynamicGeometryBinding>(gl_);
3267 } 3326 }
3268 3327
3269 void GLRenderer::PrepareGeometry(BoundGeometry binding) { 3328 void GLRenderer::PrepareGeometry(BoundGeometry binding) {
3270 if (binding == bound_geometry_) { 3329 if (binding == bound_geometry_) {
3271 return; 3330 return;
3272 } 3331 }
3273 3332
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
3725 video_stream_texture_program_[i].Cleanup(gl_); 3784 video_stream_texture_program_[i].Cleanup(gl_);
3726 } 3785 }
3727 3786
3728 debug_border_program_.Cleanup(gl_); 3787 debug_border_program_.Cleanup(gl_);
3729 solid_color_program_.Cleanup(gl_); 3788 solid_color_program_.Cleanup(gl_);
3730 solid_color_program_aa_.Cleanup(gl_); 3789 solid_color_program_aa_.Cleanup(gl_);
3731 3790
3732 if (offscreen_framebuffer_id_) 3791 if (offscreen_framebuffer_id_)
3733 gl_->DeleteFramebuffers(1, &offscreen_framebuffer_id_); 3792 gl_->DeleteFramebuffers(1, &offscreen_framebuffer_id_);
3734 3793
3794 if (offscreen_stencil_renderbuffer_id_)
3795 gl_->DeleteRenderbuffers(1, &offscreen_stencil_renderbuffer_id_);
3796
3735 ReleaseRenderPassTextures(); 3797 ReleaseRenderPassTextures();
3736 } 3798 }
3737 3799
3738 void GLRenderer::ReinitializeGLState() { 3800 void GLRenderer::ReinitializeGLState() {
3739 is_scissor_enabled_ = false; 3801 is_scissor_enabled_ = false;
3740 scissor_rect_ = gfx::Rect(); 3802 scissor_rect_ = gfx::Rect();
3741 stencil_shadow_ = false; 3803 stencil_shadow_ = false;
3742 blend_shadow_ = true; 3804 blend_shadow_ = true;
3743 program_shadow_ = 0; 3805 program_shadow_ = 0;
3744 3806
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
4057 4119
4058 // The alpha has already been applied when copying the RPDQ to an IOSurface. 4120 // The alpha has already been applied when copying the RPDQ to an IOSurface.
4059 GLfloat alpha = 1; 4121 GLfloat alpha = 1;
4060 gl_->ScheduleCALayerSharedStateCHROMIUM(alpha, is_clipped, clip_rect, 4122 gl_->ScheduleCALayerSharedStateCHROMIUM(alpha, is_clipped, clip_rect,
4061 sorting_context_id, gl_transform); 4123 sorting_context_id, gl_transform);
4062 gl_->ScheduleCALayerCHROMIUM( 4124 gl_->ScheduleCALayerCHROMIUM(
4063 texture_id, contents_rect, ca_layer_overlay->background_color, 4125 texture_id, contents_rect, ca_layer_overlay->background_color,
4064 ca_layer_overlay->edge_aa_mask, bounds_rect, filter); 4126 ca_layer_overlay->edge_aa_mask, bounds_rect, filter);
4065 } 4127 }
4066 4128
4129 void GLRenderer::SetupOverdrawFeedback() {
4130 gl_->StencilFunc(GL_ALWAYS, 1, 0xffffffff);
4131 // First two values are ignored as test always passes.
4132 gl_->StencilOp(GL_KEEP, GL_KEEP, GL_INCR);
4133 gl_->StencilMask(0xff);
4134 }
4135
4136 void GLRenderer::FlushOverdrawFeedback(const DrawingFrame* frame,
4137 const gfx::Rect& output_rect) {
4138 // Return early if already flushed.
4139 if (!stencil_shadow_)
4140 return;
4141
4142 // Test only, keep everything.
4143 gl_->StencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
4144 gl_->StencilMask(0);
4145
4146 EnsureScissorTestDisabled();
4147 SetBlendEnabled(true);
4148
4149 PrepareGeometry(SHARED_BINDING);
4150
4151 const DebugBorderProgram* program = GetDebugBorderProgram();
4152 DCHECK(program && (program->initialized() || IsContextLost()));
4153 SetUseProgram(program->program());
4154
4155 gfx::Transform render_matrix;
4156 render_matrix.Translate(0.5 * output_rect.width() + output_rect.x(),
4157 0.5 * output_rect.height() + output_rect.y());
4158 render_matrix.Scale(output_rect.width(), output_rect.height());
4159 static float gl_matrix[16];
4160 GLRenderer::ToGLMatrix(&gl_matrix[0],
4161 frame->projection_matrix * render_matrix);
4162 gl_->UniformMatrix4fv(program->vertex_shader().matrix_location(), 1, false,
4163 &gl_matrix[0]);
4164
4165 // Produce hinting for the amount of overdraw on screen for each pixel by
4166 // drawing hint colors to the framebuffer based on the current stencil value.
4167 struct {
4168 int category;
4169 GLenum func;
4170 GLint ref;
4171 SkColor color;
4172 } stencil_tests[] = {
4173 {1, GL_EQUAL, 2, 0x2f0000ff}, // Blue: Overdrawn once.
4174 {2, GL_EQUAL, 3, 0x2f00ff00}, // Green: Overdrawn twice.
4175 {3, GL_EQUAL, 4, 0x3fff0000}, // Pink: Overdrawn three times.
4176 {4, GL_LESS, 4, 0x7fff0000}, // Red: Overdrawn four or more times.
4177 };
4178
4179 // Occlusion queries can be expensive, so only collect trace data if we select
4180 // cc.debug.overdraw.
4181 bool tracing_enabled;
4182 TRACE_EVENT_CATEGORY_GROUP_ENABLED(
4183 TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"), &tracing_enabled);
4184
4185 // Trace only the root render pass.
4186 if (frame->current_render_pass != frame->root_render_pass)
4187 tracing_enabled = false;
4188
4189 base::Closure barrier = base::BarrierClosure(
4190 arraysize(stencil_tests),
4191 base::Bind(&GLRenderer::UpdateOverdrawCounter, base::Unretained(this)));
4192
4193 for (const auto& test : stencil_tests) {
4194 if (tracing_enabled) {
4195 GLuint query = 0;
4196 gl_->GenQueriesEXT(1, &query);
4197 // TODO(reveman): Use SAMPLES_PASSED_ARB when available for exact amount
4198 // of overdraw.
4199 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
4200
4201 std::unique_ptr<PendingOverdrawQuery> pending_overdraw_query(
4202 new PendingOverdrawQuery(query));
4203 pending_overdraw_queries_.push_back(std::move(pending_overdraw_query));
4204 }
4205
4206 gl_->StencilFunc(test.func, test.ref, 0xffffffff);
4207 Float4 color = PremultipliedColor(test.color);
4208 gl_->Uniform4fv(program->fragment_shader().color_location(), 1, color.data);
4209 gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
4210
4211 if (tracing_enabled) {
4212 base::Closure overdraw_feedback_callback = base::Bind(
4213 &GLRenderer::OverdrawFeedback, base::Unretained(this),
4214 pending_overdraw_queries_.back()->query, test.category, barrier);
4215
4216 // Save the overdraw_feedback_callback so it can be cancelled.
4217 pending_overdraw_queries_.back()->overdraw_callback.Reset(
4218 overdraw_feedback_callback);
4219 base::Closure cancelable_callback =
4220 pending_overdraw_queries_.back()->overdraw_callback.callback();
4221
4222 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
4223 context_support_->SignalQuery(pending_overdraw_queries_.back()->query,
4224 cancelable_callback);
4225 }
4226 }
4227
4228 gl_->StencilFunc(GL_ALWAYS, 0, 0xffffffff);
4229 gl_->Disable(GL_STENCIL_TEST);
4230 stencil_shadow_ = false;
4231 }
4232
4233 void GLRenderer::OverdrawFeedback(unsigned query,
4234 int category,
4235 base::Closure barrier) {
4236 DCHECK(!pending_overdraw_queries_.empty());
4237 DCHECK_EQ(pending_overdraw_queries_.front()->query, query);
4238 pending_overdraw_queries_.pop_front();
4239
4240 unsigned result = 0;
4241 if (query) {
4242 gl_->GetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
4243 gl_->DeleteQueriesEXT(1, &query);
4244 }
4245
4246 if (result)
4247 current_overdraw_.insert(category);
4248 else
4249 current_overdraw_.erase(category);
4250
4251 barrier.Run();
4252 }
4253
4254 void GLRenderer::UpdateOverdrawCounter() const {
4255 // Report overdraw as multiple of the screen size. ie. 1x for the whole
4256 // screen is 1.0. Note: this will always report the worst overdraw on screen
4257 // as the overdraw for the whole screen until SAMPLES_PASSED_ARB is supported.
4258 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"), "GPU Overdraw",
4259 current_overdraw_.empty() ? 0 : *current_overdraw_.rbegin());
4260 }
4261
4067 } // namespace cc 4262 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698