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 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 capabilities_.allow_partial_texture_updates = true; | 331 capabilities_.allow_partial_texture_updates = true; |
332 | 332 |
333 capabilities_.using_image = context_caps.gpu.image; | 333 capabilities_.using_image = context_caps.gpu.image; |
334 | 334 |
335 capabilities_.using_discard_framebuffer = | 335 capabilities_.using_discard_framebuffer = |
336 context_caps.gpu.discard_framebuffer; | 336 context_caps.gpu.discard_framebuffer; |
337 | 337 |
338 capabilities_.allow_rasterize_on_demand = true; | 338 capabilities_.allow_rasterize_on_demand = true; |
339 | 339 |
340 use_sync_query_ = context_caps.gpu.sync_query; | 340 use_sync_query_ = context_caps.gpu.sync_query; |
| 341 use_blend_minmax = context_caps.gpu.blend_minmax; |
341 | 342 |
342 InitializeSharedObjects(); | 343 InitializeSharedObjects(); |
343 } | 344 } |
344 | 345 |
345 GLRenderer::~GLRenderer() { | 346 GLRenderer::~GLRenderer() { |
346 while (!pending_async_read_pixels_.empty()) { | 347 while (!pending_async_read_pixels_.empty()) { |
347 PendingAsyncReadPixels* pending_read = pending_async_read_pixels_.back(); | 348 PendingAsyncReadPixels* pending_read = pending_async_read_pixels_.back(); |
348 pending_read->finished_read_pixels_callback.Cancel(); | 349 pending_read->finished_read_pixels_callback.Cancel(); |
349 pending_async_read_pixels_.pop_back(); | 350 pending_async_read_pixels_.pop_back(); |
350 } | 351 } |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 } | 692 } |
692 | 693 |
693 // Flush the GrContext to ensure all buffered GL calls are drawn to the | 694 // Flush the GrContext to ensure all buffered GL calls are drawn to the |
694 // backing store before we access and return it, and have cc begin using the | 695 // backing store before we access and return it, and have cc begin using the |
695 // GL context again. | 696 // GL context again. |
696 canvas->flush(); | 697 canvas->flush(); |
697 | 698 |
698 return image; | 699 return image; |
699 } | 700 } |
700 | 701 |
701 bool GLRenderer::ShouldApplyBlendModeUsingBlendFunc(const DrawQuad* quad) { | 702 bool GLRenderer::CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { |
702 SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode; | 703 return (use_blend_minmax && blend_mode == SkXfermode::kLighten_Mode) || |
703 return blend_mode == SkXfermode::kScreen_Mode || | 704 blend_mode == SkXfermode::kScreen_Mode || |
704 blend_mode == SkXfermode::kSrcOver_Mode; | 705 blend_mode == SkXfermode::kSrcOver_Mode; |
705 } | 706 } |
706 | 707 |
707 void GLRenderer::ApplyBlendModeUsingBlendFunc(const DrawQuad* quad) { | 708 void GLRenderer::ApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { |
708 DCHECK(ShouldApplyBlendModeUsingBlendFunc(quad)); | 709 DCHECK(CanApplyBlendModeUsingBlendFunc(blend_mode)); |
709 if (quad->shared_quad_state->blend_mode == SkXfermode::kScreen_Mode) { | 710 |
| 711 // Any modes set here must be reset in RestoreBlendFuncToDefault |
| 712 if (blend_mode == SkXfermode::kScreen_Mode) { |
710 GLC(gl_, gl_->BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE)); | 713 GLC(gl_, gl_->BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE)); |
| 714 } else if (blend_mode == SkXfermode::kLighten_Mode) { |
| 715 GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE)); |
| 716 GLC(gl_, gl_->BlendEquation(GL_MAX_EXT)); |
711 } | 717 } |
712 } | 718 } |
713 | 719 |
714 void GLRenderer::RestoreBlendFuncToDefault() { | 720 void GLRenderer::RestoreBlendFuncToDefault(SkXfermode::Mode blend_mode) { |
| 721 if (blend_mode == SkXfermode::kSrcOver_Mode) |
| 722 return; |
| 723 |
715 GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); | 724 GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); |
| 725 |
| 726 if (blend_mode == SkXfermode::kLighten_Mode) |
| 727 GLC(gl_, gl_->BlendEquation(GL_FUNC_ADD)); |
716 } | 728 } |
717 | 729 |
718 static skia::RefPtr<SkImage> ApplyBlendModeWithBackdrop( | 730 static skia::RefPtr<SkImage> ApplyBlendModeWithBackdrop( |
719 scoped_ptr<GLRenderer::ScopedUseGrContext> use_gr_context, | 731 scoped_ptr<GLRenderer::ScopedUseGrContext> use_gr_context, |
720 ResourceProvider* resource_provider, | 732 ResourceProvider* resource_provider, |
721 skia::RefPtr<SkImage> source_bitmap_with_filters, | 733 skia::RefPtr<SkImage> source_bitmap_with_filters, |
722 ScopedResource* source_texture_resource, | 734 ScopedResource* source_texture_resource, |
723 ScopedResource* background_texture_resource, | 735 ScopedResource* background_texture_resource, |
724 SkXfermode::Mode blend_mode) { | 736 SkXfermode::Mode blend_mode) { |
725 if (!use_gr_context) | 737 if (!use_gr_context) |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1005 | 1017 |
1006 UseRenderPass(frame, target_render_pass); | 1018 UseRenderPass(frame, target_render_pass); |
1007 | 1019 |
1008 if (!using_background_texture) | 1020 if (!using_background_texture) |
1009 return nullptr; | 1021 return nullptr; |
1010 return background_texture.Pass(); | 1022 return background_texture.Pass(); |
1011 } | 1023 } |
1012 | 1024 |
1013 void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, | 1025 void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
1014 const RenderPassDrawQuad* quad) { | 1026 const RenderPassDrawQuad* quad) { |
| 1027 SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode; |
1015 SetBlendEnabled(quad->ShouldDrawWithBlending() || | 1028 SetBlendEnabled(quad->ShouldDrawWithBlending() || |
1016 ShouldApplyBlendModeUsingBlendFunc(quad)); | 1029 (!IsDefaultBlendMode(blend_mode) && |
| 1030 CanApplyBlendModeUsingBlendFunc(blend_mode))); |
1017 | 1031 |
1018 ScopedResource* contents_texture = | 1032 ScopedResource* contents_texture = |
1019 render_pass_textures_.get(quad->render_pass_id); | 1033 render_pass_textures_.get(quad->render_pass_id); |
1020 if (!contents_texture || !contents_texture->id()) | 1034 if (!contents_texture || !contents_texture->id()) |
1021 return; | 1035 return; |
1022 | 1036 |
1023 gfx::Transform quad_rect_matrix; | 1037 gfx::Transform quad_rect_matrix; |
1024 QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect); | 1038 QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect); |
1025 gfx::Transform contents_device_transform = | 1039 gfx::Transform contents_device_transform = |
1026 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; | 1040 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; |
1027 contents_device_transform.FlattenTo2d(); | 1041 contents_device_transform.FlattenTo2d(); |
1028 | 1042 |
1029 // Can only draw surface if device matrix is invertible. | 1043 // Can only draw surface if device matrix is invertible. |
1030 gfx::Transform contents_device_transform_inverse( | 1044 gfx::Transform contents_device_transform_inverse( |
1031 gfx::Transform::kSkipInitialization); | 1045 gfx::Transform::kSkipInitialization); |
1032 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) | 1046 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) |
1033 return; | 1047 return; |
1034 | 1048 |
1035 bool need_background_texture = !ShouldApplyBlendModeUsingBlendFunc(quad) || | 1049 bool need_background_texture = !CanApplyBlendModeUsingBlendFunc(blend_mode) || |
1036 ShouldApplyBackgroundFilters(frame, quad); | 1050 ShouldApplyBackgroundFilters(frame, quad); |
1037 | 1051 |
1038 scoped_ptr<ScopedResource> background_texture; | 1052 scoped_ptr<ScopedResource> background_texture; |
1039 if (need_background_texture) { | 1053 if (need_background_texture) { |
1040 // The pixels from the filtered background should completely replace the | 1054 // The pixels from the filtered background should completely replace the |
1041 // current pixel values. | 1055 // current pixel values. |
1042 bool disable_blending = blend_enabled(); | 1056 bool disable_blending = blend_enabled(); |
1043 if (disable_blending) | 1057 if (disable_blending) |
1044 SetBlendEnabled(false); | 1058 SetBlendEnabled(false); |
1045 | 1059 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1101 ApplyImageFilter(ScopedUseGrContext::Create(this, frame), | 1115 ApplyImageFilter(ScopedUseGrContext::Create(this, frame), |
1102 resource_provider_, | 1116 resource_provider_, |
1103 quad->rect.origin(), | 1117 quad->rect.origin(), |
1104 quad->filters_scale, | 1118 quad->filters_scale, |
1105 filter.get(), | 1119 filter.get(), |
1106 contents_texture); | 1120 contents_texture); |
1107 } | 1121 } |
1108 } | 1122 } |
1109 } | 1123 } |
1110 | 1124 |
1111 // If blending is applied using shaders, the background texture with | 1125 if (background_texture) { |
1112 // filters will be used as backdrop for blending operation, so we don't | 1126 if (CanApplyBlendModeUsingBlendFunc(blend_mode)) { |
1113 // need to copy it to the frame buffer. | 1127 // Draw the background texture if it has some filters applied. |
1114 if (background_texture && !ShouldApplyBlendModeUsingBlendFunc(quad)) { | 1128 DCHECK(ShouldApplyBackgroundFilters(frame, quad)); |
1115 filter_bitmap = | 1129 DCHECK(background_texture->size() == quad->rect.size()); |
1116 ApplyBlendModeWithBackdrop(ScopedUseGrContext::Create(this, frame), | 1130 ResourceProvider::ScopedReadLockGL lock(resource_provider_, |
1117 resource_provider_, | 1131 background_texture->id()); |
1118 filter_bitmap, | |
1119 contents_texture, | |
1120 background_texture.get(), | |
1121 quad->shared_quad_state->blend_mode); | |
1122 } else if (background_texture) { | |
1123 // Draw the background texture if it has some filters applied. | |
1124 DCHECK(ShouldApplyBackgroundFilters(frame, quad)); | |
1125 DCHECK(background_texture->size() == quad->rect.size()); | |
1126 ResourceProvider::ScopedReadLockGL lock(resource_provider_, | |
1127 background_texture->id()); | |
1128 | 1132 |
1129 // The background_texture is oriented the same as the frame buffer. The | 1133 // The background_texture is oriented the same as the frame buffer. The |
1130 // transform we are copying with has a vertical flip, so flip the contents | 1134 // transform we are copying with has a vertical flip, so flip the contents |
1131 // in the shader to maintain orientation | 1135 // in the shader to maintain orientation |
1132 bool flip_vertically = true; | 1136 bool flip_vertically = true; |
1133 | 1137 |
1134 CopyTextureToFramebuffer(frame, | 1138 CopyTextureToFramebuffer(frame, |
1135 lock.texture_id(), | 1139 lock.texture_id(), |
1136 quad->rect, | 1140 quad->rect, |
1137 quad->quadTransform(), | 1141 quad->quadTransform(), |
1138 flip_vertically); | 1142 flip_vertically); |
| 1143 } else { |
| 1144 // If blending is applied using shaders, the background texture with |
| 1145 // filters will be used as backdrop for blending operation, so we don't |
| 1146 // need to copy it to the frame buffer. |
| 1147 filter_bitmap = |
| 1148 ApplyBlendModeWithBackdrop(ScopedUseGrContext::Create(this, frame), |
| 1149 resource_provider_, |
| 1150 filter_bitmap, |
| 1151 contents_texture, |
| 1152 background_texture.get(), |
| 1153 quad->shared_quad_state->blend_mode); |
| 1154 } |
1139 } | 1155 } |
1140 | 1156 |
1141 bool clipped = false; | 1157 bool clipped = false; |
1142 gfx::QuadF device_quad = MathUtil::MapQuad( | 1158 gfx::QuadF device_quad = MathUtil::MapQuad( |
1143 contents_device_transform, SharedGeometryQuad(), &clipped); | 1159 contents_device_transform, SharedGeometryQuad(), &clipped); |
1144 LayerQuad device_layer_bounds(gfx::QuadF(device_quad.BoundingBox())); | 1160 LayerQuad device_layer_bounds(gfx::QuadF(device_quad.BoundingBox())); |
1145 LayerQuad device_layer_edges(device_quad); | 1161 LayerQuad device_layer_edges(device_quad); |
1146 | 1162 |
1147 // Use anti-aliasing programs only when necessary. | 1163 // Use anti-aliasing programs only when necessary. |
1148 bool use_aa = | 1164 bool use_aa = |
(...skipping 22 matching lines...) Expand all Loading... |
1171 DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_)); | 1187 DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_)); |
1172 gl_->BindTexture(GL_TEXTURE_2D, texture->getTextureHandle()); | 1188 gl_->BindTexture(GL_TEXTURE_2D, texture->getTextureHandle()); |
1173 } else { | 1189 } else { |
1174 contents_resource_lock = | 1190 contents_resource_lock = |
1175 make_scoped_ptr(new ResourceProvider::ScopedSamplerGL( | 1191 make_scoped_ptr(new ResourceProvider::ScopedSamplerGL( |
1176 resource_provider_, contents_texture->id(), GL_LINEAR)); | 1192 resource_provider_, contents_texture->id(), GL_LINEAR)); |
1177 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), | 1193 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), |
1178 contents_resource_lock->target()); | 1194 contents_resource_lock->target()); |
1179 } | 1195 } |
1180 | 1196 |
1181 if (ShouldApplyBlendModeUsingBlendFunc(quad)) | 1197 if (CanApplyBlendModeUsingBlendFunc(blend_mode)) |
1182 ApplyBlendModeUsingBlendFunc(quad); | 1198 ApplyBlendModeUsingBlendFunc(blend_mode); |
1183 | 1199 |
1184 TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired( | 1200 TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired( |
1185 gl_, | 1201 gl_, |
1186 &highp_threshold_cache_, | 1202 &highp_threshold_cache_, |
1187 highp_threshold_min_, | 1203 highp_threshold_min_, |
1188 quad->shared_quad_state->visible_content_rect.bottom_right()); | 1204 quad->shared_quad_state->visible_content_rect.bottom_right()); |
1189 | 1205 |
1190 int shader_quad_location = -1; | 1206 int shader_quad_location = -1; |
1191 int shader_edge_location = -1; | 1207 int shader_edge_location = -1; |
1192 int shader_viewport_location = -1; | 1208 int shader_viewport_location = -1; |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1421 SetShaderOpacity(quad->opacity(), shader_alpha_location); | 1437 SetShaderOpacity(quad->opacity(), shader_alpha_location); |
1422 SetShaderQuadF(surface_quad, shader_quad_location); | 1438 SetShaderQuadF(surface_quad, shader_quad_location); |
1423 DrawQuadGeometry( | 1439 DrawQuadGeometry( |
1424 frame, quad->quadTransform(), quad->rect, shader_matrix_location); | 1440 frame, quad->quadTransform(), quad->rect, shader_matrix_location); |
1425 | 1441 |
1426 // Flush the compositor context before the filter bitmap goes out of | 1442 // Flush the compositor context before the filter bitmap goes out of |
1427 // scope, so the draw gets processed before the filter texture gets deleted. | 1443 // scope, so the draw gets processed before the filter texture gets deleted. |
1428 if (filter_bitmap) | 1444 if (filter_bitmap) |
1429 GLC(gl_, gl_->Flush()); | 1445 GLC(gl_, gl_->Flush()); |
1430 | 1446 |
1431 if (ShouldApplyBlendModeUsingBlendFunc(quad)) | 1447 if (CanApplyBlendModeUsingBlendFunc(blend_mode)) |
1432 RestoreBlendFuncToDefault(); | 1448 RestoreBlendFuncToDefault(blend_mode); |
1433 } | 1449 } |
1434 | 1450 |
1435 struct SolidColorProgramUniforms { | 1451 struct SolidColorProgramUniforms { |
1436 unsigned program; | 1452 unsigned program; |
1437 unsigned matrix_location; | 1453 unsigned matrix_location; |
1438 unsigned viewport_location; | 1454 unsigned viewport_location; |
1439 unsigned quad_location; | 1455 unsigned quad_location; |
1440 unsigned edge_location; | 1456 unsigned edge_location; |
1441 unsigned color_location; | 1457 unsigned color_location; |
1442 }; | 1458 }; |
(...skipping 1824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3267 context_support_->ScheduleOverlayPlane( | 3283 context_support_->ScheduleOverlayPlane( |
3268 overlay.plane_z_order, | 3284 overlay.plane_z_order, |
3269 overlay.transform, | 3285 overlay.transform, |
3270 pending_overlay_resources_.back()->texture_id(), | 3286 pending_overlay_resources_.back()->texture_id(), |
3271 overlay.display_rect, | 3287 overlay.display_rect, |
3272 overlay.uv_rect); | 3288 overlay.uv_rect); |
3273 } | 3289 } |
3274 } | 3290 } |
3275 | 3291 |
3276 } // namespace cc | 3292 } // namespace cc |
OLD | NEW |