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 |