| Index: cc/output/gl_renderer.cc
|
| diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
|
| index 4eb1324217b00d0c587e346899a272fbe3ed45a0..cb6189e90e14f7b7d012f5a7644691b2ca6be0c4 100644
|
| --- a/cc/output/gl_renderer.cc
|
| +++ b/cc/output/gl_renderer.cc
|
| @@ -98,6 +98,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:
|
| @@ -128,7 +130,7 @@ BlendMode BlendModeFromSkXfermode(SkXfermode::Mode mode) {
|
| return BlendModeLuminosity;
|
| default:
|
| NOTREACHED();
|
| - return BlendModeNormal;
|
| + return BlendModeNone;
|
| }
|
| }
|
|
|
| @@ -865,99 +867,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())
|
| @@ -983,62 +894,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;
|
| @@ -1071,25 +979,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;
|
| @@ -1100,9 +989,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();
|
| @@ -1116,7 +1002,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());
|
|
|
| @@ -1143,10 +1029,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(
|
| @@ -1423,7 +1309,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);
|
| }
|
|
|
| @@ -2096,8 +1982,8 @@ void GLRenderer::DrawPictureQuad(const DrawingFrame* frame,
|
| }
|
|
|
| SkCanvas canvas(on_demand_tile_raster_bitmap_);
|
| - quad->picture_pile->PlaybackToCanvas(&canvas, quad->content_rect,
|
| - quad->contents_scale);
|
| + quad->raster_source->PlaybackToCanvas(&canvas, quad->content_rect,
|
| + quad->contents_scale);
|
|
|
| uint8_t* bitmap_pixels = NULL;
|
| SkBitmap on_demand_tile_raster_bitmap_dest;
|
| @@ -2451,43 +2337,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());
|
|
|