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:
parent
c6cbcdb05b
commit
a3f4a32022
|
@ -904,7 +904,8 @@
|
||||||
"tags": ["dawn"],
|
"tags": ["dawn"],
|
||||||
"values": [
|
"values": [
|
||||||
{"value": 0, "name": "premultiplied"},
|
{"value": 0, "name": "premultiplied"},
|
||||||
{"value": 1, "name": "unpremultiplied"}
|
{"value": 1, "name": "unpremultiplied"},
|
||||||
|
{"value": 2, "name": "opaque"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"copy texture for browser options": {
|
"copy texture for browser options": {
|
||||||
|
|
|
@ -145,9 +145,11 @@ static const char sCopyTextureForBrowserShader[] = R"(
|
||||||
let kEncodeToGammaStep = 0x08u;
|
let kEncodeToGammaStep = 0x08u;
|
||||||
let kPremultiplyStep = 0x10u;
|
let kPremultiplyStep = 0x10u;
|
||||||
let kDecodeForSrgbDstFormat = 0x20u;
|
let kDecodeForSrgbDstFormat = 0x20u;
|
||||||
|
let kClearSrcAlphaToOne = 0x40u;
|
||||||
|
|
||||||
// Unpremultiply step. Appling color space conversion op on premultiplied source texture
|
// Unpremultiply step. Appling color space conversion op on premultiplied source texture
|
||||||
// also needs to unpremultiply first.
|
// also needs to unpremultiply first.
|
||||||
|
// This step is exclusive with clear src alpha to one step.
|
||||||
if (bool(uniforms.steps_mask & kUnpremultiplyStep)) {
|
if (bool(uniforms.steps_mask & kUnpremultiplyStep)) {
|
||||||
if (color.a != 0.0) {
|
if (color.a != 0.0) {
|
||||||
color = vec4<f32>(color.rgb / color.a, color.a);
|
color = vec4<f32>(color.rgb / color.a, color.a);
|
||||||
|
@ -180,6 +182,7 @@ static const char sCopyTextureForBrowserShader[] = R"(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Premultiply step.
|
// Premultiply step.
|
||||||
|
// This step is exclusive with clear src alpha to one step.
|
||||||
if (bool(uniforms.steps_mask & kPremultiplyStep)) {
|
if (bool(uniforms.steps_mask & kPremultiplyStep)) {
|
||||||
color = vec4<f32>(color.rgb * color.a, color.a);
|
color = vec4<f32>(color.rgb * color.a, color.a);
|
||||||
}
|
}
|
||||||
|
@ -192,6 +195,12 @@ static const char sCopyTextureForBrowserShader[] = R"(
|
||||||
color.a);
|
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;
|
return color;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
@ -456,11 +465,16 @@ MaybeError DoCopyTextureForBrowser(DeviceBase* device,
|
||||||
constexpr uint32_t kEncodeToGammaStep = 0x08;
|
constexpr uint32_t kEncodeToGammaStep = 0x08;
|
||||||
constexpr uint32_t kPremultiplyStep = 0x10;
|
constexpr uint32_t kPremultiplyStep = 0x10;
|
||||||
constexpr uint32_t kDecodeForSrgbDstFormat = 0x20;
|
constexpr uint32_t kDecodeForSrgbDstFormat = 0x20;
|
||||||
|
constexpr uint32_t kClearSrcAlphaToOne = 0x40;
|
||||||
|
|
||||||
if (options->srcAlphaMode == wgpu::AlphaMode::Premultiplied) {
|
if (options->srcAlphaMode == wgpu::AlphaMode::Premultiplied) {
|
||||||
if (options->needsColorSpaceConversion || options->srcAlphaMode != options->dstAlphaMode) {
|
if (options->needsColorSpaceConversion ||
|
||||||
|
options->dstAlphaMode == wgpu::AlphaMode::Unpremultiplied) {
|
||||||
stepsMask |= kUnpremultiplyStep;
|
stepsMask |= kUnpremultiplyStep;
|
||||||
}
|
}
|
||||||
|
} else if (options->srcAlphaMode == wgpu::AlphaMode::Opaque) {
|
||||||
|
// Simply clear src alpha channel to 1.0
|
||||||
|
stepsMask |= kClearSrcAlphaToOne;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options->needsColorSpaceConversion) {
|
if (options->needsColorSpaceConversion) {
|
||||||
|
@ -497,7 +511,8 @@ MaybeError DoCopyTextureForBrowser(DeviceBase* device,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options->dstAlphaMode == wgpu::AlphaMode::Premultiplied) {
|
if (options->dstAlphaMode == wgpu::AlphaMode::Premultiplied) {
|
||||||
if (options->needsColorSpaceConversion || options->srcAlphaMode != options->dstAlphaMode) {
|
if (options->needsColorSpaceConversion ||
|
||||||
|
options->srcAlphaMode == wgpu::AlphaMode::Unpremultiplied) {
|
||||||
stepsMask |= kPremultiplyStep;
|
stepsMask |= kPremultiplyStep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,25 +181,22 @@ class CopyTextureForBrowserTests : public Parent {
|
||||||
// Source textures will have variable pixel data to cover cases like
|
// Source textures will have variable pixel data to cover cases like
|
||||||
// flipY.
|
// flipY.
|
||||||
if (textureRole == TextureCopyRole::SOURCE) {
|
if (textureRole == TextureCopyRole::SOURCE) {
|
||||||
if (srcAlphaMode != dstAlphaMode) {
|
if (srcAlphaMode == wgpu::AlphaMode::Unpremultiplied &&
|
||||||
if (dstAlphaMode == wgpu::AlphaMode::Premultiplied) {
|
dstAlphaMode == wgpu::AlphaMode::Premultiplied) {
|
||||||
// For premultiply alpha test cases, we expect each channel in dst
|
// We expect each channel in dst
|
||||||
// texture will equal to the alpha channel value.
|
// texture will equal to the alpha channel value.
|
||||||
ASSERT(srcAlphaMode == wgpu::AlphaMode::Unpremultiplied);
|
|
||||||
textureData[sliceOffset + rowOffset + x] = RGBA8(
|
textureData[sliceOffset + rowOffset + x] = RGBA8(
|
||||||
static_cast<uint8_t>(255), static_cast<uint8_t>(255),
|
static_cast<uint8_t>(255), static_cast<uint8_t>(255),
|
||||||
static_cast<uint8_t>(255), static_cast<uint8_t>(alpha[x % 4]));
|
static_cast<uint8_t>(255), static_cast<uint8_t>(alpha[x % 4]));
|
||||||
} else {
|
} else if (srcAlphaMode == wgpu::AlphaMode::Premultiplied &&
|
||||||
// For unpremultiply alpha test cases, we expect each channel in dst
|
dstAlphaMode == wgpu::AlphaMode::Unpremultiplied) {
|
||||||
|
// We expect each channel in dst
|
||||||
// texture will equal to 1.0.
|
// texture will equal to 1.0.
|
||||||
ASSERT(srcAlphaMode == wgpu::AlphaMode::Premultiplied);
|
|
||||||
textureData[sliceOffset + rowOffset + x] =
|
textureData[sliceOffset + rowOffset + x] =
|
||||||
RGBA8(static_cast<uint8_t>(alpha[x % 4]),
|
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]),
|
static_cast<uint8_t>(alpha[x % 4]),
|
||||||
static_cast<uint8_t>(alpha[x % 4]));
|
static_cast<uint8_t>(alpha[x % 4]));
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
textureData[sliceOffset + rowOffset + x] =
|
textureData[sliceOffset + rowOffset + x] =
|
||||||
RGBA8(static_cast<uint8_t>((x + layer * x) % 256),
|
RGBA8(static_cast<uint8_t>((x + layer * x) % 256),
|
||||||
|
@ -300,19 +297,20 @@ class CopyTextureForBrowserTests : public Parent {
|
||||||
// after premultiply.
|
// after premultiply.
|
||||||
let premultiplied = 0u;
|
let premultiplied = 0u;
|
||||||
let unpremultiplied = 1u;
|
let unpremultiplied = 1u;
|
||||||
if (uniforms.srcAlphaMode != uniforms.dstAlphaMode) {
|
let opaque = 2u;
|
||||||
if (uniforms.dstAlphaMode == premultiplied) {
|
if (uniforms.srcAlphaMode == opaque) {
|
||||||
// srcAlphaMode == unpremultiplied
|
srcColor.a = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uniforms.srcAlphaMode == unpremultiplied && uniforms.dstAlphaMode == premultiplied) {
|
||||||
srcColor = vec4<f32>(srcColor.rgb * srcColor.a, srcColor.a);
|
srcColor = vec4<f32>(srcColor.rgb * srcColor.a, srcColor.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uniforms.dstAlphaMode == unpremultiplied) {
|
if (uniforms.srcAlphaMode == premultiplied && uniforms.dstAlphaMode == unpremultiplied) {
|
||||||
// srcAlphaMode == premultiplied
|
|
||||||
if (srcColor.a != 0.0) {
|
if (srcColor.a != 0.0) {
|
||||||
srcColor = vec4<f32>(srcColor.rgb / srcColor.a, srcColor.a);
|
srcColor = vec4<f32>(srcColor.rgb / srcColor.a, srcColor.a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Not use loop and variable index format to workaround
|
// Not use loop and variable index format to workaround
|
||||||
// crbug.com/tint/638.
|
// crbug.com/tint/638.
|
||||||
|
@ -1134,13 +1132,13 @@ TEST_P(CopyTextureForBrowser_AlphaMode, alphaMode) {
|
||||||
DoAlphaModeTest();
|
DoAlphaModeTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST_P(CopyTextureForBrowser_AlphaMode,
|
DAWN_INSTANTIATE_TEST_P(
|
||||||
{D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
|
CopyTextureForBrowser_AlphaMode,
|
||||||
VulkanBackend()},
|
{D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
|
||||||
std::vector<wgpu::AlphaMode>({wgpu::AlphaMode::Premultiplied,
|
std::vector<wgpu::AlphaMode>({wgpu::AlphaMode::Premultiplied, wgpu::AlphaMode::Unpremultiplied,
|
||||||
wgpu::AlphaMode::Unpremultiplied}),
|
wgpu::AlphaMode::Opaque}),
|
||||||
std::vector<wgpu::AlphaMode>({wgpu::AlphaMode::Premultiplied,
|
std::vector<wgpu::AlphaMode>({wgpu::AlphaMode::Premultiplied, wgpu::AlphaMode::Unpremultiplied,
|
||||||
wgpu::AlphaMode::Unpremultiplied}));
|
wgpu::AlphaMode::Opaque}));
|
||||||
|
|
||||||
// Verify |CopyTextureForBrowser| doing color space conversion.
|
// Verify |CopyTextureForBrowser| doing color space conversion.
|
||||||
TEST_P(CopyTextureForBrowser_ColorSpace, colorSpaceConversion) {
|
TEST_P(CopyTextureForBrowser_ColorSpace, colorSpaceConversion) {
|
||||||
|
|
Loading…
Reference in New Issue