| Index: cc/output/gl_renderer.cc
|
| diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
|
| index ac449a46f5df84bc66ffe091b6470f8c6a394cb9..70fb606b979268845d70a898b93a8dae44f0d505 100644
|
| --- a/cc/output/gl_renderer.cc
|
| +++ b/cc/output/gl_renderer.cc
|
| @@ -727,141 +727,6 @@ void GLRenderer::RestoreBlendFuncToDefault(SkXfermode::Mode blend_mode) {
|
| GLC(gl_, gl_->BlendEquation(GL_FUNC_ADD));
|
| }
|
|
|
| -static skia::RefPtr<SkImage> ApplyBlendModeWithBackdrop(
|
| - scoped_ptr<GLRenderer::ScopedUseGrContext> use_gr_context,
|
| - ResourceProvider* resource_provider,
|
| - skia::RefPtr<SkImage> source_bitmap_with_filters,
|
| - ScopedResource* source_texture_resource,
|
| - ScopedResource* background_texture_resource,
|
| - SkXfermode::Mode blend_mode) {
|
| - if (!use_gr_context)
|
| - return source_bitmap_with_filters;
|
| -
|
| - DCHECK(background_texture_resource);
|
| - DCHECK(source_texture_resource);
|
| -
|
| - gfx::Size source_size = source_texture_resource->size();
|
| - gfx::Size background_size = background_texture_resource->size();
|
| -
|
| - DCHECK_LE(background_size.width(), source_size.width());
|
| - DCHECK_LE(background_size.height(), source_size.height());
|
| -
|
| - int source_texture_with_filters_id;
|
| - scoped_ptr<ResourceProvider::ScopedReadLockGL> lock;
|
| - if (source_bitmap_with_filters) {
|
| - DCHECK_EQ(source_size.width(), source_bitmap_with_filters->width());
|
| - DCHECK_EQ(source_size.height(), source_bitmap_with_filters->height());
|
| - GrTexture* texture =
|
| - reinterpret_cast<GrTexture*>(source_bitmap_with_filters->getTexture());
|
| - source_texture_with_filters_id = texture->getTextureHandle();
|
| - } else {
|
| - lock.reset(new ResourceProvider::ScopedReadLockGL(
|
| - resource_provider, source_texture_resource->id()));
|
| - source_texture_with_filters_id = lock->texture_id();
|
| - }
|
| -
|
| - ResourceProvider::ScopedReadLockGL lock_background(
|
| - resource_provider, background_texture_resource->id());
|
| -
|
| - // Wrap the source texture in a Ganesh platform texture.
|
| - GrBackendTextureDesc backend_texture_description;
|
| - backend_texture_description.fConfig = kSkia8888_GrPixelConfig;
|
| - backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin;
|
| -
|
| - backend_texture_description.fWidth = source_size.width();
|
| - backend_texture_description.fHeight = source_size.height();
|
| - backend_texture_description.fTextureHandle = source_texture_with_filters_id;
|
| - skia::RefPtr<GrTexture> source_texture =
|
| - skia::AdoptRef(use_gr_context->context()->wrapBackendTexture(
|
| - backend_texture_description));
|
| - if (!source_texture) {
|
| - TRACE_EVENT_INSTANT0(
|
| - "cc",
|
| - "ApplyBlendModeWithBackdrop wrap source texture failed",
|
| - TRACE_EVENT_SCOPE_THREAD);
|
| - return skia::RefPtr<SkImage>();
|
| - }
|
| -
|
| - backend_texture_description.fWidth = background_size.width();
|
| - backend_texture_description.fHeight = background_size.height();
|
| - backend_texture_description.fTextureHandle = lock_background.texture_id();
|
| - skia::RefPtr<GrTexture> background_texture =
|
| - skia::AdoptRef(use_gr_context->context()->wrapBackendTexture(
|
| - backend_texture_description));
|
| - if (!background_texture) {
|
| - TRACE_EVENT_INSTANT0(
|
| - "cc",
|
| - "ApplyBlendModeWithBackdrop wrap background texture failed",
|
| - TRACE_EVENT_SCOPE_THREAD);
|
| - return skia::RefPtr<SkImage>();
|
| - }
|
| -
|
| - SkImageInfo source_info =
|
| - SkImageInfo::MakeN32Premul(source_size.width(), source_size.height());
|
| - // Place the platform texture inside an SkBitmap.
|
| - SkBitmap source;
|
| - source.setInfo(source_info);
|
| - skia::RefPtr<SkGrPixelRef> source_pixel_ref =
|
| - skia::AdoptRef(new SkGrPixelRef(source_info, source_texture.get()));
|
| - source.setPixelRef(source_pixel_ref.get());
|
| -
|
| - SkImageInfo background_info = SkImageInfo::MakeN32Premul(
|
| - background_size.width(), background_size.height());
|
| -
|
| - SkBitmap background;
|
| - background.setInfo(background_info);
|
| - skia::RefPtr<SkGrPixelRef> background_pixel_ref =
|
| - skia::AdoptRef(new SkGrPixelRef(
|
| - background_info, background_texture.get()));
|
| - background.setPixelRef(background_pixel_ref.get());
|
| -
|
| - // Create a scratch texture for backing store.
|
| - GrTextureDesc desc;
|
| - desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
|
| - desc.fSampleCnt = 0;
|
| - desc.fWidth = source.width();
|
| - desc.fHeight = source.height();
|
| - desc.fConfig = kSkia8888_GrPixelConfig;
|
| - desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
|
| - GrAutoScratchTexture scratch_texture(
|
| - use_gr_context->context(), desc, GrContext::kExact_ScratchTexMatch);
|
| - skia::RefPtr<GrTexture> backing_store =
|
| - skia::AdoptRef(scratch_texture.detach());
|
| - if (!backing_store) {
|
| - TRACE_EVENT_INSTANT0(
|
| - "cc",
|
| - "ApplyBlendModeWithBackdrop scratch texture allocation failed",
|
| - TRACE_EVENT_SCOPE_THREAD);
|
| - return source_bitmap_with_filters;
|
| - }
|
| -
|
| - // Create a device and canvas using that backing store.
|
| - skia::RefPtr<SkSurface> surface = skia::AdoptRef(
|
| - SkSurface::NewRenderTargetDirect(backing_store->asRenderTarget()));
|
| - if (!surface)
|
| - return skia::RefPtr<SkImage>();
|
| - skia::RefPtr<SkCanvas> canvas = skia::SharePtr(surface->getCanvas());
|
| -
|
| - // Draw the source bitmap through the filter to the canvas.
|
| - canvas->clear(SK_ColorTRANSPARENT);
|
| - canvas->drawSprite(background, 0, 0);
|
| - SkPaint paint;
|
| - paint.setXfermodeMode(blend_mode);
|
| - canvas->drawSprite(source, 0, 0, &paint);
|
| -
|
| - skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot());
|
| - if (!image || !image->getTexture()) {
|
| - return skia::RefPtr<SkImage>();
|
| - }
|
| -
|
| - // Flush the GrContext to ensure all buffered GL calls are drawn to the
|
| - // backing store before we access and return it, and have cc begin using the
|
| - // GL context again.
|
| - canvas->flush();
|
| -
|
| - return image;
|
| -}
|
| -
|
| bool GLRenderer::ShouldApplyBackgroundFilters(DrawingFrame* frame,
|
| const RenderPassDrawQuad* quad) {
|
| if (quad->background_filters.IsEmpty())
|
| @@ -883,7 +748,8 @@ bool GLRenderer::ShouldApplyBackgroundFilters(DrawingFrame* frame,
|
| gfx::Rect GLRenderer::GetBackdropBoundingBoxForRenderPassQuad(
|
| DrawingFrame* frame,
|
| const RenderPassDrawQuad* quad,
|
| - const gfx::Transform& contents_device_transform) {
|
| + const gfx::Transform& contents_device_transform,
|
| + bool use_aa) {
|
| gfx::Rect backdrop_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect(
|
| contents_device_transform, SharedGeometryQuad().BoundingBox()));
|
|
|
| @@ -893,6 +759,11 @@ gfx::Rect GLRenderer::GetBackdropBoundingBoxForRenderPassQuad(
|
| backdrop_rect.Inset(-left, -top, -right, -bottom);
|
| }
|
|
|
| + if (!backdrop_rect.IsEmpty() && use_aa) {
|
| + const int kOutsetForAntialiasing = 1;
|
| + backdrop_rect.Inset(-kOutsetForAntialiasing, -kOutsetForAntialiasing);
|
| + }
|
| +
|
| backdrop_rect.Intersect(
|
| MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect));
|
| return backdrop_rect;
|
| @@ -937,7 +808,6 @@ GLRenderer::ApplyInverseTransformForBackgroundFilters(
|
| DrawingFrame* frame,
|
| const RenderPassDrawQuad* quad,
|
| const gfx::Transform& contents_device_transform_inverse,
|
| - ScopedResource* device_background_texture,
|
| 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
|
| @@ -964,18 +834,9 @@ GLRenderer::ApplyInverseTransformForBackgroundFilters(
|
| // TODO(danakj): When this algorithm changes, update
|
| // LayerTreeHost::PrioritizeTextures() accordingly.
|
|
|
| - DCHECK(device_background_texture);
|
| + DCHECK(filtered_device_background);
|
|
|
| - int filtered_device_background_texture_id = 0;
|
| - scoped_ptr<ResourceProvider::ScopedReadLockGL> lock;
|
| - if (filtered_device_background) {
|
| - GrTexture* texture = filtered_device_background->getTexture();
|
| - filtered_device_background_texture_id = texture->getTextureHandle();
|
| - } else {
|
| - lock.reset(new ResourceProvider::ScopedReadLockGL(
|
| - resource_provider_, device_background_texture->id()));
|
| - filtered_device_background_texture_id = lock->texture_id();
|
| - }
|
| + GrTexture* texture = filtered_device_background->getTexture();
|
|
|
| scoped_ptr<ScopedResource> background_texture =
|
| ScopedResource::Create(resource_provider_);
|
| @@ -1009,7 +870,7 @@ GLRenderer::ApplyInverseTransformForBackgroundFilters(
|
| bool flip_vertically = false;
|
|
|
| CopyTextureToFramebuffer(frame,
|
| - filtered_device_background_texture_id,
|
| + texture->getTextureHandle(),
|
| backdrop_bounding_rect,
|
| device_to_framebuffer_transform,
|
| flip_vertically);
|
| @@ -1025,9 +886,9 @@ GLRenderer::ApplyInverseTransformForBackgroundFilters(
|
| void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| const RenderPassDrawQuad* quad) {
|
| SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode;
|
| - SetBlendEnabled(quad->ShouldDrawWithBlending() ||
|
| - (!IsDefaultBlendMode(blend_mode) &&
|
| - CanApplyBlendModeUsingBlendFunc(blend_mode)));
|
| + SetBlendEnabled(
|
| + CanApplyBlendModeUsingBlendFunc(blend_mode) &&
|
| + (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode)));
|
|
|
| ScopedResource* contents_texture =
|
| render_pass_textures_.get(quad->render_pass_id);
|
| @@ -1046,44 +907,69 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| if (!contents_device_transform.GetInverse(&contents_device_transform_inverse))
|
| return;
|
|
|
| + bool clipped = false;
|
| + gfx::QuadF device_quad = MathUtil::MapQuad(
|
| + contents_device_transform, SharedGeometryQuad(), &clipped);
|
| + // Use anti-aliasing programs only when necessary.
|
| + bool use_aa =
|
| + !clipped && (!device_quad.IsRectilinear() ||
|
| + !gfx::IsNearestRectWithinDistance(device_quad.BoundingBox(),
|
| + kAntiAliasingEpsilon));
|
| +
|
| bool need_background_texture = !CanApplyBlendModeUsingBlendFunc(blend_mode) ||
|
| ShouldApplyBackgroundFilters(frame, quad);
|
|
|
| scoped_ptr<ScopedResource> background_texture;
|
| + skia::RefPtr<SkImage> background_image;
|
| + gfx::Rect background_rect;
|
| if (need_background_texture) {
|
| + // 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);
|
|
|
| - // Compute a bounding box around the pixels that will be visible through
|
| - // the quad.
|
| - gfx::Rect backdrop_rect = GetBackdropBoundingBoxForRenderPassQuad(
|
| - frame, quad, contents_device_transform);
|
| -
|
| // Read the pixels in the bounding box into a buffer R.
|
| scoped_ptr<ScopedResource> scoped_background_texture =
|
| - GetBackdropTexture(backdrop_rect);
|
| + GetBackdropTexture(background_rect);
|
|
|
| skia::RefPtr<SkImage> background_with_filters;
|
| - if (ShouldApplyBackgroundFilters(frame, quad)) {
|
| + 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());
|
| }
|
| - // 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_inverse,
|
| - scoped_background_texture.get(),
|
| - background_with_filters,
|
| - backdrop_rect);
|
| +
|
| + 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_inverse,
|
| + 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 (disable_blending)
|
| SetBlendEnabled(true);
|
| @@ -1122,49 +1008,27 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| }
|
| }
|
|
|
| - if (background_texture) {
|
| - if (CanApplyBlendModeUsingBlendFunc(blend_mode)) {
|
| - // Draw the background texture if it has some filters applied.
|
| - DCHECK(ShouldApplyBackgroundFilters(frame, quad));
|
| - 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);
|
| - } else {
|
| - // If blending is applied using shaders, the background texture with
|
| - // filters will be used as backdrop for blending operation, so we don't
|
| - // need to copy it to the frame buffer.
|
| - filter_bitmap =
|
| - ApplyBlendModeWithBackdrop(ScopedUseGrContext::Create(this, frame),
|
| - resource_provider_,
|
| - filter_bitmap,
|
| - contents_texture,
|
| - background_texture.get(),
|
| - quad->shared_quad_state->blend_mode);
|
| - }
|
| + 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);
|
| }
|
|
|
| - bool clipped = false;
|
| - gfx::QuadF device_quad = MathUtil::MapQuad(
|
| - contents_device_transform, SharedGeometryQuad(), &clipped);
|
| LayerQuad device_layer_bounds(gfx::QuadF(device_quad.BoundingBox()));
|
| LayerQuad device_layer_edges(device_quad);
|
| -
|
| - // Use anti-aliasing programs only when necessary.
|
| - bool use_aa =
|
| - !clipped && (!device_quad.IsRectilinear() ||
|
| - !gfx::IsNearestRectWithinDistance(device_quad.BoundingBox(),
|
| - kAntiAliasingEpsilon));
|
| if (use_aa) {
|
| device_layer_bounds.InflateAntiAliasingDistance();
|
| device_layer_edges.InflateAntiAliasingDistance();
|
| @@ -1214,10 +1078,18 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| int shader_color_matrix_location = -1;
|
| int shader_color_offset_location = -1;
|
| int shader_tex_transform_location = -1;
|
| + int shader_backdrop_location = -1;
|
| + int shader_backdrop_rect_location = -1;
|
| +
|
| + SkXfermode::Mode shader_blend_mode =
|
| + ((background_texture || background_image) &&
|
| + !CanApplyBlendModeUsingBlendFunc(blend_mode))
|
| + ? blend_mode
|
| + : kDefaultBlendMode;
|
|
|
| if (use_aa && mask_texture_id && !use_color_matrix) {
|
| const RenderPassMaskProgramAA* program =
|
| - GetRenderPassMaskProgramAA(tex_coord_precision);
|
| + GetRenderPassMaskProgramAA(tex_coord_precision, shader_blend_mode);
|
| SetUseProgram(program->program());
|
| GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
|
|
|
| @@ -1234,9 +1106,12 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| shader_alpha_location = program->fragment_shader().alpha_location();
|
| shader_tex_transform_location =
|
| program->vertex_shader().tex_transform_location();
|
| + shader_backdrop_location = program->fragment_shader().backdrop_location();
|
| + shader_backdrop_rect_location =
|
| + program->fragment_shader().backdrop_rect_location();
|
| } else if (!use_aa && mask_texture_id && !use_color_matrix) {
|
| const RenderPassMaskProgram* program =
|
| - GetRenderPassMaskProgram(tex_coord_precision);
|
| + GetRenderPassMaskProgram(tex_coord_precision, shader_blend_mode);
|
| SetUseProgram(program->program());
|
| GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
|
|
|
| @@ -1250,9 +1125,12 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| shader_alpha_location = program->fragment_shader().alpha_location();
|
| shader_tex_transform_location =
|
| program->vertex_shader().tex_transform_location();
|
| + shader_backdrop_location = program->fragment_shader().backdrop_location();
|
| + shader_backdrop_rect_location =
|
| + program->fragment_shader().backdrop_rect_location();
|
| } else if (use_aa && !mask_texture_id && !use_color_matrix) {
|
| const RenderPassProgramAA* program =
|
| - GetRenderPassProgramAA(tex_coord_precision);
|
| + GetRenderPassProgramAA(tex_coord_precision, shader_blend_mode);
|
| SetUseProgram(program->program());
|
| GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
|
|
|
| @@ -1263,9 +1141,13 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| shader_alpha_location = program->fragment_shader().alpha_location();
|
| shader_tex_transform_location =
|
| program->vertex_shader().tex_transform_location();
|
| + shader_backdrop_location = program->fragment_shader().backdrop_location();
|
| + shader_backdrop_rect_location =
|
| + program->fragment_shader().backdrop_rect_location();
|
| } else if (use_aa && mask_texture_id && use_color_matrix) {
|
| const RenderPassMaskColorMatrixProgramAA* program =
|
| - GetRenderPassMaskColorMatrixProgramAA(tex_coord_precision);
|
| + GetRenderPassMaskColorMatrixProgramAA(tex_coord_precision,
|
| + shader_blend_mode);
|
| SetUseProgram(program->program());
|
| GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
|
|
|
| @@ -1286,9 +1168,13 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| program->fragment_shader().color_matrix_location();
|
| shader_color_offset_location =
|
| program->fragment_shader().color_offset_location();
|
| + shader_backdrop_location = program->fragment_shader().backdrop_location();
|
| + shader_backdrop_rect_location =
|
| + program->fragment_shader().backdrop_rect_location();
|
| } else if (use_aa && !mask_texture_id && use_color_matrix) {
|
| const RenderPassColorMatrixProgramAA* program =
|
| - GetRenderPassColorMatrixProgramAA(tex_coord_precision);
|
| + GetRenderPassColorMatrixProgramAA(tex_coord_precision,
|
| + shader_blend_mode);
|
| SetUseProgram(program->program());
|
| GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
|
|
|
| @@ -1303,9 +1189,13 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| program->fragment_shader().color_matrix_location();
|
| shader_color_offset_location =
|
| program->fragment_shader().color_offset_location();
|
| + shader_backdrop_location = program->fragment_shader().backdrop_location();
|
| + shader_backdrop_rect_location =
|
| + program->fragment_shader().backdrop_rect_location();
|
| } else if (!use_aa && mask_texture_id && use_color_matrix) {
|
| const RenderPassMaskColorMatrixProgram* program =
|
| - GetRenderPassMaskColorMatrixProgram(tex_coord_precision);
|
| + GetRenderPassMaskColorMatrixProgram(tex_coord_precision,
|
| + shader_blend_mode);
|
| SetUseProgram(program->program());
|
| GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
|
|
|
| @@ -1323,9 +1213,12 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| program->fragment_shader().color_matrix_location();
|
| shader_color_offset_location =
|
| program->fragment_shader().color_offset_location();
|
| + shader_backdrop_location = program->fragment_shader().backdrop_location();
|
| + shader_backdrop_rect_location =
|
| + program->fragment_shader().backdrop_rect_location();
|
| } else if (!use_aa && !mask_texture_id && use_color_matrix) {
|
| const RenderPassColorMatrixProgram* program =
|
| - GetRenderPassColorMatrixProgram(tex_coord_precision);
|
| + GetRenderPassColorMatrixProgram(tex_coord_precision, shader_blend_mode);
|
| SetUseProgram(program->program());
|
| GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
|
|
|
| @@ -1337,9 +1230,12 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| program->fragment_shader().color_matrix_location();
|
| shader_color_offset_location =
|
| program->fragment_shader().color_offset_location();
|
| + shader_backdrop_location = program->fragment_shader().backdrop_location();
|
| + shader_backdrop_rect_location =
|
| + program->fragment_shader().backdrop_rect_location();
|
| } else {
|
| const RenderPassProgram* program =
|
| - GetRenderPassProgram(tex_coord_precision);
|
| + GetRenderPassProgram(tex_coord_precision, shader_blend_mode);
|
| SetUseProgram(program->program());
|
| GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
|
|
|
| @@ -1347,6 +1243,9 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| shader_alpha_location = program->fragment_shader().alpha_location();
|
| shader_tex_transform_location =
|
| program->vertex_shader().tex_transform_location();
|
| + shader_backdrop_location = program->fragment_shader().backdrop_location();
|
| + shader_backdrop_rect_location =
|
| + program->fragment_shader().backdrop_rect_location();
|
| }
|
| float tex_scale_x =
|
| quad->rect.width() / static_cast<float>(contents_texture->size().width());
|
| @@ -1366,6 +1265,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| tex_scale_x,
|
| -tex_scale_y));
|
|
|
| + GLint last_texture_unit = 0;
|
| scoped_ptr<ResourceProvider::ScopedSamplerGL> shader_mask_sampler_lock;
|
| if (shader_mask_sampler_location != -1) {
|
| DCHECK_NE(shader_mask_tex_coord_scale_location, 1);
|
| @@ -1393,6 +1293,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| GL_LINEAR));
|
| DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
|
| shader_mask_sampler_lock->target());
|
| + last_texture_unit = 1;
|
| }
|
|
|
| if (shader_edge_location != -1) {
|
| @@ -1428,6 +1329,37 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| GLC(gl_, gl_->Uniform4fv(shader_color_offset_location, 1, offset));
|
| }
|
|
|
| + scoped_ptr<ResourceProvider::ScopedSamplerGL> shader_background_sampler_lock;
|
| + if (shader_backdrop_location != -1) {
|
| + DCHECK(background_texture || background_image);
|
| + DCHECK_NE(shader_backdrop_location, 0);
|
| + DCHECK_NE(shader_backdrop_rect_location, 0);
|
| +
|
| + GLC(gl_, gl_->Uniform1i(shader_backdrop_location, ++last_texture_unit));
|
| +
|
| + GLC(gl_,
|
| + gl_->Uniform4f(shader_backdrop_rect_location,
|
| + background_rect.x(),
|
| + background_rect.y(),
|
| + background_rect.width(),
|
| + background_rect.height()));
|
| +
|
| + if (background_image) {
|
| + GrTexture* texture = background_image->getTexture();
|
| + GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0 + last_texture_unit));
|
| + gl_->BindTexture(GL_TEXTURE_2D, texture->getTextureHandle());
|
| + GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0));
|
| + } else {
|
| + shader_background_sampler_lock = make_scoped_ptr(
|
| + new ResourceProvider::ScopedSamplerGL(resource_provider_,
|
| + background_texture->id(),
|
| + GL_TEXTURE0 + last_texture_unit,
|
| + GL_LINEAR));
|
| + DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
|
| + shader_background_sampler_lock->target());
|
| + }
|
| + }
|
| +
|
| // Map device space quad to surface space. contents_device_transform has no 3d
|
| // component since it was flattened, so we don't need to project.
|
| gfx::QuadF surface_quad = MathUtil::MapQuad(contents_device_transform_inverse,
|
| @@ -2363,7 +2295,8 @@ void GLRenderer::CopyTextureToFramebuffer(const DrawingFrame* frame,
|
| TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
|
| gl_, &highp_threshold_cache_, highp_threshold_min_, rect.bottom_right());
|
|
|
| - const RenderPassProgram* program = GetRenderPassProgram(tex_coord_precision);
|
| + const RenderPassProgram* program =
|
| + GetRenderPassProgram(tex_coord_precision, kDefaultBlendMode);
|
| SetUseProgram(program->program());
|
|
|
| GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
|
| @@ -2842,112 +2775,145 @@ const GLRenderer::SolidColorProgramAA* GLRenderer::GetSolidColorProgramAA() {
|
| }
|
|
|
| const GLRenderer::RenderPassProgram* GLRenderer::GetRenderPassProgram(
|
| - TexCoordPrecision precision) {
|
| + TexCoordPrecision precision,
|
| + SkXfermode::Mode blend_mode) {
|
| DCHECK_GE(precision, 0);
|
| DCHECK_LT(precision, NumTexCoordPrecisions);
|
| - RenderPassProgram* program = &render_pass_program_[precision];
|
| + int bm = index_for_blend_mode(blend_mode);
|
| + RenderPassProgram* program = &render_pass_program_[precision][bm];
|
| if (!program->initialized()) {
|
| TRACE_EVENT0("cc", "GLRenderer::renderPassProgram::initialize");
|
| - program->Initialize(
|
| - output_surface_->context_provider(), precision, SamplerType2D);
|
| + program->Initialize(output_surface_->context_provider(),
|
| + precision,
|
| + SamplerType2D,
|
| + blend_mode);
|
| }
|
| return program;
|
| }
|
|
|
| const GLRenderer::RenderPassProgramAA* GLRenderer::GetRenderPassProgramAA(
|
| - TexCoordPrecision precision) {
|
| + TexCoordPrecision precision,
|
| + SkXfermode::Mode blend_mode) {
|
| DCHECK_GE(precision, 0);
|
| DCHECK_LT(precision, NumTexCoordPrecisions);
|
| - RenderPassProgramAA* program = &render_pass_program_aa_[precision];
|
| + int bm = index_for_blend_mode(blend_mode);
|
| + RenderPassProgramAA* program = &render_pass_program_aa_[precision][bm];
|
| if (!program->initialized()) {
|
| TRACE_EVENT0("cc", "GLRenderer::renderPassProgramAA::initialize");
|
| - program->Initialize(
|
| - output_surface_->context_provider(), precision, SamplerType2D);
|
| + program->Initialize(output_surface_->context_provider(),
|
| + precision,
|
| + SamplerType2D,
|
| + blend_mode);
|
| }
|
| return program;
|
| }
|
|
|
| const GLRenderer::RenderPassMaskProgram* GLRenderer::GetRenderPassMaskProgram(
|
| - TexCoordPrecision precision) {
|
| + TexCoordPrecision precision,
|
| + SkXfermode::Mode blend_mode) {
|
| DCHECK_GE(precision, 0);
|
| DCHECK_LT(precision, NumTexCoordPrecisions);
|
| - RenderPassMaskProgram* program = &render_pass_mask_program_[precision];
|
| + int bm = index_for_blend_mode(blend_mode);
|
| + RenderPassMaskProgram* program = &render_pass_mask_program_[precision][bm];
|
| if (!program->initialized()) {
|
| TRACE_EVENT0("cc", "GLRenderer::renderPassMaskProgram::initialize");
|
| - program->Initialize(
|
| - output_surface_->context_provider(), precision, SamplerType2D);
|
| + program->Initialize(output_surface_->context_provider(),
|
| + precision,
|
| + SamplerType2D,
|
| + blend_mode);
|
| }
|
| return program;
|
| }
|
|
|
| const GLRenderer::RenderPassMaskProgramAA*
|
| -GLRenderer::GetRenderPassMaskProgramAA(TexCoordPrecision precision) {
|
| +GLRenderer::GetRenderPassMaskProgramAA(TexCoordPrecision precision,
|
| + SkXfermode::Mode blend_mode) {
|
| DCHECK_GE(precision, 0);
|
| DCHECK_LT(precision, NumTexCoordPrecisions);
|
| - RenderPassMaskProgramAA* program = &render_pass_mask_program_aa_[precision];
|
| + int bm = index_for_blend_mode(blend_mode);
|
| + RenderPassMaskProgramAA* program =
|
| + &render_pass_mask_program_aa_[precision][bm];
|
| if (!program->initialized()) {
|
| TRACE_EVENT0("cc", "GLRenderer::renderPassMaskProgramAA::initialize");
|
| - program->Initialize(
|
| - output_surface_->context_provider(), precision, SamplerType2D);
|
| + program->Initialize(output_surface_->context_provider(),
|
| + precision,
|
| + SamplerType2D,
|
| + blend_mode);
|
| }
|
| return program;
|
| }
|
|
|
| const GLRenderer::RenderPassColorMatrixProgram*
|
| -GLRenderer::GetRenderPassColorMatrixProgram(TexCoordPrecision precision) {
|
| +GLRenderer::GetRenderPassColorMatrixProgram(TexCoordPrecision precision,
|
| + SkXfermode::Mode blend_mode) {
|
| DCHECK_GE(precision, 0);
|
| DCHECK_LT(precision, NumTexCoordPrecisions);
|
| + int bm = index_for_blend_mode(blend_mode);
|
| RenderPassColorMatrixProgram* program =
|
| - &render_pass_color_matrix_program_[precision];
|
| + &render_pass_color_matrix_program_[precision][bm];
|
| if (!program->initialized()) {
|
| TRACE_EVENT0("cc", "GLRenderer::renderPassColorMatrixProgram::initialize");
|
| - program->Initialize(
|
| - output_surface_->context_provider(), precision, SamplerType2D);
|
| + program->Initialize(output_surface_->context_provider(),
|
| + precision,
|
| + SamplerType2D,
|
| + blend_mode);
|
| }
|
| return program;
|
| }
|
|
|
| const GLRenderer::RenderPassColorMatrixProgramAA*
|
| -GLRenderer::GetRenderPassColorMatrixProgramAA(TexCoordPrecision precision) {
|
| +GLRenderer::GetRenderPassColorMatrixProgramAA(TexCoordPrecision precision,
|
| + SkXfermode::Mode blend_mode) {
|
| DCHECK_GE(precision, 0);
|
| DCHECK_LT(precision, NumTexCoordPrecisions);
|
| + int bm = index_for_blend_mode(blend_mode);
|
| RenderPassColorMatrixProgramAA* program =
|
| - &render_pass_color_matrix_program_aa_[precision];
|
| + &render_pass_color_matrix_program_aa_[precision][bm];
|
| if (!program->initialized()) {
|
| TRACE_EVENT0("cc",
|
| "GLRenderer::renderPassColorMatrixProgramAA::initialize");
|
| - program->Initialize(
|
| - output_surface_->context_provider(), precision, SamplerType2D);
|
| + program->Initialize(output_surface_->context_provider(),
|
| + precision,
|
| + SamplerType2D,
|
| + blend_mode);
|
| }
|
| return program;
|
| }
|
|
|
| const GLRenderer::RenderPassMaskColorMatrixProgram*
|
| -GLRenderer::GetRenderPassMaskColorMatrixProgram(TexCoordPrecision precision) {
|
| +GLRenderer::GetRenderPassMaskColorMatrixProgram(TexCoordPrecision precision,
|
| + SkXfermode::Mode blend_mode) {
|
| DCHECK_GE(precision, 0);
|
| DCHECK_LT(precision, NumTexCoordPrecisions);
|
| + int bm = index_for_blend_mode(blend_mode);
|
| RenderPassMaskColorMatrixProgram* program =
|
| - &render_pass_mask_color_matrix_program_[precision];
|
| + &render_pass_mask_color_matrix_program_[precision][bm];
|
| if (!program->initialized()) {
|
| TRACE_EVENT0("cc",
|
| "GLRenderer::renderPassMaskColorMatrixProgram::initialize");
|
| - program->Initialize(
|
| - output_surface_->context_provider(), precision, SamplerType2D);
|
| + program->Initialize(output_surface_->context_provider(),
|
| + precision,
|
| + SamplerType2D,
|
| + blend_mode);
|
| }
|
| return program;
|
| }
|
|
|
| const GLRenderer::RenderPassMaskColorMatrixProgramAA*
|
| -GLRenderer::GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision) {
|
| +GLRenderer::GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision,
|
| + SkXfermode::Mode blend_mode) {
|
| DCHECK_GE(precision, 0);
|
| DCHECK_LT(precision, NumTexCoordPrecisions);
|
| + int bm = index_for_blend_mode(blend_mode);
|
| RenderPassMaskColorMatrixProgramAA* program =
|
| - &render_pass_mask_color_matrix_program_aa_[precision];
|
| + &render_pass_mask_color_matrix_program_aa_[precision][bm];
|
| if (!program->initialized()) {
|
| TRACE_EVENT0("cc",
|
| "GLRenderer::renderPassMaskColorMatrixProgramAA::initialize");
|
| - program->Initialize(
|
| - output_surface_->context_provider(), precision, SamplerType2D);
|
| + program->Initialize(output_surface_->context_provider(),
|
| + precision,
|
| + SamplerType2D,
|
| + blend_mode);
|
| }
|
| return program;
|
| }
|
| @@ -3173,15 +3139,16 @@ void GLRenderer::CleanupSharedObjects() {
|
| tile_program_aa_[i][j].Cleanup(gl_);
|
| tile_program_swizzle_aa_[i][j].Cleanup(gl_);
|
| }
|
| -
|
| - render_pass_mask_program_[i].Cleanup(gl_);
|
| - render_pass_program_[i].Cleanup(gl_);
|
| - render_pass_mask_program_aa_[i].Cleanup(gl_);
|
| - render_pass_program_aa_[i].Cleanup(gl_);
|
| - render_pass_color_matrix_program_[i].Cleanup(gl_);
|
| - render_pass_mask_color_matrix_program_aa_[i].Cleanup(gl_);
|
| - render_pass_color_matrix_program_aa_[i].Cleanup(gl_);
|
| - render_pass_mask_color_matrix_program_[i].Cleanup(gl_);
|
| + for (int j = 0; j < kNumBlendModes; j++) {
|
| + render_pass_mask_program_[i][j].Cleanup(gl_);
|
| + render_pass_program_[i][j].Cleanup(gl_);
|
| + render_pass_mask_program_aa_[i][j].Cleanup(gl_);
|
| + render_pass_program_aa_[i][j].Cleanup(gl_);
|
| + render_pass_color_matrix_program_[i][j].Cleanup(gl_);
|
| + render_pass_mask_color_matrix_program_aa_[i][j].Cleanup(gl_);
|
| + render_pass_color_matrix_program_aa_[i][j].Cleanup(gl_);
|
| + render_pass_mask_color_matrix_program_[i][j].Cleanup(gl_);
|
| + }
|
|
|
| texture_program_[i].Cleanup(gl_);
|
| nonpremultiplied_texture_program_[i].Cleanup(gl_);
|
|
|