Bug 1632249 - NON_PREMULT TextureClient iff NON_PREMULT CanvasClient. r=handyman

Differential Revision: https://phabricator.services.mozilla.com/D78800
This commit is contained in:
Jeff Gilbert 2020-06-15 18:26:02 +00:00
Родитель a3bc94c178
Коммит 3ae501809c
7 изменённых файлов: 29 добавлений и 22 удалений

Просмотреть файл

@ -421,7 +421,6 @@ void ClientWebGLContext::Present(WebGLFramebufferJS* const fb,
const layers::TextureType type) { const layers::TextureType type) {
if (!mIsCanvasDirty && !fb) return; if (!mIsCanvasDirty && !fb) return;
mIsCanvasDirty = false; mIsCanvasDirty = false;
mFrontBufferSnapshot = nullptr;
Run<RPROC(Present)>(fb ? fb->mId : 0, type); Run<RPROC(Present)>(fb ? fb->mId : 0, type);
} }
@ -882,7 +881,8 @@ already_AddRefed<gfx::SourceSurface> ClientWebGLContext::GetSurfaceSnapshot(
return ret.forget(); return ret.forget();
} }
RefPtr<gfx::SourceSurface> ClientWebGLContext::GetFrontBufferSnapshot() { RefPtr<gfx::SourceSurface> ClientWebGLContext::GetFrontBufferSnapshot(
const bool requireAlphaPremult) {
const FuncScope funcScope(*this, "<GetSurfaceSnapshot>"); const FuncScope funcScope(*this, "<GetSurfaceSnapshot>");
if (IsContextLost()) return nullptr; if (IsContextLost()) return nullptr;
const auto notLost = const auto notLost =
@ -890,20 +890,19 @@ RefPtr<gfx::SourceSurface> ClientWebGLContext::GetFrontBufferSnapshot() {
const auto& options = mNotLost->info.options; const auto& options = mNotLost->info.options;
if (!mFrontBufferSnapshot) { auto snapshot = Run<RPROC(GetFrontBufferSnapshot)>();
mFrontBufferSnapshot = Run<RPROC(GetFrontBufferSnapshot)>(); if (!snapshot) return nullptr;
if (!mFrontBufferSnapshot) return nullptr;
if (options.alpha && !options.premultipliedAlpha) { if (requireAlphaPremult && options.alpha && !options.premultipliedAlpha) {
const auto nonPremultSurf = mFrontBufferSnapshot; const auto nonPremultSurf = snapshot;
const auto& size = nonPremultSurf->GetSize(); const auto& size = nonPremultSurf->GetSize();
const auto format = nonPremultSurf->GetFormat(); const auto format = nonPremultSurf->GetFormat();
mFrontBufferSnapshot = snapshot =
gfx::Factory::CreateDataSourceSurface(size, format, /*zero=*/false); gfx::Factory::CreateDataSourceSurface(size, format, /*zero=*/false);
gfxUtils::PremultiplyDataSurface(nonPremultSurf, mFrontBufferSnapshot); gfxUtils::PremultiplyDataSurface(nonPremultSurf, snapshot);
}
} }
return mFrontBufferSnapshot;
return snapshot;
} }
RefPtr<gfx::DataSourceSurface> ClientWebGLContext::BackBufferSnapshot() { RefPtr<gfx::DataSourceSurface> ClientWebGLContext::BackBufferSnapshot() {

Просмотреть файл

@ -723,8 +723,6 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
bool mIsCanvasDirty = false; bool mIsCanvasDirty = false;
uvec2 mRequestedSize = {}; uvec2 mRequestedSize = {};
RefPtr<gfx::DataSourceSurface> mFrontBufferSnapshot;
public: public:
explicit ClientWebGLContext(bool webgl2); explicit ClientWebGLContext(bool webgl2);
@ -997,7 +995,8 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
void Present(WebGLFramebufferJS*, layers::TextureType); void Present(WebGLFramebufferJS*, layers::TextureType);
Maybe<layers::SurfaceDescriptor> GetFrontBuffer(WebGLFramebufferJS*, Maybe<layers::SurfaceDescriptor> GetFrontBuffer(WebGLFramebufferJS*,
layers::TextureType); layers::TextureType);
RefPtr<gfx::SourceSurface> GetFrontBufferSnapshot() override; RefPtr<gfx::SourceSurface> GetFrontBufferSnapshot(
bool requireAlphaPremult = true) override;
private: private:
RefPtr<gfx::DataSourceSurface> BackBufferSnapshot(); RefPtr<gfx::DataSourceSurface> BackBufferSnapshot();

Просмотреть файл

@ -137,7 +137,7 @@ class nsICanvasRenderingContextInternal : public nsISupports,
virtual already_AddRefed<mozilla::gfx::SourceSurface> GetSurfaceSnapshot( virtual already_AddRefed<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(
gfxAlphaType* out_alphaType = nullptr) = 0; gfxAlphaType* out_alphaType = nullptr) = 0;
virtual RefPtr<mozilla::gfx::SourceSurface> GetFrontBufferSnapshot() { virtual RefPtr<mozilla::gfx::SourceSurface> GetFrontBufferSnapshot(bool) {
return GetSurfaceSnapshot(); return GetSurfaceSnapshot();
} }

Просмотреть файл

@ -46,7 +46,8 @@ bool CanvasRenderer::IsDataValid(const CanvasRendererData& aData) const {
return mData.GetContext() == aData.GetContext(); return mData.GetContext() == aData.GetContext();
} }
std::shared_ptr<BorrowedSourceSurface> CanvasRenderer::BorrowSnapshot() const { std::shared_ptr<BorrowedSourceSurface> CanvasRenderer::BorrowSnapshot(
const bool requireAlphaPremult) const {
const auto context = mData.GetContext(); const auto context = mData.GetContext();
if (!context) return nullptr; if (!context) return nullptr;
const auto& provider = context->GetBufferProvider(); const auto& provider = context->GetBufferProvider();
@ -57,7 +58,7 @@ std::shared_ptr<BorrowedSourceSurface> CanvasRenderer::BorrowSnapshot() const {
ss = provider->BorrowSnapshot(); ss = provider->BorrowSnapshot();
} }
if (!ss) { if (!ss) {
ss = context->GetFrontBufferSnapshot(); ss = context->GetFrontBufferSnapshot(requireAlphaPremult);
} }
if (!ss) return nullptr; if (!ss) return nullptr;

Просмотреть файл

@ -137,7 +137,8 @@ class CanvasRenderer : public RefCounted<CanvasRenderer> {
return nullptr; return nullptr;
} }
std::shared_ptr<BorrowedSourceSurface> BorrowSnapshot() const; std::shared_ptr<BorrowedSourceSurface> BorrowSnapshot(
bool requireAlphaPremult = true) const;
protected: protected:
void FirePreTransactionCallback() const; void FirePreTransactionCallback() const;

Просмотреть файл

@ -159,7 +159,8 @@ void ShareableCanvasRenderer::UpdateCompositableClient() {
const RefPtr<DrawTarget> dt = tc->BorrowDrawTarget(); const RefPtr<DrawTarget> dt = tc->BorrowDrawTarget();
const auto borrowed = BorrowSnapshot(); const bool requireAlphaPremult = false;
const auto borrowed = BorrowSnapshot(requireAlphaPremult);
if (!borrowed) return nullptr; if (!borrowed) return nullptr;
dt->CopySurface(borrowed->mSurf, {{0, 0}, size}, {0, 0}); dt->CopySurface(borrowed->mSurf, {{0, 0}, size}, {0, 0});

Просмотреть файл

@ -31,6 +31,12 @@ namespace layers {
void CanvasClient::UseTexture(TextureClient* const aTexture) { void CanvasClient::UseTexture(TextureClient* const aTexture) {
MOZ_ASSERT(aTexture); MOZ_ASSERT(aTexture);
const auto isClientNonPremult =
bool(mTextureFlags & TextureFlags::NON_PREMULTIPLIED);
const auto isTextureNonPremult =
bool(aTexture->GetFlags() & TextureFlags::NON_PREMULTIPLIED);
MOZ_ALWAYS_TRUE(isTextureNonPremult == isClientNonPremult);
bool changed = false; bool changed = false;
if (aTexture != mFrontBuffer) { if (aTexture != mFrontBuffer) {