Index: cc/output/gl_renderer.cc |
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc |
index 7cf5a00face44d5bfa4fdf49f6e805ae4d5b209c..0800eb6051a62dacb1afeb23c60a436e38560112 100644 |
--- a/cc/output/gl_renderer.cc |
+++ b/cc/output/gl_renderer.cc |
@@ -589,7 +589,8 @@ void GLRenderer::DrawDebugBorderQuad(const DrawingFrame* frame, |
static sk_sp<SkImage> WrapTexture( |
const ResourceProvider::ScopedReadLockGL& lock, |
- GrContext* context) { |
+ GrContext* context, |
+ bool is_render_pass_input) { |
// Wrap a given texture in a Ganesh platform texture. |
GrBackendTextureDesc backend_texture_description; |
GrGLTextureInfo texture_info; |
@@ -600,7 +601,9 @@ static sk_sp<SkImage> WrapTexture( |
backend_texture_description.fConfig = kSkia8888_GrPixelConfig; |
backend_texture_description.fTextureHandle = |
skia::GrGLTextureInfoToGrBackendObject(texture_info); |
- backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin; |
+ backend_texture_description.fOrigin = is_render_pass_input |
+ ? kBottomLeft_GrSurfaceOrigin |
+ : kTopLeft_GrSurfaceOrigin; |
return SkImage::MakeFromTexture(context, backend_texture_description); |
} |
@@ -612,16 +615,19 @@ static sk_sp<SkImage> ApplyImageFilter( |
const gfx::RectF& dst_rect, |
const gfx::Vector2dF& scale, |
sk_sp<SkImageFilter> filter, |
- ScopedResource* source_texture_resource, |
+ const Resource* source_texture_resource, |
SkIPoint* offset, |
- SkIRect* subset) { |
+ SkIRect* subset, |
+ bool is_render_pass_input) { |
if (!filter || !use_gr_context) |
return nullptr; |
ResourceProvider::ScopedReadLockGL lock(resource_provider, |
source_texture_resource->id()); |
- sk_sp<SkImage> src_image = WrapTexture(lock, use_gr_context->context()); |
+ sk_sp<SkImage> src_image = |
+ WrapTexture(lock, use_gr_context->context(), is_render_pass_input); |
+ |
if (!src_image) { |
TRACE_EVENT_INSTANT0("cc", |
"ApplyImageFilter wrap background texture failed", |
@@ -852,7 +858,9 @@ sk_sp<SkImage> GLRenderer::ApplyBackgroundFilters( |
ResourceProvider::ScopedReadLockGL lock(resource_provider_, |
background_texture->id()); |
- sk_sp<SkImage> src_image = WrapTexture(lock, use_gr_context->context()); |
+ bool is_render_pass_input = true; |
+ sk_sp<SkImage> src_image = |
+ WrapTexture(lock, use_gr_context->context(), is_render_pass_input); |
if (!src_image) { |
TRACE_EVENT_INSTANT0( |
"cc", "ApplyBackgroundFilters wrap background texture failed", |
@@ -910,14 +918,72 @@ gfx::QuadF MapQuadToLocalSpace(const gfx::Transform& device_transform, |
return local_quad; |
} |
+const TileDrawQuad* GLRenderer::CanPassBeDrawnDirectly(const RenderPass* pass) { |
+ // Can only collapse a single tile quad. |
+ if (pass->quad_list.size() != 1) |
+ return nullptr; |
+ // If we need copy requests, then render pass has to exist. |
+ if (!pass->copy_requests.empty()) |
+ return nullptr; |
+ |
+ const DrawQuad* quad = *pass->quad_list.BackToFrontBegin(); |
+ // Hack: this could be supported by concatenating transforms, but |
+ // in practice if there is one quad, it is at the origin of the render pass. |
+ if (!quad->shared_quad_state->quad_to_target_transform.IsIdentity()) |
+ return nullptr; |
+ // The quad is expected to be the entire layer so that AA edges are correct. |
+ if (gfx::Rect(quad->shared_quad_state->quad_layer_bounds) != quad->rect) |
+ return nullptr; |
+ if (quad->material != DrawQuad::TILED_CONTENT) |
+ return nullptr; |
+ |
+ const TileDrawQuad* tile_quad = TileDrawQuad::MaterialCast(quad); |
+ // Hack: this could be supported by passing in a subrectangle to draw |
+ // render pass, although in practice if there is only one quad there |
+ // will be no border texels on the input. |
+ if (tile_quad->tex_coord_rect != gfx::RectF(tile_quad->rect)) |
+ return nullptr; |
+ // Tile quad features not supported in render pass shaders. |
+ if (tile_quad->swizzle_contents || tile_quad->nearest_neighbor) |
+ return nullptr; |
+ // BUG=skia:3868, Skia currently doesn't support texture rectangle inputs. |
+ // See also the DCHECKs about GL_TEXTURE_2D in DrawRenderPassQuad. |
+ GLenum target = |
+ resource_provider_->GetResourceTextureTarget(tile_quad->resource_id()); |
+ if (target != GL_TEXTURE_2D) |
+ return nullptr; |
+ |
+ return tile_quad; |
+} |
+ |
void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
const RenderPassDrawQuad* quad, |
const gfx::QuadF* clip_region) { |
- ScopedResource* contents_texture = |
- render_pass_textures_[quad->render_pass_id].get(); |
- DCHECK(contents_texture); |
- DCHECK(contents_texture->id()); |
+ auto bypass = render_pass_bypass_quads_.find(quad->render_pass_id); |
+ if (bypass != render_pass_bypass_quads_.end()) { |
+ TileDrawQuad* tile_quad = &bypass->second; |
+ // TODO(enne): format here doesn't appear to get used. |
+ Resource tile_resource(tile_quad->resource_id(), tile_quad->texture_size, |
+ ResourceFormat::RGBA_8888); |
+ bool is_render_pass_input = false; |
+ DrawRenderPassQuadInternal(frame, quad, clip_region, &tile_resource, |
+ is_render_pass_input); |
+ } else { |
+ ScopedResource* contents_texture = |
+ render_pass_textures_[quad->render_pass_id].get(); |
+ DCHECK(contents_texture); |
+ DCHECK(contents_texture->id()); |
+ bool is_render_pass_input = true; |
+ DrawRenderPassQuadInternal(frame, quad, clip_region, contents_texture, |
+ is_render_pass_input); |
+ } |
+} |
+void GLRenderer::DrawRenderPassQuadInternal(DrawingFrame* frame, |
+ const RenderPassDrawQuad* quad, |
+ const gfx::QuadF* clip_region, |
+ const Resource* contents_texture, |
+ bool is_render_pass_input) { |
SkMatrix scale_matrix; |
scale_matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y()); |
gfx::RectF dst_rect(quad->filters.MapRect(quad->rect, scale_matrix)); |
@@ -1022,7 +1088,6 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
SkScalar color_matrix[20]; |
bool use_color_matrix = false; |
gfx::Size texture_size = contents_texture->size(); |
- bool flip_texture = true; |
gfx::Point src_offset; |
if (!quad->filters.IsEmpty()) { |
sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( |
@@ -1057,13 +1122,12 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
SkIPoint offset; |
SkIRect subset; |
gfx::RectF src_rect(quad->rect); |
- filter_image = ApplyImageFilter(ScopedUseGrContext::Create(this, frame), |
- resource_provider_, src_rect, dst_rect, |
- quad->filters_scale, std::move(filter), |
- contents_texture, &offset, &subset); |
- if (!filter_image) { |
+ filter_image = ApplyImageFilter( |
+ ScopedUseGrContext::Create(this, frame), resource_provider_, |
+ src_rect, dst_rect, quad->filters_scale, std::move(filter), |
+ contents_texture, &offset, &subset, is_render_pass_input); |
+ if (!filter_image) |
return; |
- } |
filter_image_id = skia::GrBackendObjectToGrGLTextureInfo( |
filter_image->getTextureHandle(true)) |
->fID; |
@@ -1074,7 +1138,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
gfx::RectF(src_rect.x() + offset.fX, src_rect.y() + offset.fY, |
subset.width(), subset.height()); |
src_offset.SetPoint(subset.x(), subset.y()); |
- flip_texture = |
+ // If the output of the filter needs to be flipped. |
+ is_render_pass_input = |
Stephen White
2016/06/03 19:30:15
<bikeshed> At this point, it's not really true tha
enne (OOO)
2016/06/03 20:40:22
Haha, yeah sure. I had named it differently befor
|
filter_image->getTexture()->origin() == kBottomLeft_GrSurfaceOrigin; |
} |
} |
@@ -1192,13 +1257,15 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
tex_rect.Scale(1.0f / texture_size.width(), 1.0f / texture_size.height()); |
DCHECK(locations.tex_transform != -1 || IsContextLost()); |
- if (flip_texture) { |
+ if (is_render_pass_input) { |
// Flip the content vertically in the shader, as the RenderPass input |
// texture is already oriented the same way as the framebuffer, but the |
// projection transform does a flip. |
gl_->Uniform4f(locations.tex_transform, tex_rect.x(), 1.0f - tex_rect.y(), |
tex_rect.width(), -tex_rect.height()); |
} else { |
+ // Tile textures are oriented opposite the framebuffer, so can use |
+ // the projection transform to do the flip. |
gl_->Uniform4f(locations.tex_transform, tex_rect.x(), tex_rect.y(), |
tex_rect.width(), tex_rect.height()); |
} |
@@ -1214,16 +1281,24 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
mask_uv_rect.Scale(quad->mask_texture_size.width(), |
quad->mask_texture_size.height()); |
} |
- |
- // Mask textures are oriented vertically flipped relative to the framebuffer |
- // and the RenderPass contents texture, so we flip the tex coords from the |
- // RenderPass texture to find the mask texture coords. |
- gl_->Uniform2f( |
- locations.mask_tex_coord_offset, mask_uv_rect.x(), |
- mask_uv_rect.height() / tex_rect.height() + mask_uv_rect.y()); |
- gl_->Uniform2f(locations.mask_tex_coord_scale, |
- mask_uv_rect.width() / tex_rect.width(), |
- -mask_uv_rect.height() / tex_rect.height()); |
+ if (is_render_pass_input) { |
+ // Mask textures are oriented vertically flipped relative to the |
+ // framebuffer and the RenderPass contents texture, so we flip the tex |
+ // coords from the RenderPass texture to find the mask texture coords. |
+ gl_->Uniform2f( |
+ locations.mask_tex_coord_offset, mask_uv_rect.x(), |
+ mask_uv_rect.height() / tex_rect.height() + mask_uv_rect.y()); |
+ gl_->Uniform2f(locations.mask_tex_coord_scale, |
+ mask_uv_rect.width() / tex_rect.width(), |
+ -mask_uv_rect.height() / tex_rect.height()); |
+ } else { |
+ // Tile textures are oriented the same way as mask textures. |
+ gl_->Uniform2f(locations.mask_tex_coord_offset, mask_uv_rect.x(), |
+ mask_uv_rect.y()); |
+ gl_->Uniform2f(locations.mask_tex_coord_scale, |
+ mask_uv_rect.width() / tex_rect.width(), |
+ mask_uv_rect.height() / tex_rect.height()); |
+ } |
last_texture_unit = 1; |
} |