| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |