Commit f0157aa2 authored by Mason Freed's avatar Mason Freed Committed by Commit Bot

Fall back to CopyTextureCHROMIUM for GL_TEXTURE_RECTANGLE masks

In some cases, ScopedReadLockSkImage is not able to read back the
texture, because it does not know the hardware supports texture
rectangles. In that case, fall back to using CopyTextureCHROMIUM
to copy the mask texture into an SkImage.

Bug: 984766
Change-Id: I0a348a98767405f61810b03217ef96bb2b5bba2c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1730291Reviewed-by: default avatarEric Karl <ericrk@chromium.org>
Commit-Queue: Mason Freed <masonfreed@chromium.org>
Auto-Submit: Mason Freed <masonfreed@chromium.org>
Cr-Commit-Position: refs/heads/master@{#683771}
parent 98e9f7c5
...@@ -253,8 +253,12 @@ GLenum DisplayResourceProvider::GetResourceTextureTarget(ResourceId id) { ...@@ -253,8 +253,12 @@ GLenum DisplayResourceProvider::GetResourceTextureTarget(ResourceId id) {
} }
gfx::BufferFormat DisplayResourceProvider::GetBufferFormat(ResourceId id) { gfx::BufferFormat DisplayResourceProvider::GetBufferFormat(ResourceId id) {
return BufferFormat(GetResourceFormat(id));
}
ResourceFormat DisplayResourceProvider::GetResourceFormat(ResourceId id) {
ChildResource* resource = GetResource(id); ChildResource* resource = GetResource(id);
return BufferFormat(resource->transferable.format); return resource->transferable.format;
} }
const gfx::ColorSpace& DisplayResourceProvider::GetColorSpace(ResourceId id) { const gfx::ColorSpace& DisplayResourceProvider::GetColorSpace(ResourceId id) {
......
...@@ -113,6 +113,7 @@ class VIZ_SERVICE_EXPORT DisplayResourceProvider ...@@ -113,6 +113,7 @@ class VIZ_SERVICE_EXPORT DisplayResourceProvider
GLenum GetResourceTextureTarget(ResourceId id); GLenum GetResourceTextureTarget(ResourceId id);
// Return the format of the underlying buffer that can be used for scanout. // Return the format of the underlying buffer that can be used for scanout.
gfx::BufferFormat GetBufferFormat(ResourceId id); gfx::BufferFormat GetBufferFormat(ResourceId id);
ResourceFormat GetResourceFormat(ResourceId id);
const gfx::ColorSpace& GetColorSpace(ResourceId id); const gfx::ColorSpace& GetColorSpace(ResourceId id);
// Indicates if this resource may be used for a hardware overlay plane. // Indicates if this resource may be used for a hardware overlay plane.
bool IsOverlayCandidate(ResourceId id); bool IsOverlayCandidate(ResourceId id);
...@@ -182,6 +183,7 @@ class VIZ_SERVICE_EXPORT DisplayResourceProvider ...@@ -182,6 +183,7 @@ class VIZ_SERVICE_EXPORT DisplayResourceProvider
~ScopedReadLockSkImage(); ~ScopedReadLockSkImage();
const SkImage* sk_image() const { return sk_image_.get(); } const SkImage* sk_image() const { return sk_image_.get(); }
sk_sp<SkImage> TakeSkImage() { return std::move(sk_image_); }
bool valid() const { return !!sk_image_; } bool valid() const { return !!sk_image_; }
......
...@@ -594,28 +594,32 @@ static SkColorType GlFormatToSkFormat(GrGLenum format) { ...@@ -594,28 +594,32 @@ static SkColorType GlFormatToSkFormat(GrGLenum format) {
} }
} }
// Wrap a given texture in a Ganesh backend texture. static GrGLenum SkFormatToGlFormat(SkColorType format) {
static sk_sp<SkImage> WrapTexture(uint32_t texture_id,
uint32_t target,
const gfx::Size& size,
GrContext* context,
bool flip_texture,
SkColorType format) {
GrGLenum texture_format(GL_RGBA8_OES);
switch (format) { switch (format) {
case kRGB_888x_SkColorType: case kRGB_888x_SkColorType:
texture_format = GL_RGB8_OES; return GL_RGB8_OES;
break; break;
case kRGBA_8888_SkColorType: case kRGBA_8888_SkColorType:
texture_format = GL_RGBA8_OES; return GL_RGBA8_OES;
break; break;
case kBGRA_8888_SkColorType: case kBGRA_8888_SkColorType:
texture_format = GL_BGRA8_EXT; return GL_BGRA8_EXT;
break; break;
default: default:
NOTREACHED(); NOTREACHED();
return GL_RGBA8_OES;
} }
}
// Wrap a given texture in a Ganesh backend texture.
static sk_sp<SkImage> WrapTexture(uint32_t texture_id,
uint32_t target,
const gfx::Size& size,
GrContext* context,
bool flip_texture,
SkColorType format,
bool adopt_texture) {
GrGLenum texture_format = SkFormatToGlFormat(format);
GrGLTextureInfo texture_info; GrGLTextureInfo texture_info;
texture_info.fTarget = target; texture_info.fTarget = target;
texture_info.fID = texture_id; texture_info.fID = texture_id;
...@@ -624,8 +628,13 @@ static sk_sp<SkImage> WrapTexture(uint32_t texture_id, ...@@ -624,8 +628,13 @@ static sk_sp<SkImage> WrapTexture(uint32_t texture_id,
GrMipMapped::kNo, texture_info); GrMipMapped::kNo, texture_info);
GrSurfaceOrigin origin = GrSurfaceOrigin origin =
flip_texture ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin; flip_texture ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
return SkImage::MakeFromTexture(context, backend_texture, origin, format, if (adopt_texture) {
kPremul_SkAlphaType, nullptr); return SkImage::MakeFromAdoptedTexture(
context, backend_texture, origin, format, kPremul_SkAlphaType, nullptr);
} else {
return SkImage::MakeFromTexture(context, backend_texture, origin, format,
kPremul_SkAlphaType, nullptr);
}
} }
static gfx::RectF CenteredRect(const gfx::Rect& tile_rect) { static gfx::RectF CenteredRect(const gfx::Rect& tile_rect) {
...@@ -887,12 +896,11 @@ sk_sp<SkImage> GLRenderer::ApplyBackdropFilters( ...@@ -887,12 +896,11 @@ sk_sp<SkImage> GLRenderer::ApplyBackdropFilters(
return nullptr; return nullptr;
auto filter = paint_filter->cached_sk_filter_; auto filter = paint_filter->cached_sk_filter_;
bool flip_texture = true;
sk_sp<SkImage> src_image = WrapTexture( sk_sp<SkImage> src_image = WrapTexture(
params->background_texture, GL_TEXTURE_2D, params->background_rect.size(), params->background_texture, GL_TEXTURE_2D, params->background_rect.size(),
use_gr_context->context(), flip_texture, use_gr_context->context(), /*flip_texture=*/true,
GlFormatToSkFormat(params->background_texture_format)); GlFormatToSkFormat(params->background_texture_format),
/*adopt_texture=*/false);
if (!src_image) { if (!src_image) {
TRACE_EVENT_INSTANT0("cc", TRACE_EVENT_INSTANT0("cc",
"ApplyBackdropFilters wrap background texture failed", "ApplyBackdropFilters wrap background texture failed",
...@@ -976,13 +984,48 @@ sk_sp<SkImage> GLRenderer::ApplyBackdropFilters( ...@@ -976,13 +984,48 @@ sk_sp<SkImage> GLRenderer::ApplyBackdropFilters(
// 2. Render the parent render pass (containing the "backdrop image" to be // 2. Render the parent render pass (containing the "backdrop image" to be
// filtered). // filtered).
// 3. Run this code, to filter, and possibly mask, the backdrop image. // 3. Run this code, to filter, and possibly mask, the backdrop image.
const SkImage* mask_image = nullptr; sk_sp<const SkImage> mask_image = nullptr;
base::Optional<DisplayResourceProvider::ScopedReadLockSkImage> base::Optional<DisplayResourceProvider::ScopedReadLockSkImage>
backdrop_image_lock; backdrop_image_lock_sk;
base::Optional<DisplayResourceProvider::ScopedSamplerGL>
backdrop_image_lock_gl;
if (quad->mask_applies_to_backdrop && quad->mask_resource_id()) { if (quad->mask_applies_to_backdrop && quad->mask_resource_id()) {
backdrop_image_lock.emplace(resource_provider_, quad->mask_resource_id()); if (resource_provider_->GetResourceTextureTarget(
// TODO(984766): This will be null on Mac, so masks will not be applied. quad->mask_resource_id()) == GL_TEXTURE_RECTANGLE_ARB) {
mask_image = backdrop_image_lock->sk_image(); // On some platforms, Skia doesn't know that the hardware supports
// GL_TEXTURE_RECTANGLE. So for texture rectangles, fall back to using
// CopyTextureCHROMIUM to copy from the mask resource to a newly-created
// texture, and then wrap that texture with an SkImage.
backdrop_image_lock_gl.emplace(resource_provider_,
quad->mask_resource_id(), GL_LINEAR);
GLenum source_id = backdrop_image_lock_gl->texture_id();
GLint internalformat = GLInternalFormat(
resource_provider_->GetResourceFormat(quad->mask_resource_id()));
GLuint dest_id;
gl_->GenTextures(1, &dest_id);
gl_->BindTexture(GL_TEXTURE_2D, dest_id);
// Format is the same as internalformat for the formats being considered.
GLint format = internalformat;
gl_->TexImage2D(GL_TEXTURE_2D, 0, internalformat,
quad->mask_texture_size.width(),
quad->mask_texture_size.height(), 0, format,
GL_UNSIGNED_BYTE, nullptr);
gl_->CopyTextureCHROMIUM(source_id, 0, GL_TEXTURE_2D, dest_id, 0,
internalformat, GL_UNSIGNED_BYTE,
/*unpack_flip_y=*/false,
/*unpack_premultiply_alpha=*/false,
/*unpack_unmultiply_alpha=*/false);
mask_image = WrapTexture(dest_id, GL_TEXTURE_2D, quad->mask_texture_size,
use_gr_context->context(), false,
GlFormatToSkFormat(internalformat),
/*adopt_texture=*/true);
} else {
backdrop_image_lock_sk.emplace(
resource_provider_, quad->mask_resource_id(), kPremul_SkAlphaType,
kTopLeft_GrSurfaceOrigin);
mask_image = backdrop_image_lock_sk->TakeSkImage();
}
DCHECK(mask_image);
} }
if (mask_image) { if (mask_image) {
// Scale normalized uv rect into absolute texel coordinates. // Scale normalized uv rect into absolute texel coordinates.
...@@ -1288,7 +1331,7 @@ bool GLRenderer::UpdateRPDQWithSkiaFilters( ...@@ -1288,7 +1331,7 @@ bool GLRenderer::UpdateRPDQWithSkiaFilters(
sk_sp<SkImage> src_image = WrapTexture( sk_sp<SkImage> src_image = WrapTexture(
params->contents_texture->id(), GL_TEXTURE_2D, params->contents_texture->id(), GL_TEXTURE_2D,
params->contents_texture->size(), use_gr_context->context(), params->contents_texture->size(), use_gr_context->context(),
params->flip_texture, kN32_SkColorType); params->flip_texture, kN32_SkColorType, /*adopt_texture=*/false);
params->filter_image = SkiaHelper::ApplyImageFilter( params->filter_image = SkiaHelper::ApplyImageFilter(
use_gr_context->context(), src_image, src_rect, params->dst_rect, use_gr_context->context(), src_image, src_rect, params->dst_rect,
quad->filters_scale, std::move(filter), &offset, &subset, quad->filters_scale, std::move(filter), &offset, &subset,
...@@ -1304,7 +1347,7 @@ bool GLRenderer::UpdateRPDQWithSkiaFilters( ...@@ -1304,7 +1347,7 @@ bool GLRenderer::UpdateRPDQWithSkiaFilters(
prefilter_bypass_quad_texture_lock.target(), prefilter_bypass_quad_texture_lock.target(),
prefilter_bypass_quad_texture_lock.size(), prefilter_bypass_quad_texture_lock.size(),
use_gr_context->context(), params->flip_texture, use_gr_context->context(), params->flip_texture,
kN32_SkColorType); kN32_SkColorType, /*adopt_texture=*/false);
params->filter_image = SkiaHelper::ApplyImageFilter( params->filter_image = SkiaHelper::ApplyImageFilter(
use_gr_context->context(), src_image, src_rect, params->dst_rect, use_gr_context->context(), src_image, src_rect, params->dst_rect,
quad->filters_scale, std::move(filter), &offset, &subset, quad->filters_scale, std::move(filter), &offset, &subset,
......
...@@ -2984,13 +2984,6 @@ TYPED_TEST(RendererPixelTestWithBackdropFilter, InvertFilterWithMask) { ...@@ -2984,13 +2984,6 @@ TYPED_TEST(RendererPixelTestWithBackdropFilter, InvertFilterWithMask) {
const bool is_gl_renderer = const bool is_gl_renderer =
std::is_same<TypeParam, GLRenderer>() || std::is_same<TypeParam, GLRenderer>() ||
std::is_same<TypeParam, cc::GLRendererWithExpandedViewport>(); std::is_same<TypeParam, cc::GLRendererWithExpandedViewport>();
// TODO(984766): If the texture_rectangle feature is not available, then
// (currently) mask image readback will break for gl_renderer.
if (is_gl_renderer && !this->output_surface_->context_provider()
->ContextCapabilities()
.texture_rectangle) {
return;
}
// TODO(989312): The mask on gl_renderer and software_renderer appears to be // TODO(989312): The mask on gl_renderer and software_renderer appears to be
// offset from the correct location. // offset from the correct location.
const bool is_software_renderer = std::is_same<TypeParam, SoftwareRenderer>(); const bool is_software_renderer = std::is_same<TypeParam, SoftwareRenderer>();
......
...@@ -2258,8 +2258,6 @@ crbug.com/538697 [ Win Win10 ] virtual/threaded/printing/webgl-oversized-printin ...@@ -2258,8 +2258,6 @@ crbug.com/538697 [ Win Win10 ] virtual/threaded/printing/webgl-oversized-printin
crbug.com/538697 [ Win ] printing/webgl-oversized-printing.html [ Failure Crash ] crbug.com/538697 [ Win ] printing/webgl-oversized-printing.html [ Failure Crash ]
crbug.com/904592 css3/filters/backdrop-filter-svg.html [ Failure ] crbug.com/904592 css3/filters/backdrop-filter-svg.html [ Failure ]
crbug.com/984766 [ Mac ] css3/filters/backdrop-filter-plus-mask.html [ Failure ]
crbug.com/984766 [ Mac ] virtual/scalefactor200/css3/filters/backdrop-filter-plus-mask.html [ Failure ]
crbug.com/492664 [ Linux ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vlr-005.xht [ Failure ] crbug.com/492664 [ Linux ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vlr-005.xht [ Failure ]
crbug.com/492664 [ Linux ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vrl-004.xht [ Failure ] crbug.com/492664 [ Linux ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vrl-004.xht [ Failure ]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment