summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorrosca <rosca@adobe.com>2014-11-10 04:35:39 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-10 12:36:02 +0000
commit5381f8a3e23802e88b0e5a3bdc17911f7aab610a (patch)
treeb15e5f257934fbe0aae89ecb9cf4454c2fb11ff4 /cc
parent53dfc3259153100ab0102fff2265671006911675 (diff)
downloadchromium_src-5381f8a3e23802e88b0e5a3bdc17911f7aab610a.zip
chromium_src-5381f8a3e23802e88b0e5a3bdc17911f7aab610a.tar.gz
chromium_src-5381f8a3e23802e88b0e5a3bdc17911f7aab610a.tar.bz2
Use blending shaders for background filters.
Adding the missing blend modes (normal and screen) to shaders allows us to send background filters to shaders all the time. This way we avoid the inverse transform of the background texture, which leads to losing quality and speed. BUG=411079 Review URL: https://codereview.chromium.org/676433002 Cr-Commit-Position: refs/heads/master@{#303451}
Diffstat (limited to 'cc')
-rw-r--r--cc/output/gl_renderer.cc245
-rw-r--r--cc/output/gl_renderer.h12
-rw-r--r--cc/output/gl_renderer_unittest.cc6
-rw-r--r--cc/output/program_binding.h2
-rw-r--r--cc/output/shader.cc18
-rw-r--r--cc/output/shader.h4
-rw-r--r--cc/test/data/background_filter_blur_off_axis.pngbin7304 -> 4463 bytes
-rw-r--r--cc/test/data/background_filter_blur_outsets.pngbin1757 -> 1759 bytes
-rw-r--r--cc/trees/layer_tree_host.cc8
-rw-r--r--cc/trees/layer_tree_host_pixeltest_blending.cc64
-rw-r--r--cc/trees/layer_tree_host_pixeltest_filters.cc4
-rw-r--r--cc/trees/layer_tree_settings.cc1
-rw-r--r--cc/trees/layer_tree_settings.h1
13 files changed, 136 insertions, 229 deletions
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index a472475..214b989 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -99,6 +99,8 @@ BlendMode BlendModeFromSkXfermode(SkXfermode::Mode mode) {
switch (mode) {
case SkXfermode::kSrcOver_Mode:
return BlendModeNormal;
+ case SkXfermode::kScreen_Mode:
+ return BlendModeScreen;
case SkXfermode::kOverlay_Mode:
return BlendModeOverlay;
case SkXfermode::kDarken_Mode:
@@ -129,7 +131,7 @@ BlendMode BlendModeFromSkXfermode(SkXfermode::Mode mode) {
return BlendModeLuminosity;
default:
NOTREACHED();
- return BlendModeNormal;
+ return BlendModeNone;
}
}
@@ -866,99 +868,8 @@ skia::RefPtr<SkImage> GLRenderer::ApplyBackgroundFilters(
return background_with_filters;
}
-scoped_ptr<ScopedResource>
-GLRenderer::ApplyInverseTransformForBackgroundFilters(
- DrawingFrame* frame,
- const RenderPassDrawQuad* quad,
- const gfx::Transform& contents_device_transform,
- skia::RefPtr<SkImage> filtered_device_background,
- const gfx::Rect& backdrop_bounding_rect) {
- // This method draws a background filter, which applies a filter to any pixels
- // behind the quad and seen through its background. The algorithm works as
- // follows:
- // 1. Read the pixels in the bounding box into a buffer.
- // Moved to GLRenderer::GetBackdropBoundingBoxForRenderPassQuad().
- // 2. Read the pixels in the bounding box into a buffer R.
- // Moved to GLRenderer::GetBackdropTexture().
- // 3. Apply the background filter to R, so that it is applied in the pixels'
- // coordinate space. Moved to GLRenderer::ApplyBackgroundFilters().
- // 4. Apply the quad's inverse transform to map the pixels in R into the
- // quad's content space. This implicitly clips R by the content bounds of the
- // quad since the destination texture has bounds matching the quad's content.
- // 5. Draw the background texture for the contents using the same transform as
- // used to draw the contents itself. This is done without blending to replace
- // the current background pixels with the new filtered background.
- // 6. Draw the contents of the quad over drop of the new background with
- // blending, as per usual. The filtered background pixels will show through
- // any non-opaque pixels in this draws.
- //
- // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5.
-
- // TODO(danakj): When this algorithm changes, update
- // LayerTreeHost::PrioritizeTextures() accordingly.
-
- DCHECK(filtered_device_background);
-
- GrTexture* texture = filtered_device_background->getTexture();
-
- scoped_ptr<ScopedResource> background_texture =
- ScopedResource::Create(resource_provider_);
- background_texture->Allocate(
- quad->rect.size(),
- ResourceProvider::TextureHintImmutableFramebuffer,
- RGBA_8888);
-
- const RenderPass* target_render_pass = frame->current_render_pass;
- bool using_background_texture =
- UseScopedTexture(frame, background_texture.get(), quad->rect);
-
- if (using_background_texture) {
- // Copy the readback pixels from device to the background texture for the
- // surface.
-
- gfx::Transform contents_device_transform_inverse(
- gfx::Transform::kSkipInitialization);
- bool did_invert = contents_device_transform.GetInverse(
- &contents_device_transform_inverse);
- DCHECK(did_invert);
- gfx::Transform device_to_framebuffer_transform;
- QuadRectTransform(
- &device_to_framebuffer_transform, gfx::Transform(), quad->rect);
- device_to_framebuffer_transform.PreconcatTransform(
- contents_device_transform_inverse);
-
-#ifndef NDEBUG
- GLC(gl_, gl_->ClearColor(0, 0, 1, 1));
- gl_->Clear(GL_COLOR_BUFFER_BIT);
-#endif
-
- // The background_texture is oriented the same as the frame buffer.
- // The transform we are copying with has a vertical flip, as well as
- // the |device_to_framebuffer_transform|, which cancel each other out. So do
- // not flip the contents in the shader to maintain orientation.
- bool flip_vertically = false;
-
- CopyTextureToFramebuffer(frame,
- texture->getTextureHandle(),
- backdrop_bounding_rect,
- device_to_framebuffer_transform,
- flip_vertically);
- }
-
- UseRenderPass(frame, target_render_pass);
-
- if (!using_background_texture)
- return nullptr;
- return background_texture.Pass();
-}
-
void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
const RenderPassDrawQuad* quad) {
- SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode;
- SetBlendEnabled(
- CanApplyBlendModeUsingBlendFunc(blend_mode) &&
- (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode)));
-
ScopedResource* contents_texture =
render_pass_textures_.get(quad->render_pass_id);
if (!contents_texture || !contents_texture->id())
@@ -984,62 +895,59 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
SetupQuadForAntialiasing(contents_device_transform, quad,
&surface_quad, edge);
- bool need_background_texture = !CanApplyBlendModeUsingBlendFunc(blend_mode) ||
- ShouldApplyBackgroundFilters(frame, quad);
+ SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode;
+ bool use_shaders_for_blending =
+ !CanApplyBlendModeUsingBlendFunc(blend_mode) ||
+ ShouldApplyBackgroundFilters(frame, quad) ||
+ settings_->force_blending_with_shaders;
scoped_ptr<ScopedResource> background_texture;
skia::RefPtr<SkImage> background_image;
gfx::Rect background_rect;
- if (need_background_texture) {
+ if (use_shaders_for_blending) {
// Compute a bounding box around the pixels that will be visible through
// the quad.
background_rect = GetBackdropBoundingBoxForRenderPassQuad(
frame, quad, contents_device_transform, use_aa);
- }
- if (!background_rect.IsEmpty()) {
- // The pixels from the filtered background should completely replace the
- // current pixel values.
- bool disable_blending = blend_enabled();
- if (disable_blending)
- SetBlendEnabled(false);
-
- // Read the pixels in the bounding box into a buffer R.
- scoped_ptr<ScopedResource> scoped_background_texture =
- GetBackdropTexture(background_rect);
-
- skia::RefPtr<SkImage> background_with_filters;
- if (ShouldApplyBackgroundFilters(frame, quad) &&
- scoped_background_texture) {
- // Apply the background filters to R, so that it is applied in the pixels'
- // coordinate space.
- background_with_filters =
- ApplyBackgroundFilters(frame, quad, scoped_background_texture.get());
- }
-
- if (CanApplyBlendModeUsingBlendFunc(blend_mode) &&
- background_with_filters) {
- // The background with filters will be copied to the frame buffer.
- // Apply the quad's inverse transform to map the pixels in R into the
- // quad's content space. This implicitly clips R by the content bounds of
- // the quad since the destination texture has bounds matching the quad's
- // content.
- background_texture = ApplyInverseTransformForBackgroundFilters(
- frame, quad, contents_device_transform, background_with_filters,
- background_rect);
- } else if (!CanApplyBlendModeUsingBlendFunc(blend_mode)) {
- if (background_with_filters) {
- // The background with filters will be used as backdrop for blending.
- background_image = background_with_filters;
- } else {
- background_texture = scoped_background_texture.Pass();
+ if (!background_rect.IsEmpty()) {
+ // The pixels from the filtered background should completely replace the
+ // current pixel values.
+ if (blend_enabled())
+ SetBlendEnabled(false);
+
+ // Read the pixels in the bounding box into a buffer R.
+ // This function allocates a texture, which should contribute to the
+ // amount of memory used by render surfaces:
+ // LayerTreeHost::CalculateMemoryForRenderSurfaces.
+ background_texture = GetBackdropTexture(background_rect);
+
+ if (ShouldApplyBackgroundFilters(frame, quad) && background_texture) {
+ // Apply the background filters to R, so that it is applied in the
+ // pixels' coordinate space.
+ background_image =
+ ApplyBackgroundFilters(frame, quad, background_texture.get());
}
}
- if (disable_blending)
- SetBlendEnabled(true);
+ if (!background_texture) {
+ // Something went wrong with reading the backdrop.
+ DCHECK(!background_image);
+ use_shaders_for_blending = false;
+ } else if (background_image) {
+ background_texture.reset();
+ } else if (CanApplyBlendModeUsingBlendFunc(blend_mode) &&
+ ShouldApplyBackgroundFilters(frame, quad)) {
+ // Something went wrong with applying background filters to the backdrop.
+ use_shaders_for_blending = false;
+ background_texture.reset();
+ }
}
+ SetBlendEnabled(
+ !use_shaders_for_blending &&
+ (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode)));
+
// TODO(senorblanco): Cache this value so that we don't have to do it for both
// the surface and its replica. Apply filters to the contents texture.
skia::RefPtr<SkImage> filter_image;
@@ -1072,25 +980,6 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
}
}
- if (background_texture && ShouldApplyBackgroundFilters(frame, quad)) {
- // Draw the background texture if it has some filters applied.
- DCHECK(CanApplyBlendModeUsingBlendFunc(blend_mode));
- DCHECK(background_texture->size() == quad->rect.size());
- ResourceProvider::ScopedReadLockGL lock(resource_provider_,
- background_texture->id());
-
- // The background_texture is oriented the same as the frame buffer. The
- // transform we are copying with has a vertical flip, so flip the contents
- // in the shader to maintain orientation
- bool flip_vertically = true;
-
- CopyTextureToFramebuffer(frame,
- lock.texture_id(),
- quad->rect,
- quad->quadTransform(),
- flip_vertically);
- }
-
scoped_ptr<ResourceProvider::ScopedSamplerGL> mask_resource_lock;
unsigned mask_texture_id = 0;
SamplerType mask_sampler = SamplerTypeNA;
@@ -1101,9 +990,6 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
mask_sampler = SamplerTypeFromTextureTarget(mask_resource_lock->target());
}
- // TODO(danakj): use the background_texture and blend the background in with
- // this draw instead of having a separate copy of the background texture.
-
scoped_ptr<ResourceProvider::ScopedSamplerGL> contents_resource_lock;
if (filter_image) {
GrTexture* texture = filter_image->getTexture();
@@ -1117,7 +1003,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
contents_resource_lock->target());
}
- if (CanApplyBlendModeUsingBlendFunc(blend_mode)) {
+ if (!use_shaders_for_blending) {
if (!use_blend_equation_advanced_coherent_ && use_blend_equation_advanced_)
GLC(gl_, gl_->BlendBarrierKHR());
@@ -1144,10 +1030,10 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
int shader_backdrop_location = -1;
int shader_backdrop_rect_location = -1;
- BlendMode shader_blend_mode = ((background_texture || background_image) &&
- !CanApplyBlendModeUsingBlendFunc(blend_mode))
+ DCHECK_EQ(background_texture || background_image, use_shaders_for_blending);
+ BlendMode shader_blend_mode = use_shaders_for_blending
? BlendModeFromSkXfermode(blend_mode)
- : BlendModeNormal;
+ : BlendModeNone;
if (use_aa && mask_texture_id && !use_color_matrix) {
const RenderPassMaskProgramAA* program = GetRenderPassMaskProgramAA(
@@ -1424,7 +1310,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
if (filter_image)
GLC(gl_, gl_->Flush());
- if (CanApplyBlendModeUsingBlendFunc(blend_mode))
+ if (!use_shaders_for_blending)
RestoreBlendFuncToDefault(blend_mode);
}
@@ -2452,43 +2338,6 @@ void GLRenderer::DrawQuadGeometry(const DrawingFrame* frame,
GLC(gl_, gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0));
}
-void GLRenderer::CopyTextureToFramebuffer(const DrawingFrame* frame,
- int texture_id,
- const gfx::Rect& rect,
- const gfx::Transform& draw_matrix,
- bool flip_vertically) {
- TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
- gl_, &highp_threshold_cache_, highp_threshold_min_, rect.bottom_right());
-
- const RenderPassProgram* program =
- GetRenderPassProgram(tex_coord_precision, BlendModeNormal);
- SetUseProgram(program->program());
-
- GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
-
- if (flip_vertically) {
- GLC(gl_,
- gl_->Uniform4f(program->vertex_shader().tex_transform_location(),
- 0.f,
- 1.f,
- 1.f,
- -1.f));
- } else {
- GLC(gl_,
- gl_->Uniform4f(program->vertex_shader().tex_transform_location(),
- 0.f,
- 0.f,
- 1.f,
- 1.f));
- }
-
- SetShaderOpacity(1.f, program->fragment_shader().alpha_location());
- DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
- GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, texture_id));
- DrawQuadGeometry(
- frame, draw_matrix, rect, program->vertex_shader().matrix_location());
-}
-
void GLRenderer::Finish() {
TRACE_EVENT0("cc", "GLRenderer::Finish");
GLC(gl_, gl_->Finish());
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h
index 4930204..ecadebb 100644
--- a/cc/output/gl_renderer.h
+++ b/cc/output/gl_renderer.h
@@ -167,12 +167,6 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
DrawingFrame* frame,
const RenderPassDrawQuad* quad,
ScopedResource* background_texture);
- scoped_ptr<ScopedResource> ApplyInverseTransformForBackgroundFilters(
- DrawingFrame* frame,
- const RenderPassDrawQuad* quad,
- const gfx::Transform& contents_device_transform,
- skia::RefPtr<SkImage> backdrop_bitmap,
- const gfx::Rect& backdrop_bounding_rect);
void DrawRenderPassQuad(DrawingFrame* frame, const RenderPassDrawQuad* quad);
void DrawSolidColorQuad(const DrawingFrame* frame,
@@ -208,12 +202,6 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
int matrix_location);
void SetUseProgram(unsigned program);
- void CopyTextureToFramebuffer(const DrawingFrame* frame,
- int texture_id,
- const gfx::Rect& rect,
- const gfx::Transform& draw_matrix,
- bool flip_vertically);
-
bool UseScopedTexture(DrawingFrame* frame,
const ScopedResource* resource,
const gfx::Rect& viewport_rect);
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
index dc68675..2af953e 100644
--- a/cc/output/gl_renderer_unittest.cc
+++ b/cc/output/gl_renderer_unittest.cc
@@ -57,8 +57,11 @@ class GLRendererTest : public testing::Test {
static inline SkXfermode::Mode BlendModeToSkXfermode(BlendMode blend_mode) {
switch (blend_mode) {
+ case BlendModeNone:
case BlendModeNormal:
return SkXfermode::kSrcOver_Mode;
+ case BlendModeScreen:
+ return SkXfermode::kScreen_Mode;
case BlendModeOverlay:
return SkXfermode::kOverlay_Mode;
case BlendModeDarken:
@@ -1421,6 +1424,7 @@ TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
for (int i = 0; i < NumBlendModes; ++i) {
BlendMode blend_mode = static_cast<BlendMode>(i);
SkXfermode::Mode xfer_mode = BlendModeToSkXfermode(blend_mode);
+ settings_.force_blending_with_shaders = (blend_mode != BlendModeNone);
// RenderPassProgram
render_passes_in_draw_order_.clear();
child_pass = AddRenderPass(&render_passes_in_draw_order_,
@@ -1690,7 +1694,7 @@ TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
// If use_aa incorrectly ignores clipping, it will use the
// RenderPassProgramAA shader instead of the RenderPassProgram.
- TestRenderPassProgram(TexCoordPrecisionMedium, BlendModeNormal);
+ TestRenderPassProgram(TexCoordPrecisionMedium, BlendModeNone);
}
TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
diff --git a/cc/output/program_binding.h b/cc/output/program_binding.h
index 722c782..a10d0ab 100644
--- a/cc/output/program_binding.h
+++ b/cc/output/program_binding.h
@@ -59,7 +59,7 @@ class ProgramBinding : public ProgramBindingBase {
void Initialize(ContextProvider* context_provider,
TexCoordPrecision precision,
SamplerType sampler,
- BlendMode blend_mode = BlendModeNormal) {
+ BlendMode blend_mode = BlendModeNone) {
DCHECK(context_provider);
DCHECK(!initialized_);
diff --git a/cc/output/shader.cc b/cc/output/shader.cc
index b962d4a..e22e446 100644
--- a/cc/output/shader.cc
+++ b/cc/output/shader.cc
@@ -669,9 +669,9 @@ std::string VertexShaderVideoTransform::GetShaderString() const {
}
#define BLEND_MODE_UNIFORMS "s_backdropTexture", "backdropRect"
-#define UNUSED_BLEND_MODE_UNIFORMS (is_default_blend_mode() ? 2 : 0)
+#define UNUSED_BLEND_MODE_UNIFORMS (!has_blend_mode() ? 2 : 0)
#define BLEND_MODE_SET_LOCATIONS(X, POS) \
- if (!is_default_blend_mode()) { \
+ if (has_blend_mode()) { \
DCHECK_LT(static_cast<size_t>(POS) + 1, arraysize(X)); \
backdrop_location_ = locations[POS]; \
backdrop_rect_location_ = locations[POS + 1]; \
@@ -680,7 +680,7 @@ std::string VertexShaderVideoTransform::GetShaderString() const {
FragmentTexBlendMode::FragmentTexBlendMode()
: backdrop_location_(-1),
backdrop_rect_location_(-1),
- blend_mode_(BlendModeNormal) {
+ blend_mode_(BlendModeNone) {
}
std::string FragmentTexBlendMode::SetBlendModeFunctions(
@@ -688,7 +688,7 @@ std::string FragmentTexBlendMode::SetBlendModeFunctions(
if (shader_string.find("ApplyBlendMode") == std::string::npos)
return shader_string;
- if (is_default_blend_mode()) {
+ if (!has_blend_mode()) {
return "#define ApplyBlendMode(X) (X)\n" + shader_string;
}
@@ -902,6 +902,10 @@ std::string FragmentTexBlendMode::GetBlendFunction() const {
std::string FragmentTexBlendMode::GetBlendFunctionBodyForRGB() const {
switch (blend_mode_) {
+ case BlendModeNormal:
+ return "result.rgb = src.rgb + dst.rgb * (1.0 - src.a);";
+ case BlendModeScreen:
+ return "result.rgb = src.rgb + (1.0 - src.rgb) * dst.rgb;";
case BlendModeLighten:
return "result.rgb = max((1.0 - src.a) * dst.rgb + src.rgb,"
" (1.0 - dst.a) * src.rgb + dst.rgb);";
@@ -963,11 +967,11 @@ std::string FragmentTexBlendMode::GetBlendFunctionBodyForRGB() const {
" srcDstAlpha.a,"
" srcDstAlpha.rgb);"
"result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
- default:
+ case BlendModeNone:
+ case NumBlendModes:
NOTREACHED();
- // simple alpha compositing
- return "result.rgb = src.rgb * src.a + dst.rgb * dst.a * (1 - src.a)";
}
+ return "result = vec4(1.0, 0.0, 0.0, 1.0);";
}
FragmentTexAlphaBinding::FragmentTexAlphaBinding()
diff --git a/cc/output/shader.h b/cc/output/shader.h
index 0384366..8c1f264 100644
--- a/cc/output/shader.h
+++ b/cc/output/shader.h
@@ -39,7 +39,9 @@ enum SamplerType {
};
enum BlendMode {
+ BlendModeNone,
BlendModeNormal,
+ BlendModeScreen,
BlendModeOverlay,
BlendModeDarken,
BlendModeLighten,
@@ -305,7 +307,7 @@ class FragmentTexBlendMode {
BlendMode blend_mode() const { return blend_mode_; }
void set_blend_mode(BlendMode blend_mode) { blend_mode_ = blend_mode; }
- bool is_default_blend_mode() const { return blend_mode_ == BlendModeNormal; }
+ bool has_blend_mode() const { return blend_mode_ != BlendModeNone; }
protected:
FragmentTexBlendMode();
diff --git a/cc/test/data/background_filter_blur_off_axis.png b/cc/test/data/background_filter_blur_off_axis.png
index 050ec54..5077171 100644
--- a/cc/test/data/background_filter_blur_off_axis.png
+++ b/cc/test/data/background_filter_blur_off_axis.png
Binary files differ
diff --git a/cc/test/data/background_filter_blur_outsets.png b/cc/test/data/background_filter_blur_outsets.png
index 9234496..3293ab8 100644
--- a/cc/test/data/background_filter_blur_outsets.png
+++ b/cc/test/data/background_filter_blur_outsets.png
Binary files differ
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index af7eb5b..ae85fc7c 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -960,7 +960,6 @@ void LayerTreeHost::PrioritizeTextures(
size_t LayerTreeHost::CalculateMemoryForRenderSurfaces(
const RenderSurfaceLayerList& update_list) {
size_t readback_bytes = 0;
- size_t max_background_texture_bytes = 0;
size_t contents_texture_bytes = 0;
// Start iteration at 1 to skip the root surface as it does not have a texture
@@ -974,17 +973,16 @@ size_t LayerTreeHost::CalculateMemoryForRenderSurfaces(
RGBA_8888);
contents_texture_bytes += bytes;
- if (render_surface_layer->background_filters().IsEmpty())
+ if (render_surface_layer->background_filters().IsEmpty() &&
+ render_surface_layer->uses_default_blend_mode())
continue;
- if (bytes > max_background_texture_bytes)
- max_background_texture_bytes = bytes;
if (!readback_bytes) {
readback_bytes = Resource::MemorySizeBytes(device_viewport_size_,
RGBA_8888);
}
}
- return readback_bytes + max_background_texture_bytes + contents_texture_bytes;
+ return readback_bytes + contents_texture_bytes;
}
void LayerTreeHost::PaintMasksForRenderSurface(Layer* render_surface_layer,
diff --git a/cc/trees/layer_tree_host_pixeltest_blending.cc b/cc/trees/layer_tree_host_pixeltest_blending.cc
index 1b075b2..148769e 100644
--- a/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -52,15 +52,18 @@ using RenderPassOptions = uint32;
const uint32 kUseMasks = 1 << 0;
const uint32 kUseAntialiasing = 1 << 1;
const uint32 kUseColorMatrix = 1 << 2;
+const uint32 kForceShaders = 1 << 3;
class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest {
public:
- LayerTreeHostBlendingPixelTest() {
+ LayerTreeHostBlendingPixelTest()
+ : force_antialiasing_(false), force_blending_with_shaders_(false) {
pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true));
}
virtual void InitializeSettings(LayerTreeSettings* settings) override {
settings->force_antialiasing = force_antialiasing_;
+ settings->force_blending_with_shaders = force_blending_with_shaders_;
}
protected:
@@ -233,6 +236,7 @@ class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest {
this->impl_side_painting_ = false;
this->force_antialiasing_ = (flags & kUseAntialiasing);
+ this->force_blending_with_shaders_ = (flags & kForceShaders);
if ((flags & kUseAntialiasing) && (type == PIXEL_TEST_GL)) {
// Anti aliasing causes differences up to 8 pixels at the edges.
@@ -259,7 +263,8 @@ class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest {
RunPixelTest(type, root, base::FilePath(expected_path));
}
- bool force_antialiasing_ = false;
+ bool force_antialiasing_;
+ bool force_blending_with_shaders_;
};
TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) {
@@ -410,6 +415,61 @@ TEST_F(LayerTreeHostBlendingPixelTest,
kUseMasks | kUseAntialiasing | kUseColorMatrix);
}
+// Tests for render passes forcing shaders for all the blend modes.
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShaders_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass.png"),
+ kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersAA_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass.png"),
+ kUseAntialiasing | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersWithMask_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+ kUseMasks | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersWithMaskAA_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+ kUseMasks | kUseAntialiasing | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersColorMatrix_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass.png"),
+ kUseColorMatrix | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersColorMatrixAA_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass.png"),
+ kUseAntialiasing | kUseColorMatrix | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersWithMaskColorMatrix_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+ kUseMasks | kUseColorMatrix | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersWithMaskColorMatrixAA_GL) {
+ RunBlendingWithRenderPass(
+ PIXEL_TEST_GL, FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+ kUseMasks | kUseAntialiasing | kUseColorMatrix | kForceShaders);
+}
+
} // namespace
} // namespace cc
diff --git a/cc/trees/layer_tree_host_pixeltest_filters.cc b/cc/trees/layer_tree_host_pixeltest_filters.cc
index 40fa2c3..a425eed 100644
--- a/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -136,8 +136,8 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) {
blur->SetBackgroundFilters(filters);
#if defined(OS_WIN)
- // Windows has 153 pixels off by at most 2: crbug.com/225027
- float percentage_pixels_large_error = 0.3825f; // 153px / (200*200)
+ // Windows has 116 pixels off by at most 2: crbug.com/225027
+ float percentage_pixels_large_error = 0.3f; // 116px / (200*200), rounded up
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
int large_error_allowed = 2;
diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc
index 1d5cf1b..c9763a5 100644
--- a/cc/trees/layer_tree_settings.cc
+++ b/cc/trees/layer_tree_settings.cc
@@ -16,6 +16,7 @@ LayerTreeSettings::LayerTreeSettings()
: impl_side_painting(false),
allow_antialiasing(true),
force_antialiasing(false),
+ force_blending_with_shaders(false),
throttle_frame_production(true),
single_thread_proxy_scheduler(true),
begin_frame_scheduling_enabled(false),
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index 74a3b0c..c5f08e9 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -21,6 +21,7 @@ class CC_EXPORT LayerTreeSettings {
bool impl_side_painting;
bool allow_antialiasing;
bool force_antialiasing;
+ bool force_blending_with_shaders;
bool throttle_frame_production;
bool single_thread_proxy_scheduler;
bool begin_frame_scheduling_enabled;