Chromium Code Reviews| Index: cc/output/gl_renderer.cc |
| diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc |
| index 7cf5a00face44d5bfa4fdf49f6e805ae4d5b209c..9b954eb1fadabcbdbbd87bbc0a8ef2e9b70dde3f 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 flip_texture) { |
| // Wrap a given texture in a Ganesh platform texture. |
| GrBackendTextureDesc backend_texture_description; |
| GrGLTextureInfo texture_info; |
| @@ -600,7 +601,8 @@ 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 = |
| + flip_texture ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin; |
| return SkImage::MakeFromTexture(context, backend_texture_description); |
| } |
| @@ -612,16 +614,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 flip_texture) { |
| 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(), flip_texture); |
| + |
| if (!src_image) { |
| TRACE_EVENT_INSTANT0("cc", |
| "ApplyImageFilter wrap background texture failed", |
| @@ -852,7 +857,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 flip_texture = true; |
| + sk_sp<SkImage> src_image = |
| + WrapTexture(lock, use_gr_context->context(), flip_texture); |
| if (!src_image) { |
| TRACE_EVENT_INSTANT0( |
| "cc", "ApplyBackgroundFilters wrap background texture failed", |
| @@ -910,14 +917,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 flip_texture = false; |
|
ericrk
2016/06/07 20:23:17
Can you add a comment explaining why this is not f
enne (OOO)
2016/06/07 21:22:44
Done.
|
| + DrawRenderPassQuadInternal(frame, quad, clip_region, &tile_resource, |
| + flip_texture); |
| + } else { |
| + ScopedResource* contents_texture = |
| + render_pass_textures_[quad->render_pass_id].get(); |
| + DCHECK(contents_texture); |
| + DCHECK(contents_texture->id()); |
| + bool flip_texture = true; |
| + DrawRenderPassQuadInternal(frame, quad, clip_region, contents_texture, |
| + flip_texture); |
| + } |
| +} |
| +void GLRenderer::DrawRenderPassQuadInternal(DrawingFrame* frame, |
| + const RenderPassDrawQuad* quad, |
| + const gfx::QuadF* clip_region, |
| + const Resource* contents_texture, |
| + bool flip_texture) { |
| 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 +1087,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 +1121,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, flip_texture); |
| + if (!filter_image) |
| return; |
| - } |
| filter_image_id = skia::GrBackendObjectToGrGLTextureInfo( |
| filter_image->getTextureHandle(true)) |
| ->fID; |
| @@ -1074,6 +1137,7 @@ 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()); |
| + // If the output of the filter needs to be flipped. |
| flip_texture = |
| filter_image->getTexture()->origin() == kBottomLeft_GrSurfaceOrigin; |
| } |
| @@ -1199,6 +1263,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
| 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 +1280,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 (flip_texture) { |
| + // 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; |
| } |