Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(426)

Side by Side Diff: cc/output/gl_renderer.cc

Issue 614953002: Accelerate the lighten blendmode if GL_EXT_blend_minmax is enabled. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698