| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 capabilities_.allow_partial_texture_updates = true; | 366 capabilities_.allow_partial_texture_updates = true; |
| 367 | 367 |
| 368 capabilities_.using_image = context_caps.gpu.image; | 368 capabilities_.using_image = context_caps.gpu.image; |
| 369 | 369 |
| 370 capabilities_.using_discard_framebuffer = | 370 capabilities_.using_discard_framebuffer = |
| 371 context_caps.gpu.discard_framebuffer; | 371 context_caps.gpu.discard_framebuffer; |
| 372 | 372 |
| 373 capabilities_.allow_rasterize_on_demand = true; | 373 capabilities_.allow_rasterize_on_demand = true; |
| 374 | 374 |
| 375 use_sync_query_ = context_caps.gpu.sync_query; | 375 use_sync_query_ = context_caps.gpu.sync_query; |
| 376 use_blend_minmax_ = context_caps.gpu.blend_minmax; | |
| 377 use_blend_equation_advanced_ = context_caps.gpu.blend_equation_advanced; | 376 use_blend_equation_advanced_ = context_caps.gpu.blend_equation_advanced; |
| 378 use_blend_equation_advanced_coherent_ = | 377 use_blend_equation_advanced_coherent_ = |
| 379 context_caps.gpu.blend_equation_advanced_coherent; | 378 context_caps.gpu.blend_equation_advanced_coherent; |
| 380 | 379 |
| 381 InitializeSharedObjects(); | 380 InitializeSharedObjects(); |
| 382 } | 381 } |
| 383 | 382 |
| 384 GLRenderer::~GLRenderer() { | 383 GLRenderer::~GLRenderer() { |
| 385 while (!pending_async_read_pixels_.empty()) { | 384 while (!pending_async_read_pixels_.empty()) { |
| 386 PendingAsyncReadPixels* pending_read = pending_async_read_pixels_.back(); | 385 PendingAsyncReadPixels* pending_read = pending_async_read_pixels_.back(); |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 // Flush the GrContext to ensure all buffered GL calls are drawn to the | 730 // Flush the GrContext to ensure all buffered GL calls are drawn to the |
| 732 // backing store before we access and return it, and have cc begin using the | 731 // backing store before we access and return it, and have cc begin using the |
| 733 // GL context again. | 732 // GL context again. |
| 734 canvas->flush(); | 733 canvas->flush(); |
| 735 | 734 |
| 736 return image; | 735 return image; |
| 737 } | 736 } |
| 738 | 737 |
| 739 bool GLRenderer::CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { | 738 bool GLRenderer::CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { |
| 740 return use_blend_equation_advanced_ || | 739 return use_blend_equation_advanced_ || |
| 741 (use_blend_minmax_ && blend_mode == SkXfermode::kLighten_Mode) || | |
| 742 blend_mode == SkXfermode::kScreen_Mode || | 740 blend_mode == SkXfermode::kScreen_Mode || |
| 743 blend_mode == SkXfermode::kSrcOver_Mode; | 741 blend_mode == SkXfermode::kSrcOver_Mode; |
| 744 } | 742 } |
| 745 | 743 |
| 746 void GLRenderer::ApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { | 744 void GLRenderer::ApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { |
| 747 DCHECK(CanApplyBlendModeUsingBlendFunc(blend_mode)); | 745 DCHECK(CanApplyBlendModeUsingBlendFunc(blend_mode)); |
| 748 | 746 |
| 749 // Any modes set here must be reset in RestoreBlendFuncToDefault | 747 // Any modes set here must be reset in RestoreBlendFuncToDefault |
| 750 if (use_blend_equation_advanced_) { | 748 if (use_blend_equation_advanced_) { |
| 751 GLenum equation = GL_FUNC_ADD; | 749 GLenum equation = GL_FUNC_ADD; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 equation = GL_HSL_LUMINOSITY_KHR; | 795 equation = GL_HSL_LUMINOSITY_KHR; |
| 798 break; | 796 break; |
| 799 default: | 797 default: |
| 800 return; | 798 return; |
| 801 } | 799 } |
| 802 | 800 |
| 803 GLC(gl_, gl_->BlendEquation(equation)); | 801 GLC(gl_, gl_->BlendEquation(equation)); |
| 804 } else { | 802 } else { |
| 805 if (blend_mode == SkXfermode::kScreen_Mode) { | 803 if (blend_mode == SkXfermode::kScreen_Mode) { |
| 806 GLC(gl_, gl_->BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE)); | 804 GLC(gl_, gl_->BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE)); |
| 807 } else if (blend_mode == SkXfermode::kLighten_Mode) { | |
| 808 GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE)); | |
| 809 GLC(gl_, gl_->BlendEquation(GL_MAX_EXT)); | |
| 810 } | 805 } |
| 811 } | 806 } |
| 812 } | 807 } |
| 813 | 808 |
| 814 void GLRenderer::RestoreBlendFuncToDefault(SkXfermode::Mode blend_mode) { | 809 void GLRenderer::RestoreBlendFuncToDefault(SkXfermode::Mode blend_mode) { |
| 815 if (blend_mode == SkXfermode::kSrcOver_Mode) | 810 if (blend_mode == SkXfermode::kSrcOver_Mode) |
| 816 return; | 811 return; |
| 817 | 812 |
| 818 if (use_blend_equation_advanced_) { | 813 if (use_blend_equation_advanced_) { |
| 819 GLC(gl_, gl_->BlendEquation(GL_FUNC_ADD)); | 814 GLC(gl_, gl_->BlendEquation(GL_FUNC_ADD)); |
| 820 } else { | 815 } else { |
| 821 GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); | 816 GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); |
| 822 | |
| 823 if (blend_mode == SkXfermode::kLighten_Mode) | |
| 824 GLC(gl_, gl_->BlendEquation(GL_FUNC_ADD)); | |
| 825 } | 817 } |
| 826 } | 818 } |
| 827 | 819 |
| 828 bool GLRenderer::ShouldApplyBackgroundFilters(DrawingFrame* frame, | 820 bool GLRenderer::ShouldApplyBackgroundFilters(DrawingFrame* frame, |
| 829 const RenderPassDrawQuad* quad) { | 821 const RenderPassDrawQuad* quad) { |
| 830 if (quad->background_filters.IsEmpty()) | 822 if (quad->background_filters.IsEmpty()) |
| 831 return false; | 823 return false; |
| 832 | 824 |
| 833 // TODO(danakj): We only allow background filters on an opaque render surface | 825 // TODO(danakj): We only allow background filters on an opaque render surface |
| 834 // because other surfaces may contain translucent pixels, and the contents | 826 // because other surfaces may contain translucent pixels, and the contents |
| (...skipping 20 matching lines...) Expand all Loading... |
| 855 int top, right, bottom, left; | 847 int top, right, bottom, left; |
| 856 quad->background_filters.GetOutsets(&top, &right, &bottom, &left); | 848 quad->background_filters.GetOutsets(&top, &right, &bottom, &left); |
| 857 backdrop_rect.Inset(-left, -top, -right, -bottom); | 849 backdrop_rect.Inset(-left, -top, -right, -bottom); |
| 858 } | 850 } |
| 859 | 851 |
| 860 if (!backdrop_rect.IsEmpty() && use_aa) { | 852 if (!backdrop_rect.IsEmpty() && use_aa) { |
| 861 const int kOutsetForAntialiasing = 1; | 853 const int kOutsetForAntialiasing = 1; |
| 862 backdrop_rect.Inset(-kOutsetForAntialiasing, -kOutsetForAntialiasing); | 854 backdrop_rect.Inset(-kOutsetForAntialiasing, -kOutsetForAntialiasing); |
| 863 } | 855 } |
| 864 | 856 |
| 865 backdrop_rect.Intersect( | 857 backdrop_rect.Intersect(MoveFromDrawToWindowSpace( |
| 866 MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect)); | 858 frame, frame->current_render_pass->output_rect)); |
| 867 return backdrop_rect; | 859 return backdrop_rect; |
| 868 } | 860 } |
| 869 | 861 |
| 870 scoped_ptr<ScopedResource> GLRenderer::GetBackdropTexture( | 862 scoped_ptr<ScopedResource> GLRenderer::GetBackdropTexture( |
| 871 const gfx::Rect& bounding_rect) { | 863 const gfx::Rect& bounding_rect) { |
| 872 scoped_ptr<ScopedResource> device_background_texture = | 864 scoped_ptr<ScopedResource> device_background_texture = |
| 873 ScopedResource::Create(resource_provider_); | 865 ScopedResource::Create(resource_provider_); |
| 874 // CopyTexImage2D fails when called on a texture having immutable storage. | 866 // CopyTexImage2D fails when called on a texture having immutable storage. |
| 875 device_background_texture->Allocate( | 867 device_background_texture->Allocate( |
| 876 bounding_rect.size(), ResourceProvider::TextureHintDefault, RGBA_8888); | 868 bounding_rect.size(), ResourceProvider::TextureHintDefault, RGBA_8888); |
| (...skipping 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2031 on_demand_tile_raster_resource_id_ = resource_provider_->CreateGLTexture( | 2023 on_demand_tile_raster_resource_id_ = resource_provider_->CreateGLTexture( |
| 2032 quad->texture_size, | 2024 quad->texture_size, |
| 2033 GL_TEXTURE_2D, | 2025 GL_TEXTURE_2D, |
| 2034 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM, | 2026 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM, |
| 2035 GL_CLAMP_TO_EDGE, | 2027 GL_CLAMP_TO_EDGE, |
| 2036 ResourceProvider::TextureHintImmutable, | 2028 ResourceProvider::TextureHintImmutable, |
| 2037 quad->texture_format); | 2029 quad->texture_format); |
| 2038 } | 2030 } |
| 2039 | 2031 |
| 2040 SkCanvas canvas(on_demand_tile_raster_bitmap_); | 2032 SkCanvas canvas(on_demand_tile_raster_bitmap_); |
| 2041 quad->picture_pile->RasterToBitmap( | 2033 quad->picture_pile->PlaybackToCanvas( |
| 2042 &canvas, quad->content_rect, quad->contents_scale, NULL); | 2034 &canvas, quad->content_rect, quad->contents_scale, NULL); |
| 2043 | 2035 |
| 2044 uint8_t* bitmap_pixels = NULL; | 2036 uint8_t* bitmap_pixels = NULL; |
| 2045 SkBitmap on_demand_tile_raster_bitmap_dest; | 2037 SkBitmap on_demand_tile_raster_bitmap_dest; |
| 2046 SkColorType colorType = ResourceFormatToSkColorType(quad->texture_format); | 2038 SkColorType colorType = ResourceFormatToSkColorType(quad->texture_format); |
| 2047 if (on_demand_tile_raster_bitmap_.colorType() != colorType) { | 2039 if (on_demand_tile_raster_bitmap_.colorType() != colorType) { |
| 2048 on_demand_tile_raster_bitmap_.copyTo(&on_demand_tile_raster_bitmap_dest, | 2040 on_demand_tile_raster_bitmap_.copyTo(&on_demand_tile_raster_bitmap_dest, |
| 2049 colorType); | 2041 colorType); |
| 2050 // TODO(kaanb): The GL pipeline assumes a 4-byte alignment for the | 2042 // TODO(kaanb): The GL pipeline assumes a 4-byte alignment for the |
| 2051 // bitmap data. This check will be removed once crbug.com/293728 is fixed. | 2043 // bitmap data. This check will be removed once crbug.com/293728 is fixed. |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2280 swap_buffer_rect_.Union(gfx::ToEnclosingRect(frame->root_damage_rect)); | 2272 swap_buffer_rect_.Union(gfx::ToEnclosingRect(frame->root_damage_rect)); |
| 2281 | 2273 |
| 2282 GLC(gl_, gl_->Disable(GL_BLEND)); | 2274 GLC(gl_, gl_->Disable(GL_BLEND)); |
| 2283 blend_shadow_ = false; | 2275 blend_shadow_ = false; |
| 2284 | 2276 |
| 2285 ScheduleOverlays(frame); | 2277 ScheduleOverlays(frame); |
| 2286 } | 2278 } |
| 2287 | 2279 |
| 2288 void GLRenderer::FinishDrawingQuadList() { FlushTextureQuadCache(); } | 2280 void GLRenderer::FinishDrawingQuadList() { FlushTextureQuadCache(); } |
| 2289 | 2281 |
| 2290 bool GLRenderer::FlippedFramebuffer() const { return true; } | 2282 bool GLRenderer::FlippedFramebuffer(const DrawingFrame* frame) const { |
| 2283 if (frame->current_render_pass != frame->root_render_pass) |
| 2284 return true; |
| 2285 return FlippedRootFramebuffer(); |
| 2286 } |
| 2287 |
| 2288 bool GLRenderer::FlippedRootFramebuffer() const { |
| 2289 // GL is normally flipped, so a flipped output results in an unflipping. |
| 2290 return !output_surface_->capabilities().flipped_output_surface; |
| 2291 } |
| 2291 | 2292 |
| 2292 void GLRenderer::EnsureScissorTestEnabled() { | 2293 void GLRenderer::EnsureScissorTestEnabled() { |
| 2293 if (is_scissor_enabled_) | 2294 if (is_scissor_enabled_) |
| 2294 return; | 2295 return; |
| 2295 | 2296 |
| 2296 FlushTextureQuadCache(); | 2297 FlushTextureQuadCache(); |
| 2297 GLC(gl_, gl_->Enable(GL_SCISSOR_TEST)); | 2298 GLC(gl_, gl_->Enable(GL_SCISSOR_TEST)); |
| 2298 is_scissor_enabled_ = true; | 2299 is_scissor_enabled_ = true; |
| 2299 } | 2300 } |
| 2300 | 2301 |
| 2301 void GLRenderer::EnsureScissorTestDisabled() { | 2302 void GLRenderer::EnsureScissorTestDisabled() { |
| 2302 if (!is_scissor_enabled_) | 2303 if (!is_scissor_enabled_) |
| 2303 return; | 2304 return; |
| 2304 | 2305 |
| 2305 FlushTextureQuadCache(); | 2306 FlushTextureQuadCache(); |
| 2306 GLC(gl_, gl_->Disable(GL_SCISSOR_TEST)); | 2307 GLC(gl_, gl_->Disable(GL_SCISSOR_TEST)); |
| 2307 is_scissor_enabled_ = false; | 2308 is_scissor_enabled_ = false; |
| 2308 } | 2309 } |
| 2309 | 2310 |
| 2310 void GLRenderer::CopyCurrentRenderPassToBitmap( | 2311 void GLRenderer::CopyCurrentRenderPassToBitmap( |
| 2311 DrawingFrame* frame, | 2312 DrawingFrame* frame, |
| 2312 scoped_ptr<CopyOutputRequest> request) { | 2313 scoped_ptr<CopyOutputRequest> request) { |
| 2313 TRACE_EVENT0("cc", "GLRenderer::CopyCurrentRenderPassToBitmap"); | 2314 TRACE_EVENT0("cc", "GLRenderer::CopyCurrentRenderPassToBitmap"); |
| 2314 gfx::Rect copy_rect = frame->current_render_pass->output_rect; | 2315 gfx::Rect copy_rect = frame->current_render_pass->output_rect; |
| 2315 if (request->has_area()) | 2316 if (request->has_area()) |
| 2316 copy_rect.Intersect(request->area()); | 2317 copy_rect.Intersect(request->area()); |
| 2317 GetFramebufferPixelsAsync(copy_rect, request.Pass()); | 2318 GetFramebufferPixelsAsync(frame, copy_rect, request.Pass()); |
| 2318 } | 2319 } |
| 2319 | 2320 |
| 2320 void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) { | 2321 void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) { |
| 2321 transform.matrix().asColMajorf(gl_matrix); | 2322 transform.matrix().asColMajorf(gl_matrix); |
| 2322 } | 2323 } |
| 2323 | 2324 |
| 2324 void GLRenderer::SetShaderQuadF(const gfx::QuadF& quad, int quad_location) { | 2325 void GLRenderer::SetShaderQuadF(const gfx::QuadF& quad, int quad_location) { |
| 2325 if (quad_location == -1) | 2326 if (quad_location == -1) |
| 2326 return; | 2327 return; |
| 2327 | 2328 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2440 compositor_frame.gl_frame_data->size = surface_size; | 2441 compositor_frame.gl_frame_data->size = surface_size; |
| 2441 if (capabilities_.using_partial_swap) { | 2442 if (capabilities_.using_partial_swap) { |
| 2442 // If supported, we can save significant bandwidth by only swapping the | 2443 // If supported, we can save significant bandwidth by only swapping the |
| 2443 // damaged/scissored region (clamped to the viewport). | 2444 // damaged/scissored region (clamped to the viewport). |
| 2444 swap_buffer_rect_.Intersect(gfx::Rect(surface_size)); | 2445 swap_buffer_rect_.Intersect(gfx::Rect(surface_size)); |
| 2445 int flipped_y_pos_of_rect_bottom = surface_size.height() - | 2446 int flipped_y_pos_of_rect_bottom = surface_size.height() - |
| 2446 swap_buffer_rect_.y() - | 2447 swap_buffer_rect_.y() - |
| 2447 swap_buffer_rect_.height(); | 2448 swap_buffer_rect_.height(); |
| 2448 compositor_frame.gl_frame_data->sub_buffer_rect = | 2449 compositor_frame.gl_frame_data->sub_buffer_rect = |
| 2449 gfx::Rect(swap_buffer_rect_.x(), | 2450 gfx::Rect(swap_buffer_rect_.x(), |
| 2450 flipped_y_pos_of_rect_bottom, | 2451 FlippedRootFramebuffer() ? flipped_y_pos_of_rect_bottom |
| 2452 : swap_buffer_rect_.y(), |
| 2451 swap_buffer_rect_.width(), | 2453 swap_buffer_rect_.width(), |
| 2452 swap_buffer_rect_.height()); | 2454 swap_buffer_rect_.height()); |
| 2453 } else { | 2455 } else { |
| 2454 compositor_frame.gl_frame_data->sub_buffer_rect = | 2456 compositor_frame.gl_frame_data->sub_buffer_rect = |
| 2455 gfx::Rect(output_surface_->SurfaceSize()); | 2457 gfx::Rect(output_surface_->SurfaceSize()); |
| 2456 } | 2458 } |
| 2457 output_surface_->SwapBuffers(&compositor_frame); | 2459 output_surface_->SwapBuffers(&compositor_frame); |
| 2458 | 2460 |
| 2459 // Release previously used overlay resources and hold onto the pending ones | 2461 // Release previously used overlay resources and hold onto the pending ones |
| 2460 // until the next swap buffers. | 2462 // until the next swap buffers. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2489 | 2491 |
| 2490 void GLRenderer::EnsureBackbuffer() { | 2492 void GLRenderer::EnsureBackbuffer() { |
| 2491 if (!is_backbuffer_discarded_) | 2493 if (!is_backbuffer_discarded_) |
| 2492 return; | 2494 return; |
| 2493 | 2495 |
| 2494 output_surface_->EnsureBackbuffer(); | 2496 output_surface_->EnsureBackbuffer(); |
| 2495 is_backbuffer_discarded_ = false; | 2497 is_backbuffer_discarded_ = false; |
| 2496 } | 2498 } |
| 2497 | 2499 |
| 2498 void GLRenderer::GetFramebufferPixelsAsync( | 2500 void GLRenderer::GetFramebufferPixelsAsync( |
| 2501 const DrawingFrame* frame, |
| 2499 const gfx::Rect& rect, | 2502 const gfx::Rect& rect, |
| 2500 scoped_ptr<CopyOutputRequest> request) { | 2503 scoped_ptr<CopyOutputRequest> request) { |
| 2501 DCHECK(!request->IsEmpty()); | 2504 DCHECK(!request->IsEmpty()); |
| 2502 if (request->IsEmpty()) | 2505 if (request->IsEmpty()) |
| 2503 return; | 2506 return; |
| 2504 if (rect.IsEmpty()) | 2507 if (rect.IsEmpty()) |
| 2505 return; | 2508 return; |
| 2506 | 2509 |
| 2507 gfx::Rect window_rect = MoveFromDrawToWindowSpace(rect); | 2510 gfx::Rect window_rect = MoveFromDrawToWindowSpace(frame, rect); |
| 2508 DCHECK_GE(window_rect.x(), 0); | 2511 DCHECK_GE(window_rect.x(), 0); |
| 2509 DCHECK_GE(window_rect.y(), 0); | 2512 DCHECK_GE(window_rect.y(), 0); |
| 2510 DCHECK_LE(window_rect.right(), current_surface_size_.width()); | 2513 DCHECK_LE(window_rect.right(), current_surface_size_.width()); |
| 2511 DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); | 2514 DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); |
| 2512 | 2515 |
| 2513 if (!request->force_bitmap_result()) { | 2516 if (!request->force_bitmap_result()) { |
| 2514 bool own_mailbox = !request->has_texture_mailbox(); | 2517 bool own_mailbox = !request->has_texture_mailbox(); |
| 2515 | 2518 |
| 2516 GLuint texture_id = 0; | 2519 GLuint texture_id = 0; |
| 2517 gpu::Mailbox mailbox; | 2520 gpu::Mailbox mailbox; |
| (...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3357 context_support_->ScheduleOverlayPlane( | 3360 context_support_->ScheduleOverlayPlane( |
| 3358 overlay.plane_z_order, | 3361 overlay.plane_z_order, |
| 3359 overlay.transform, | 3362 overlay.transform, |
| 3360 pending_overlay_resources_.back()->texture_id(), | 3363 pending_overlay_resources_.back()->texture_id(), |
| 3361 overlay.display_rect, | 3364 overlay.display_rect, |
| 3362 overlay.uv_rect); | 3365 overlay.uv_rect); |
| 3363 } | 3366 } |
| 3364 } | 3367 } |
| 3365 | 3368 |
| 3366 } // namespace cc | 3369 } // namespace cc |
| OLD | NEW |