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

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

Issue 2612023002: cc: Implement overdraw feedback debugging feature. (Closed)
Patch Set: make sure overdraw_feedback_ is initialized and reset properly 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
« no previous file with comments | « cc/output/gl_renderer.h ('k') | cc/output/gl_renderer_unittest.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 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>
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 } 481 }
482 482
483 void GLRenderer::ClearFramebuffer(DrawingFrame* frame) { 483 void GLRenderer::ClearFramebuffer(DrawingFrame* frame) {
484 // On DEBUG builds, opaque render passes are cleared to blue to easily see 484 // On DEBUG builds, opaque render passes are cleared to blue to easily see
485 // regions that were not drawn on the screen. 485 // regions that were not drawn on the screen.
486 if (frame->current_render_pass->has_transparent_background) 486 if (frame->current_render_pass->has_transparent_background)
487 gl_->ClearColor(0, 0, 0, 0); 487 gl_->ClearColor(0, 0, 0, 0);
488 else 488 else
489 gl_->ClearColor(0, 0, 1, 1); 489 gl_->ClearColor(0, 0, 1, 1);
490 490
491 bool always_clear = false; 491 gl_->ClearStencil(0);
492
493 bool always_clear = overdraw_feedback_;
492 #ifndef NDEBUG 494 #ifndef NDEBUG
493 always_clear = true; 495 always_clear = true;
494 #endif 496 #endif
495 if (always_clear || frame->current_render_pass->has_transparent_background) { 497 if (always_clear || frame->current_render_pass->has_transparent_background) {
496 GLbitfield clear_bits = GL_COLOR_BUFFER_BIT; 498 GLbitfield clear_bits = GL_COLOR_BUFFER_BIT;
497 if (always_clear) 499 if (always_clear)
498 clear_bits |= GL_STENCIL_BUFFER_BIT; 500 clear_bits |= GL_STENCIL_BUFFER_BIT;
499 gl_->Clear(clear_bits); 501 gl_->Clear(clear_bits);
500 } 502 }
501 } 503 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 600
599 // This function does not handle 3D sorting right now, since the debug border 601 // This function does not handle 3D sorting right now, since the debug border
600 // quads are just drawn as their original quads and not in split pieces. This 602 // quads are just drawn as their original quads and not in split pieces. This
601 // results in some debug border quads drawing over foreground quads. 603 // results in some debug border quads drawing over foreground quads.
602 void GLRenderer::DrawDebugBorderQuad(const DrawingFrame* frame, 604 void GLRenderer::DrawDebugBorderQuad(const DrawingFrame* frame,
603 const DebugBorderDrawQuad* quad) { 605 const DebugBorderDrawQuad* quad) {
604 SetBlendEnabled(quad->ShouldDrawWithBlending()); 606 SetBlendEnabled(quad->ShouldDrawWithBlending());
605 607
606 static float gl_matrix[16]; 608 static float gl_matrix[16];
607 const Program* program = GetProgram(ProgramKey::DebugBorder()); 609 const Program* program = GetProgram(ProgramKey::DebugBorder());
608 DCHECK(program && (program->initialized() || IsContextLost())); 610 DCHECK(program);
611 DCHECK(program->initialized() || IsContextLost());
609 SetUseProgram(program->program()); 612 SetUseProgram(program->program());
610 613
611 // Use the full quad_rect for debug quads to not move the edges based on 614 // Use the full quad_rect for debug quads to not move the edges based on
612 // partial swaps. 615 // partial swaps.
613 gfx::Rect layer_rect = quad->rect; 616 gfx::Rect layer_rect = quad->rect;
614 gfx::Transform render_matrix; 617 gfx::Transform render_matrix;
615 QuadRectTransform(&render_matrix, 618 QuadRectTransform(&render_matrix,
616 quad->shared_quad_state->quad_to_target_transform, 619 quad->shared_quad_state->quad_to_target_transform,
617 gfx::RectF(layer_rect)); 620 gfx::RectF(layer_rect));
618 GLRenderer::ToGLMatrix(&gl_matrix[0], 621 GLRenderer::ToGLMatrix(&gl_matrix[0],
(...skipping 1520 matching lines...) Expand 10 before | Expand all | Expand 10 after
2139 int yuv_adj_location = -1; 2142 int yuv_adj_location = -1;
2140 int alpha_location = -1; 2143 int alpha_location = -1;
2141 int resource_multiplier_location = -1; 2144 int resource_multiplier_location = -1;
2142 int resource_offset_location = -1; 2145 int resource_offset_location = -1;
2143 const Program* program = GetProgram(ProgramKey::YUVVideo( 2146 const Program* program = GetProgram(ProgramKey::YUVVideo(
2144 tex_coord_precision, sampler, 2147 tex_coord_precision, sampler,
2145 use_alpha_plane ? YUV_HAS_ALPHA_TEXTURE : YUV_NO_ALPHA_TEXTURE, 2148 use_alpha_plane ? YUV_HAS_ALPHA_TEXTURE : YUV_NO_ALPHA_TEXTURE,
2146 use_nv12 ? UV_TEXTURE_MODE_UV : UV_TEXTURE_MODE_U_V, 2149 use_nv12 ? UV_TEXTURE_MODE_UV : UV_TEXTURE_MODE_U_V,
2147 use_color_lut ? COLOR_CONVERSION_MODE_2D_LUT_AS_3D_FROM_YUV 2150 use_color_lut ? COLOR_CONVERSION_MODE_2D_LUT_AS_3D_FROM_YUV
2148 : COLOR_CONVERSION_MODE_NONE)); 2151 : COLOR_CONVERSION_MODE_NONE));
2149 DCHECK(program && (program->initialized() || IsContextLost())); 2152 DCHECK(program);
2153 DCHECK(program->initialized() || IsContextLost());
2150 SetUseProgram(program->program()); 2154 SetUseProgram(program->program());
2151 matrix_location = program->matrix_location(); 2155 matrix_location = program->matrix_location();
2152 ya_tex_scale_location = program->ya_tex_scale_location(); 2156 ya_tex_scale_location = program->ya_tex_scale_location();
2153 ya_tex_offset_location = program->ya_tex_offset_location(); 2157 ya_tex_offset_location = program->ya_tex_offset_location();
2154 uv_tex_scale_location = program->uv_tex_scale_location(); 2158 uv_tex_scale_location = program->uv_tex_scale_location();
2155 uv_tex_offset_location = program->uv_tex_offset_location(); 2159 uv_tex_offset_location = program->uv_tex_offset_location();
2156 y_texture_location = program->y_texture_location(); 2160 y_texture_location = program->y_texture_location();
2157 u_texture_location = program->u_texture_location(); 2161 u_texture_location = program->u_texture_location();
2158 v_texture_location = program->v_texture_location(); 2162 v_texture_location = program->v_texture_location();
2159 uv_texture_location = program->uv_texture_location(); 2163 uv_texture_location = program->uv_texture_location();
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
2441 gl_->DrawElements(GL_TRIANGLES, 2445 gl_->DrawElements(GL_TRIANGLES,
2442 6 * static_cast<int>(draw_cache_.matrix_data.size()), 2446 6 * static_cast<int>(draw_cache_.matrix_data.size()),
2443 GL_UNSIGNED_SHORT, 0); 2447 GL_UNSIGNED_SHORT, 0);
2444 2448
2445 // Draw the border if requested. 2449 // Draw the border if requested.
2446 if (gl_composited_texture_quad_border_) { 2450 if (gl_composited_texture_quad_border_) {
2447 // When we draw the composited borders we have one flush per quad. 2451 // When we draw the composited borders we have one flush per quad.
2448 DCHECK_EQ(1u, draw_cache_.matrix_data.size()); 2452 DCHECK_EQ(1u, draw_cache_.matrix_data.size());
2449 SetBlendEnabled(false); 2453 SetBlendEnabled(false);
2450 const Program* program = GetProgram(ProgramKey::DebugBorder()); 2454 const Program* program = GetProgram(ProgramKey::DebugBorder());
2451 DCHECK(program && (program->initialized() || IsContextLost())); 2455 DCHECK(program);
2456 DCHECK(program->initialized() || IsContextLost());
2452 SetUseProgram(program->program()); 2457 SetUseProgram(program->program());
2453 2458
2454 gl_->UniformMatrix4fv( 2459 gl_->UniformMatrix4fv(
2455 program->matrix_location(), 1, false, 2460 program->matrix_location(), 1, false,
2456 reinterpret_cast<float*>(&draw_cache_.matrix_data.front())); 2461 reinterpret_cast<float*>(&draw_cache_.matrix_data.front()));
2457 2462
2458 gl_->Uniform4f(program->color_location(), 0.0f, 1.0f, 0.0f, 1.0f); 2463 gl_->Uniform4f(program->color_location(), 0.0f, 1.0f, 0.0f, 1.0f);
2459 2464
2460 gl_->LineWidth(3.0f); 2465 gl_->LineWidth(3.0f);
2461 // The indices for the line are stored in the same array as the triangle 2466 // The indices for the line are stored in the same array as the triangle
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
2581 } 2586 }
2582 } 2587 }
2583 2588
2584 void GLRenderer::FinishDrawingFrame(DrawingFrame* frame) { 2589 void GLRenderer::FinishDrawingFrame(DrawingFrame* frame) {
2585 if (use_sync_query_) { 2590 if (use_sync_query_) {
2586 DCHECK(current_sync_query_); 2591 DCHECK(current_sync_query_);
2587 current_sync_query_->End(); 2592 current_sync_query_->End();
2588 pending_sync_queries_.push_back(std::move(current_sync_query_)); 2593 pending_sync_queries_.push_back(std::move(current_sync_query_));
2589 } 2594 }
2590 2595
2596 swap_buffer_rect_.Union(frame->root_damage_rect);
2597 if (overdraw_feedback_)
2598 FlushOverdrawFeedback(frame, swap_buffer_rect_);
2599
2591 current_framebuffer_lock_ = nullptr; 2600 current_framebuffer_lock_ = nullptr;
2592 swap_buffer_rect_.Union(frame->root_damage_rect);
2593 2601
2594 gl_->Disable(GL_BLEND); 2602 gl_->Disable(GL_BLEND);
2595 blend_shadow_ = false; 2603 blend_shadow_ = false;
2596 2604
2597 ScheduleCALayers(frame); 2605 ScheduleCALayers(frame);
2598 ScheduleOverlays(frame); 2606 ScheduleOverlays(frame);
2599 } 2607 }
2600 2608
2601 void GLRenderer::FinishDrawingQuadList() { 2609 void GLRenderer::FinishDrawingQuadList() {
2602 FlushTextureQuadCache(SHARED_BINDING); 2610 FlushTextureQuadCache(SHARED_BINDING);
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
2820 void GLRenderer::GetFramebufferPixelsAsync( 2828 void GLRenderer::GetFramebufferPixelsAsync(
2821 const DrawingFrame* frame, 2829 const DrawingFrame* frame,
2822 const gfx::Rect& rect, 2830 const gfx::Rect& rect,
2823 std::unique_ptr<CopyOutputRequest> request) { 2831 std::unique_ptr<CopyOutputRequest> request) {
2824 DCHECK(!request->IsEmpty()); 2832 DCHECK(!request->IsEmpty());
2825 if (request->IsEmpty()) 2833 if (request->IsEmpty())
2826 return; 2834 return;
2827 if (rect.IsEmpty()) 2835 if (rect.IsEmpty())
2828 return; 2836 return;
2829 2837
2838 if (overdraw_feedback_)
2839 FlushOverdrawFeedback(frame, rect);
2840
2830 gfx::Rect window_rect = MoveFromDrawToWindowSpace(frame, rect); 2841 gfx::Rect window_rect = MoveFromDrawToWindowSpace(frame, rect);
2831 DCHECK_GE(window_rect.x(), 0); 2842 DCHECK_GE(window_rect.x(), 0);
2832 DCHECK_GE(window_rect.y(), 0); 2843 DCHECK_GE(window_rect.y(), 0);
2833 DCHECK_LE(window_rect.right(), current_surface_size_.width()); 2844 DCHECK_LE(window_rect.right(), current_surface_size_.width());
2834 DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); 2845 DCHECK_LE(window_rect.bottom(), current_surface_size_.height());
2835 2846
2836 if (!request->force_bitmap_result()) { 2847 if (!request->force_bitmap_result()) {
2837 bool own_mailbox = !request->has_texture_mailbox(); 2848 bool own_mailbox = !request->has_texture_mailbox();
2838 2849
2839 GLuint texture_id = 0; 2850 GLuint texture_id = 0;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
3011 gl_->CopyTexImage2D(GL_TEXTURE_2D, 0, format, window_rect.x(), 3022 gl_->CopyTexImage2D(GL_TEXTURE_2D, 0, format, window_rect.x(),
3012 window_rect.y(), window_rect.width(), 3023 window_rect.y(), window_rect.width(),
3013 window_rect.height(), 0); 3024 window_rect.height(), 0);
3014 gl_->BindTexture(GL_TEXTURE_2D, 0); 3025 gl_->BindTexture(GL_TEXTURE_2D, 0);
3015 } 3026 }
3016 3027
3017 void GLRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) { 3028 void GLRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) {
3018 current_framebuffer_lock_ = nullptr; 3029 current_framebuffer_lock_ = nullptr;
3019 output_surface_->BindFramebuffer(); 3030 output_surface_->BindFramebuffer();
3020 3031
3021 if (output_surface_->HasExternalStencilTest()) { 3032 if (overdraw_feedback_) {
3033 // Output surfaces that require an external stencil test should not allow
3034 // overdraw feedback by setting |supports_stencil| to false.
3035 DCHECK(!output_surface_->HasExternalStencilTest());
3036 SetupOverdrawFeedback();
3037 SetStencilEnabled(true);
3038 } else if (output_surface_->HasExternalStencilTest()) {
3022 output_surface_->ApplyExternalStencil(); 3039 output_surface_->ApplyExternalStencil();
3023 SetStencilEnabled(true); 3040 SetStencilEnabled(true);
3024 } else { 3041 } else {
3025 SetStencilEnabled(false); 3042 SetStencilEnabled(false);
3026 } 3043 }
3027 } 3044 }
3028 3045
3029 bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame, 3046 bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame,
3030 const ScopedResource* texture) { 3047 const ScopedResource* texture) {
3031 DCHECK(texture->id()); 3048 DCHECK(texture->id());
3032 3049
3033 // Explicitly release lock, otherwise we can crash when try to lock 3050 // Explicitly release lock, otherwise we can crash when try to lock
3034 // same texture again. 3051 // same texture again.
3035 current_framebuffer_lock_ = nullptr; 3052 current_framebuffer_lock_ = nullptr;
3036 3053
3037 SetStencilEnabled(false);
3038 gl_->BindFramebuffer(GL_FRAMEBUFFER, offscreen_framebuffer_id_); 3054 gl_->BindFramebuffer(GL_FRAMEBUFFER, offscreen_framebuffer_id_);
3039 current_framebuffer_lock_ = 3055 current_framebuffer_lock_ =
3040 base::MakeUnique<ResourceProvider::ScopedWriteLockGL>( 3056 base::MakeUnique<ResourceProvider::ScopedWriteLockGL>(
3041 resource_provider_, texture->id(), false); 3057 resource_provider_, texture->id(), false);
3042 current_framebuffer_format_ = texture->format(); 3058 current_framebuffer_format_ = texture->format();
3043 unsigned texture_id = current_framebuffer_lock_->texture_id(); 3059 unsigned texture_id = current_framebuffer_lock_->texture_id();
3044 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 3060 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
3045 texture_id, 0); 3061 texture_id, 0);
3062 if (overdraw_feedback_) {
3063 if (!offscreen_stencil_renderbuffer_id_)
3064 gl_->GenRenderbuffers(1, &offscreen_stencil_renderbuffer_id_);
3065 if (texture->size() != offscreen_stencil_renderbuffer_size_) {
3066 gl_->BindRenderbuffer(GL_RENDERBUFFER,
3067 offscreen_stencil_renderbuffer_id_);
3068 gl_->RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
3069 texture->size().width(),
3070 texture->size().height());
3071 gl_->BindRenderbuffer(GL_RENDERBUFFER, 0);
3072 offscreen_stencil_renderbuffer_size_ = texture->size();
3073 }
3074 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
3075 GL_RENDERBUFFER,
3076 offscreen_stencil_renderbuffer_id_);
3077 }
3046 3078
3047 DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) == 3079 DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) ==
3048 GL_FRAMEBUFFER_COMPLETE || 3080 GL_FRAMEBUFFER_COMPLETE ||
3049 IsContextLost()); 3081 IsContextLost());
3082
3083 if (overdraw_feedback_) {
3084 SetupOverdrawFeedback();
3085 SetStencilEnabled(true);
3086 } else {
3087 SetStencilEnabled(false);
3088 }
3050 return true; 3089 return true;
3051 } 3090 }
3052 3091
3053 void GLRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) { 3092 void GLRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) {
3054 EnsureScissorTestEnabled(); 3093 EnsureScissorTestEnabled();
3055 3094
3056 // Don't unnecessarily ask the context to change the scissor, because it 3095 // Don't unnecessarily ask the context to change the scissor, because it
3057 // may cause undesired GPU pipeline flushes. 3096 // may cause undesired GPU pipeline flushes.
3058 if (scissor_rect == scissor_rect_) 3097 if (scissor_rect == scissor_rect_)
3059 return; 3098 return;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
3120 void GLRenderer::CleanupSharedObjects() { 3159 void GLRenderer::CleanupSharedObjects() {
3121 shared_geometry_ = nullptr; 3160 shared_geometry_ = nullptr;
3122 3161
3123 for (auto& iter : program_cache_) 3162 for (auto& iter : program_cache_)
3124 iter.second->Cleanup(gl_); 3163 iter.second->Cleanup(gl_);
3125 program_cache_.clear(); 3164 program_cache_.clear();
3126 3165
3127 if (offscreen_framebuffer_id_) 3166 if (offscreen_framebuffer_id_)
3128 gl_->DeleteFramebuffers(1, &offscreen_framebuffer_id_); 3167 gl_->DeleteFramebuffers(1, &offscreen_framebuffer_id_);
3129 3168
3169 if (offscreen_stencil_renderbuffer_id_)
3170 gl_->DeleteRenderbuffers(1, &offscreen_stencil_renderbuffer_id_);
3171
3130 ReleaseRenderPassTextures(); 3172 ReleaseRenderPassTextures();
3131 } 3173 }
3132 3174
3133 void GLRenderer::ReinitializeGLState() { 3175 void GLRenderer::ReinitializeGLState() {
3134 is_scissor_enabled_ = false; 3176 is_scissor_enabled_ = false;
3135 scissor_rect_ = gfx::Rect(); 3177 scissor_rect_ = gfx::Rect();
3136 stencil_shadow_ = false; 3178 stencil_shadow_ = false;
3137 blend_shadow_ = true; 3179 blend_shadow_ = true;
3138 program_shadow_ = 0; 3180 program_shadow_ = 0;
3139 3181
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
3452 3494
3453 // The alpha has already been applied when copying the RPDQ to an IOSurface. 3495 // The alpha has already been applied when copying the RPDQ to an IOSurface.
3454 GLfloat alpha = 1; 3496 GLfloat alpha = 1;
3455 gl_->ScheduleCALayerSharedStateCHROMIUM(alpha, is_clipped, clip_rect, 3497 gl_->ScheduleCALayerSharedStateCHROMIUM(alpha, is_clipped, clip_rect,
3456 sorting_context_id, gl_transform); 3498 sorting_context_id, gl_transform);
3457 gl_->ScheduleCALayerCHROMIUM( 3499 gl_->ScheduleCALayerCHROMIUM(
3458 texture_id, contents_rect, ca_layer_overlay->background_color, 3500 texture_id, contents_rect, ca_layer_overlay->background_color,
3459 ca_layer_overlay->edge_aa_mask, bounds_rect, filter); 3501 ca_layer_overlay->edge_aa_mask, bounds_rect, filter);
3460 } 3502 }
3461 3503
3504 void GLRenderer::SetupOverdrawFeedback() {
3505 gl_->StencilFunc(GL_ALWAYS, 1, 0xffffffff);
3506 // First two values are ignored as test always passes.
3507 gl_->StencilOp(GL_KEEP, GL_KEEP, GL_INCR);
3508 gl_->StencilMask(0xffffffff);
3509 }
3510
3511 void GLRenderer::FlushOverdrawFeedback(const DrawingFrame* frame,
3512 const gfx::Rect& output_rect) {
3513 DCHECK(stencil_shadow_);
3514
3515 // Test only, keep everything.
3516 gl_->StencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
3517
3518 EnsureScissorTestDisabled();
3519 SetBlendEnabled(true);
3520
3521 PrepareGeometry(SHARED_BINDING);
3522
3523 const Program* program = GetProgram(ProgramKey::DebugBorder());
3524 DCHECK(program);
3525 DCHECK(program->initialized() || IsContextLost());
3526 SetUseProgram(program->program());
3527
3528 gfx::Transform render_matrix;
3529 render_matrix.Translate(0.5 * output_rect.width() + output_rect.x(),
3530 0.5 * output_rect.height() + output_rect.y());
3531 render_matrix.Scale(output_rect.width(), output_rect.height());
3532 static float gl_matrix[16];
3533 GLRenderer::ToGLMatrix(&gl_matrix[0],
3534 frame->projection_matrix * render_matrix);
3535 gl_->UniformMatrix4fv(program->matrix_location(), 1, false, &gl_matrix[0]);
3536
3537 // Produce hinting for the amount of overdraw on screen for each pixel by
3538 // drawing hint colors to the framebuffer based on the current stencil value.
3539 struct {
3540 int multiplier;
3541 GLenum func;
3542 GLint ref;
3543 SkColor color;
3544 } stencil_tests[] = {
3545 {1, GL_EQUAL, 2, 0x2f0000ff}, // Blue: Overdrawn once.
3546 {2, GL_EQUAL, 3, 0x2f00ff00}, // Green: Overdrawn twice.
3547 {3, GL_EQUAL, 4, 0x3fff0000}, // Pink: Overdrawn three times.
3548 {4, GL_LESS, 4, 0x7fff0000}, // Red: Overdrawn four or more times.
3549 };
3550
3551 // Occlusion queries can be expensive, so only collect trace data if we select
3552 // cc.debug.overdraw.
3553 bool tracing_enabled;
3554 TRACE_EVENT_CATEGORY_GROUP_ENABLED(
3555 TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"), &tracing_enabled);
3556
3557 // Trace only the root render pass.
3558 if (frame->current_render_pass != frame->root_render_pass)
3559 tracing_enabled = false;
3560
3561 OverdrawFeedbackCallback overdraw_feedback_callback = base::Bind(
3562 &GLRenderer::ProcessOverdrawFeedback, weak_ptr_factory_.GetWeakPtr(),
3563 base::Owned(new std::vector<int>), arraysize(stencil_tests));
3564
3565 for (const auto& test : stencil_tests) {
3566 GLuint query = 0;
3567 if (tracing_enabled) {
3568 gl_->GenQueriesEXT(1, &query);
3569 // TODO(reveman): Use SAMPLES_PASSED_ARB for exact amount of overdraw.
3570 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
3571 }
3572
3573 gl_->StencilFunc(test.func, test.ref, 0xffffffff);
3574 // Transparent color unless color-coding of overdraw is enabled.
3575 Float4 color =
3576 PremultipliedColor(settings_->show_overdraw_feedback ? test.color : 0);
3577 gl_->Uniform4fv(program->color_location(), 1, color.data);
3578 gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
3579
3580 if (query) {
3581 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3582 context_support_->SignalQuery(
3583 query,
3584 base::Bind(overdraw_feedback_callback, query, test.multiplier));
3585 }
3586 }
3587 }
3588
3589 void GLRenderer::ProcessOverdrawFeedback(std::vector<int>* overdraw,
3590 size_t num_expected_results,
3591 unsigned query,
3592 int multiplier) {
3593 unsigned result = 0;
3594 if (query) {
3595 gl_->GetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
3596 DCHECK_LE(result, 1u);
3597 gl_->DeleteQueriesEXT(1, &query);
3598 }
3599
3600 // Apply multiplier to get the amount of overdraw.
3601 overdraw->push_back(result * multiplier);
3602
3603 // Return early if we are expecting more results.
3604 if (overdraw->size() < num_expected_results)
3605 return;
3606
3607 // Report the maximum amount of overdraw.
3608 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"), "GPU Overdraw",
3609 *std::max_element(overdraw->begin(), overdraw->end()));
3610 }
3611
3462 } // namespace cc 3612 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/gl_renderer.h ('k') | cc/output/gl_renderer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698