Commit fad658b4 authored by ed's avatar ed Committed by Commit bot

Accelerate the 'lighten' blendmode.

If GL_EXT_blend_minmax is available then make use of that
to accelerate blending for the 'lighten' blendmode.

BUG=243223

Review URL: https://codereview.chromium.org/614953002

Cr-Commit-Position: refs/heads/master@{#299080}
parent 1e0b95af
...@@ -338,6 +338,7 @@ GLRenderer::GLRenderer(RendererClient* client, ...@@ -338,6 +338,7 @@ GLRenderer::GLRenderer(RendererClient* client,
capabilities_.allow_rasterize_on_demand = true; capabilities_.allow_rasterize_on_demand = true;
use_sync_query_ = context_caps.gpu.sync_query; use_sync_query_ = context_caps.gpu.sync_query;
use_blend_minmax_ = context_caps.gpu.blend_minmax;
InitializeSharedObjects(); InitializeSharedObjects();
} }
...@@ -698,21 +699,32 @@ static skia::RefPtr<SkImage> ApplyImageFilter( ...@@ -698,21 +699,32 @@ static skia::RefPtr<SkImage> ApplyImageFilter(
return image; return image;
} }
bool GLRenderer::ShouldApplyBlendModeUsingBlendFunc(const DrawQuad* quad) { bool GLRenderer::CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) {
SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode; return (use_blend_minmax_ && blend_mode == SkXfermode::kLighten_Mode) ||
return blend_mode == SkXfermode::kScreen_Mode || blend_mode == SkXfermode::kScreen_Mode ||
blend_mode == SkXfermode::kSrcOver_Mode; blend_mode == SkXfermode::kSrcOver_Mode;
} }
void GLRenderer::ApplyBlendModeUsingBlendFunc(const DrawQuad* quad) { void GLRenderer::ApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) {
DCHECK(ShouldApplyBlendModeUsingBlendFunc(quad)); DCHECK(CanApplyBlendModeUsingBlendFunc(blend_mode));
if (quad->shared_quad_state->blend_mode == SkXfermode::kScreen_Mode) {
// Any modes set here must be reset in RestoreBlendFuncToDefault
if (blend_mode == SkXfermode::kScreen_Mode) {
GLC(gl_, gl_->BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE)); GLC(gl_, gl_->BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE));
} else if (blend_mode == SkXfermode::kLighten_Mode) {
GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE));
GLC(gl_, gl_->BlendEquation(GL_MAX_EXT));
} }
} }
void GLRenderer::RestoreBlendFuncToDefault() { void GLRenderer::RestoreBlendFuncToDefault(SkXfermode::Mode blend_mode) {
if (blend_mode == SkXfermode::kSrcOver_Mode)
return;
GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
if (blend_mode == SkXfermode::kLighten_Mode)
GLC(gl_, gl_->BlendEquation(GL_FUNC_ADD));
} }
static skia::RefPtr<SkImage> ApplyBlendModeWithBackdrop( static skia::RefPtr<SkImage> ApplyBlendModeWithBackdrop(
...@@ -1012,8 +1024,10 @@ GLRenderer::ApplyInverseTransformForBackgroundFilters( ...@@ -1012,8 +1024,10 @@ GLRenderer::ApplyInverseTransformForBackgroundFilters(
void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
const RenderPassDrawQuad* quad) { const RenderPassDrawQuad* quad) {
SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode;
SetBlendEnabled(quad->ShouldDrawWithBlending() || SetBlendEnabled(quad->ShouldDrawWithBlending() ||
ShouldApplyBlendModeUsingBlendFunc(quad)); (!IsDefaultBlendMode(blend_mode) &&
CanApplyBlendModeUsingBlendFunc(blend_mode)));
ScopedResource* contents_texture = ScopedResource* contents_texture =
render_pass_textures_.get(quad->render_pass_id); render_pass_textures_.get(quad->render_pass_id);
...@@ -1032,7 +1046,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, ...@@ -1032,7 +1046,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) if (!contents_device_transform.GetInverse(&contents_device_transform_inverse))
return; return;
bool need_background_texture = !ShouldApplyBlendModeUsingBlendFunc(quad) || bool need_background_texture = !CanApplyBlendModeUsingBlendFunc(blend_mode) ||
ShouldApplyBackgroundFilters(frame, quad); ShouldApplyBackgroundFilters(frame, quad);
scoped_ptr<ScopedResource> background_texture; scoped_ptr<ScopedResource> background_texture;
...@@ -1108,34 +1122,36 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, ...@@ -1108,34 +1122,36 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
} }
} }
// If blending is applied using shaders, the background texture with if (background_texture) {
// filters will be used as backdrop for blending operation, so we don't if (CanApplyBlendModeUsingBlendFunc(blend_mode)) {
// need to copy it to the frame buffer. // Draw the background texture if it has some filters applied.
if (background_texture && !ShouldApplyBlendModeUsingBlendFunc(quad)) { DCHECK(ShouldApplyBackgroundFilters(frame, quad));
filter_bitmap = DCHECK(background_texture->size() == quad->rect.size());
ApplyBlendModeWithBackdrop(ScopedUseGrContext::Create(this, frame), ResourceProvider::ScopedReadLockGL lock(resource_provider_,
resource_provider_, background_texture->id());
filter_bitmap,
contents_texture, // The background_texture is oriented the same as the frame buffer. The
background_texture.get(), // transform we are copying with has a vertical flip, so flip the contents
quad->shared_quad_state->blend_mode); // in the shader to maintain orientation
} else if (background_texture) { bool flip_vertically = true;
// Draw the background texture if it has some filters applied.
DCHECK(ShouldApplyBackgroundFilters(frame, quad)); CopyTextureToFramebuffer(frame,
DCHECK(background_texture->size() == quad->rect.size()); lock.texture_id(),
ResourceProvider::ScopedReadLockGL lock(resource_provider_, quad->rect,
background_texture->id()); quad->quadTransform(),
flip_vertically);
// The background_texture is oriented the same as the frame buffer. The } else {
// transform we are copying with has a vertical flip, so flip the contents // If blending is applied using shaders, the background texture with
// in the shader to maintain orientation // filters will be used as backdrop for blending operation, so we don't
bool flip_vertically = true; // need to copy it to the frame buffer.
filter_bitmap =
CopyTextureToFramebuffer(frame, ApplyBlendModeWithBackdrop(ScopedUseGrContext::Create(this, frame),
lock.texture_id(), resource_provider_,
quad->rect, filter_bitmap,
quad->quadTransform(), contents_texture,
flip_vertically); background_texture.get(),
quad->shared_quad_state->blend_mode);
}
} }
bool clipped = false; bool clipped = false;
...@@ -1178,8 +1194,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, ...@@ -1178,8 +1194,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
contents_resource_lock->target()); contents_resource_lock->target());
} }
if (ShouldApplyBlendModeUsingBlendFunc(quad)) if (CanApplyBlendModeUsingBlendFunc(blend_mode))
ApplyBlendModeUsingBlendFunc(quad); ApplyBlendModeUsingBlendFunc(blend_mode);
TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired( TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
gl_, gl_,
...@@ -1428,8 +1444,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, ...@@ -1428,8 +1444,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
if (filter_bitmap) if (filter_bitmap)
GLC(gl_, gl_->Flush()); GLC(gl_, gl_->Flush());
if (ShouldApplyBlendModeUsingBlendFunc(quad)) if (CanApplyBlendModeUsingBlendFunc(blend_mode))
RestoreBlendFuncToDefault(); RestoreBlendFuncToDefault(blend_mode);
} }
struct SolidColorProgramUniforms { struct SolidColorProgramUniforms {
......
...@@ -143,9 +143,12 @@ class CC_EXPORT GLRenderer : public DirectRenderer { ...@@ -143,9 +143,12 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
const CheckerboardDrawQuad* quad); const CheckerboardDrawQuad* quad);
void DrawDebugBorderQuad(const DrawingFrame* frame, void DrawDebugBorderQuad(const DrawingFrame* frame,
const DebugBorderDrawQuad* quad); const DebugBorderDrawQuad* quad);
static bool ShouldApplyBlendModeUsingBlendFunc(const DrawQuad* quad); static bool IsDefaultBlendMode(SkXfermode::Mode blend_mode) {
void ApplyBlendModeUsingBlendFunc(const DrawQuad* quad); return blend_mode == SkXfermode::kSrcOver_Mode;
void RestoreBlendFuncToDefault(); }
bool CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode);
void ApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode);
void RestoreBlendFuncToDefault(SkXfermode::Mode blend_mode);
gfx::Rect GetBackdropBoundingBoxForRenderPassQuad( gfx::Rect GetBackdropBoundingBoxForRenderPassQuad(
DrawingFrame* frame, DrawingFrame* frame,
...@@ -436,6 +439,7 @@ class CC_EXPORT GLRenderer : public DirectRenderer { ...@@ -436,6 +439,7 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
ScopedPtrDeque<SyncQuery> available_sync_queries_; ScopedPtrDeque<SyncQuery> available_sync_queries_;
scoped_ptr<SyncQuery> current_sync_query_; scoped_ptr<SyncQuery> current_sync_query_;
bool use_sync_query_; bool use_sync_query_;
bool use_blend_minmax_;
SkBitmap on_demand_tile_raster_bitmap_; SkBitmap on_demand_tile_raster_bitmap_;
ResourceProvider::ResourceId on_demand_tile_raster_resource_id_; ResourceProvider::ResourceId on_demand_tile_raster_resource_id_;
......
...@@ -196,6 +196,7 @@ IPC_STRUCT_TRAITS_BEGIN(gpu::Capabilities) ...@@ -196,6 +196,7 @@ IPC_STRUCT_TRAITS_BEGIN(gpu::Capabilities)
IPC_STRUCT_TRAITS_MEMBER(discard_framebuffer) IPC_STRUCT_TRAITS_MEMBER(discard_framebuffer)
IPC_STRUCT_TRAITS_MEMBER(sync_query) IPC_STRUCT_TRAITS_MEMBER(sync_query)
IPC_STRUCT_TRAITS_MEMBER(image) IPC_STRUCT_TRAITS_MEMBER(image)
IPC_STRUCT_TRAITS_MEMBER(blend_minmax)
IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::GPUVideoMemoryUsageStats::ProcessStats) IPC_STRUCT_TRAITS_BEGIN(content::GPUVideoMemoryUsageStats::ProcessStats)
......
...@@ -19,7 +19,8 @@ Capabilities::Capabilities() ...@@ -19,7 +19,8 @@ Capabilities::Capabilities()
discard_framebuffer(false), discard_framebuffer(false),
sync_query(false), sync_query(false),
image(false), image(false),
future_sync_points(false) { future_sync_points(false),
blend_minmax(false) {
} }
} // namespace gpu } // namespace gpu
...@@ -23,6 +23,7 @@ struct GPU_EXPORT Capabilities { ...@@ -23,6 +23,7 @@ struct GPU_EXPORT Capabilities {
bool sync_query; bool sync_query;
bool image; bool image;
bool future_sync_points; bool future_sync_points;
bool blend_minmax;
Capabilities(); Capabilities();
}; };
......
...@@ -142,7 +142,8 @@ FeatureInfo::FeatureFlags::FeatureFlags() ...@@ -142,7 +142,8 @@ FeatureInfo::FeatureFlags::FeatureFlags()
is_swiftshader(false), is_swiftshader(false),
angle_texture_usage(false), angle_texture_usage(false),
ext_texture_storage(false), ext_texture_storage(false),
chromium_path_rendering(false) { chromium_path_rendering(false),
ext_blend_minmax(false) {
} }
FeatureInfo::Workarounds::Workarounds() : FeatureInfo::Workarounds::Workarounds() :
...@@ -789,6 +790,7 @@ void FeatureInfo::InitializeFeatures() { ...@@ -789,6 +790,7 @@ void FeatureInfo::InitializeFeatures() {
if (is_es3 || extensions.Contains("GL_EXT_blend_minmax") || if (is_es3 || extensions.Contains("GL_EXT_blend_minmax") ||
gfx::HasDesktopGLFeatures()) { gfx::HasDesktopGLFeatures()) {
feature_flags_.ext_blend_minmax = true;
AddExtensionString("GL_EXT_blend_minmax"); AddExtensionString("GL_EXT_blend_minmax");
validators_.equation.AddValue(GL_MIN_EXT); validators_.equation.AddValue(GL_MIN_EXT);
validators_.equation.AddValue(GL_MAX_EXT); validators_.equation.AddValue(GL_MAX_EXT);
......
...@@ -70,6 +70,7 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { ...@@ -70,6 +70,7 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
bool angle_texture_usage; bool angle_texture_usage;
bool ext_texture_storage; bool ext_texture_storage;
bool chromium_path_rendering; bool chromium_path_rendering;
bool ext_blend_minmax;
}; };
struct Workarounds { struct Workarounds {
......
...@@ -2746,6 +2746,7 @@ Capabilities GLES2DecoderImpl::GetCapabilities() { ...@@ -2746,6 +2746,7 @@ Capabilities GLES2DecoderImpl::GetCapabilities() {
caps.post_sub_buffer = supports_post_sub_buffer_; caps.post_sub_buffer = supports_post_sub_buffer_;
caps.image = true; caps.image = true;
caps.blend_minmax = feature_info_->feature_flags().ext_blend_minmax;
return caps; return caps;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment