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