Add clear alpha to one step to copy texture for browser

Bug: chromium:1331139
Change-Id: I69c31aea0320f302be686adf0167649a98db3414
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/95682
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Shaobo Yan <shaobo.yan@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
shrekshao 2022-07-11 18:11:14 +00:00 committed by Shrek Shao
parent c6cbcdb05b
commit a3f4a32022
3 changed files with 54 additions and 40 deletions

View File

@ -904,7 +904,8 @@
"tags": ["dawn"],
"values": [
{"value": 0, "name": "premultiplied"},
{"value": 1, "name": "unpremultiplied"}
{"value": 1, "name": "unpremultiplied"},
{"value": 2, "name": "opaque"}
]
},
"copy texture for browser options": {

View File

@ -145,9 +145,11 @@ static const char sCopyTextureForBrowserShader[] = R"(
let kEncodeToGammaStep = 0x08u;
let kPremultiplyStep = 0x10u;
let kDecodeForSrgbDstFormat = 0x20u;
let kClearSrcAlphaToOne = 0x40u;
// Unpremultiply step. Appling color space conversion op on premultiplied source texture
// also needs to unpremultiply first.
// This step is exclusive with clear src alpha to one step.
if (bool(uniforms.steps_mask & kUnpremultiplyStep)) {
if (color.a != 0.0) {
color = vec4<f32>(color.rgb / color.a, color.a);
@ -180,6 +182,7 @@ static const char sCopyTextureForBrowserShader[] = R"(
}
// Premultiply step.
// This step is exclusive with clear src alpha to one step.
if (bool(uniforms.steps_mask & kPremultiplyStep)) {
color = vec4<f32>(color.rgb * color.a, color.a);
}
@ -192,6 +195,12 @@ static const char sCopyTextureForBrowserShader[] = R"(
color.a);
}
// Clear alpha to one step.
// This step is exclusive with premultiply/unpremultiply step.
if (bool(uniforms.steps_mask & kClearSrcAlphaToOne)) {
color.a = 1.0;
}
return color;
}
)";
@ -456,11 +465,16 @@ MaybeError DoCopyTextureForBrowser(DeviceBase* device,
constexpr uint32_t kEncodeToGammaStep = 0x08;
constexpr uint32_t kPremultiplyStep = 0x10;
constexpr uint32_t kDecodeForSrgbDstFormat = 0x20;
constexpr uint32_t kClearSrcAlphaToOne = 0x40;
if (options->srcAlphaMode == wgpu::AlphaMode::Premultiplied) {
if (options->needsColorSpaceConversion || options->srcAlphaMode != options->dstAlphaMode) {
if (options->needsColorSpaceConversion ||
options->dstAlphaMode == wgpu::AlphaMode::Unpremultiplied) {
stepsMask |= kUnpremultiplyStep;
}
} else if (options->srcAlphaMode == wgpu::AlphaMode::Opaque) {
// Simply clear src alpha channel to 1.0
stepsMask |= kClearSrcAlphaToOne;
}
if (options->needsColorSpaceConversion) {
@ -497,7 +511,8 @@ MaybeError DoCopyTextureForBrowser(DeviceBase* device,
}
if (options->dstAlphaMode == wgpu::AlphaMode::Premultiplied) {
if (options->needsColorSpaceConversion || options->srcAlphaMode != options->dstAlphaMode) {
if (options->needsColorSpaceConversion ||
options->srcAlphaMode == wgpu::AlphaMode::Unpremultiplied) {
stepsMask |= kPremultiplyStep;
}
}
@ -587,7 +602,7 @@ MaybeError DoCopyTextureForBrowser(DeviceBase* device,
renderPassDesc.colorAttachments = &colorAttachmentDesc;
Ref<RenderPassEncoder> passEncoder = encoder->BeginRenderPass(&renderPassDesc);
// Start pipeline and encode commands to complete
// Start pipeline and encode commands to complete
// the copy from src texture to dst texture with transformation.
passEncoder->APISetPipeline(pipeline);
passEncoder->APISetBindGroup(0, bindGroup.Get());

View File

@ -181,25 +181,22 @@ class CopyTextureForBrowserTests : public Parent {
// Source textures will have variable pixel data to cover cases like
// flipY.
if (textureRole == TextureCopyRole::SOURCE) {
if (srcAlphaMode != dstAlphaMode) {
if (dstAlphaMode == wgpu::AlphaMode::Premultiplied) {
// For premultiply alpha test cases, we expect each channel in dst
// texture will equal to the alpha channel value.
ASSERT(srcAlphaMode == wgpu::AlphaMode::Unpremultiplied);
textureData[sliceOffset + rowOffset + x] = RGBA8(
static_cast<uint8_t>(255), static_cast<uint8_t>(255),
static_cast<uint8_t>(255), static_cast<uint8_t>(alpha[x % 4]));
} else {
// For unpremultiply alpha test cases, we expect each channel in dst
// texture will equal to 1.0.
ASSERT(srcAlphaMode == wgpu::AlphaMode::Premultiplied);
textureData[sliceOffset + rowOffset + x] =
RGBA8(static_cast<uint8_t>(alpha[x % 4]),
static_cast<uint8_t>(alpha[x % 4]),
static_cast<uint8_t>(alpha[x % 4]),
static_cast<uint8_t>(alpha[x % 4]));
}
if (srcAlphaMode == wgpu::AlphaMode::Unpremultiplied &&
dstAlphaMode == wgpu::AlphaMode::Premultiplied) {
// We expect each channel in dst
// texture will equal to the alpha channel value.
textureData[sliceOffset + rowOffset + x] = RGBA8(
static_cast<uint8_t>(255), static_cast<uint8_t>(255),
static_cast<uint8_t>(255), static_cast<uint8_t>(alpha[x % 4]));
} else if (srcAlphaMode == wgpu::AlphaMode::Premultiplied &&
dstAlphaMode == wgpu::AlphaMode::Unpremultiplied) {
// We expect each channel in dst
// texture will equal to 1.0.
textureData[sliceOffset + rowOffset + x] =
RGBA8(static_cast<uint8_t>(alpha[x % 4]),
static_cast<uint8_t>(alpha[x % 4]),
static_cast<uint8_t>(alpha[x % 4]),
static_cast<uint8_t>(alpha[x % 4]));
} else {
textureData[sliceOffset + rowOffset + x] =
RGBA8(static_cast<uint8_t>((x + layer * x) % 256),
@ -300,17 +297,18 @@ class CopyTextureForBrowserTests : public Parent {
// after premultiply.
let premultiplied = 0u;
let unpremultiplied = 1u;
if (uniforms.srcAlphaMode != uniforms.dstAlphaMode) {
if (uniforms.dstAlphaMode == premultiplied) {
// srcAlphaMode == unpremultiplied
srcColor = vec4<f32>(srcColor.rgb * srcColor.a, srcColor.a);
}
let opaque = 2u;
if (uniforms.srcAlphaMode == opaque) {
srcColor.a = 1.0;
}
if (uniforms.dstAlphaMode == unpremultiplied) {
// srcAlphaMode == premultiplied
if (srcColor.a != 0.0) {
srcColor = vec4<f32>(srcColor.rgb / srcColor.a, srcColor.a);
}
if (uniforms.srcAlphaMode == unpremultiplied && uniforms.dstAlphaMode == premultiplied) {
srcColor = vec4<f32>(srcColor.rgb * srcColor.a, srcColor.a);
}
if (uniforms.srcAlphaMode == premultiplied && uniforms.dstAlphaMode == unpremultiplied) {
if (srcColor.a != 0.0) {
srcColor = vec4<f32>(srcColor.rgb / srcColor.a, srcColor.a);
}
}
@ -1134,13 +1132,13 @@ TEST_P(CopyTextureForBrowser_AlphaMode, alphaMode) {
DoAlphaModeTest();
}
DAWN_INSTANTIATE_TEST_P(CopyTextureForBrowser_AlphaMode,
{D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
VulkanBackend()},
std::vector<wgpu::AlphaMode>({wgpu::AlphaMode::Premultiplied,
wgpu::AlphaMode::Unpremultiplied}),
std::vector<wgpu::AlphaMode>({wgpu::AlphaMode::Premultiplied,
wgpu::AlphaMode::Unpremultiplied}));
DAWN_INSTANTIATE_TEST_P(
CopyTextureForBrowser_AlphaMode,
{D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
std::vector<wgpu::AlphaMode>({wgpu::AlphaMode::Premultiplied, wgpu::AlphaMode::Unpremultiplied,
wgpu::AlphaMode::Opaque}),
std::vector<wgpu::AlphaMode>({wgpu::AlphaMode::Premultiplied, wgpu::AlphaMode::Unpremultiplied,
wgpu::AlphaMode::Opaque}));
// Verify |CopyTextureForBrowser| doing color space conversion.
TEST_P(CopyTextureForBrowser_ColorSpace, colorSpaceConversion) {