зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1720152 - Recurse into replay for dependencies, rather than using a temp surface. r=jrmuizel,bobowen,emilio
Differential Revision: https://phabricator.services.mozilla.com/D120050
This commit is contained in:
Родитель
4a06fcb21e
Коммит
ec9b5dd838
|
@ -1158,10 +1158,7 @@ class DrawTarget : public external::AtomicRefCounted<DrawTarget> {
|
|||
* This is considered fallible, and replaying this without making the surface
|
||||
* available to the replay will just skip the draw.
|
||||
*/
|
||||
virtual void DrawDependentSurface(
|
||||
uint64_t aId, const Rect& aDest,
|
||||
const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
|
||||
const DrawOptions& aOptions = DrawOptions()) {
|
||||
virtual void DrawDependentSurface(uint64_t aId, const Rect& aDest) {
|
||||
MOZ_CRASH("GFX: DrawDependentSurface");
|
||||
}
|
||||
|
||||
|
|
|
@ -375,12 +375,10 @@ void DrawTargetRecording::DrawSurface(SourceSurface* aSurface,
|
|||
aSurfOptions, aOptions));
|
||||
}
|
||||
|
||||
void DrawTargetRecording::DrawDependentSurface(
|
||||
uint64_t aId, const Rect& aDest, const DrawSurfaceOptions& aSurfOptions,
|
||||
const DrawOptions& aOptions) {
|
||||
void DrawTargetRecording::DrawDependentSurface(uint64_t aId,
|
||||
const Rect& aDest) {
|
||||
mRecorder->AddDependentSurface(aId);
|
||||
mRecorder->RecordEvent(
|
||||
RecordedDrawDependentSurface(this, aId, aDest, aSurfOptions, aOptions));
|
||||
mRecorder->RecordEvent(RecordedDrawDependentSurface(this, aId, aDest));
|
||||
}
|
||||
|
||||
void DrawTargetRecording::DrawSurfaceWithShadow(
|
||||
|
|
|
@ -62,10 +62,7 @@ class DrawTargetRecording : public DrawTarget {
|
|||
const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
|
||||
const DrawOptions& aOptions = DrawOptions()) override;
|
||||
|
||||
virtual void DrawDependentSurface(
|
||||
uint64_t aId, const Rect& aDest,
|
||||
const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
|
||||
const DrawOptions& aOptions = DrawOptions()) override;
|
||||
virtual void DrawDependentSurface(uint64_t aId, const Rect& aDest) override;
|
||||
|
||||
virtual void DrawFilter(FilterNode* aNode, const Rect& aSourceRect,
|
||||
const Point& aDestPoint,
|
||||
|
|
|
@ -493,12 +493,10 @@ void DrawTargetWrapAndRecord::DrawSurface(
|
|||
aSurfOptions, aOptions);
|
||||
}
|
||||
|
||||
void DrawTargetWrapAndRecord::DrawDependentSurface(
|
||||
uint64_t aId, const Rect& aDest, const DrawSurfaceOptions& aSurfOptions,
|
||||
const DrawOptions& aOptions) {
|
||||
void DrawTargetWrapAndRecord::DrawDependentSurface(uint64_t aId,
|
||||
const Rect& aDest) {
|
||||
mRecorder->AddDependentSurface(aId);
|
||||
mRecorder->RecordEvent(
|
||||
RecordedDrawDependentSurface(this, aId, aDest, aSurfOptions, aOptions));
|
||||
mRecorder->RecordEvent(RecordedDrawDependentSurface(this, aId, aDest));
|
||||
}
|
||||
|
||||
void DrawTargetWrapAndRecord::DrawSurfaceWithShadow(
|
||||
|
|
|
@ -59,10 +59,7 @@ class DrawTargetWrapAndRecord : public DrawTarget {
|
|||
const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
|
||||
const DrawOptions& aOptions = DrawOptions()) override;
|
||||
|
||||
virtual void DrawDependentSurface(
|
||||
uint64_t aId, const Rect& aDest,
|
||||
const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
|
||||
const DrawOptions& aOptions = DrawOptions()) override;
|
||||
virtual void DrawDependentSurface(uint64_t aId, const Rect& aDest) override;
|
||||
|
||||
virtual void DrawFilter(FilterNode* aNode, const Rect& aSourceRect,
|
||||
const Point& aDestPoint,
|
||||
|
|
|
@ -111,35 +111,11 @@ already_AddRefed<DrawTarget> InlineTranslator::CreateDrawTarget(
|
|||
|
||||
already_AddRefed<SourceSurface> InlineTranslator::LookupExternalSurface(
|
||||
uint64_t aKey) {
|
||||
if (mExternalSurfaces) {
|
||||
RefPtr<SourceSurface> surface = mExternalSurfaces->Get(aKey);
|
||||
if (surface) {
|
||||
return surface.forget();
|
||||
}
|
||||
}
|
||||
|
||||
if (!mDependentSurfaces) {
|
||||
if (!mExternalSurfaces) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<RecordedDependentSurface> recordedSurface =
|
||||
mDependentSurfaces->Get(aKey);
|
||||
if (!recordedSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> newDT = GetReferenceDrawTarget()->CreateSimilarDrawTarget(
|
||||
recordedSurface->mSize, SurfaceFormat::B8G8R8A8);
|
||||
|
||||
InlineTranslator translator(newDT, nullptr);
|
||||
translator.SetDependentSurfaces(mDependentSurfaces);
|
||||
if (!translator.TranslateRecording((char*)recordedSurface->mRecording.mData,
|
||||
recordedSurface->mRecording.mLen)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<SourceSurface> snapshot = newDT->Snapshot();
|
||||
return snapshot.forget();
|
||||
RefPtr<SourceSurface> surface = mExternalSurfaces->Get(aKey);
|
||||
return surface.forget();
|
||||
}
|
||||
|
||||
} // namespace mozilla::gfx
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Filters.h"
|
||||
#include "mozilla/gfx/RecordedEvent.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
@ -40,10 +39,8 @@ class InlineTranslator : public Translator {
|
|||
nsRefPtrHashtable<nsUint64HashKey, SourceSurface>* aExternalSurfaces) {
|
||||
mExternalSurfaces = aExternalSurfaces;
|
||||
}
|
||||
void SetDependentSurfaces(
|
||||
nsRefPtrHashtable<nsUint64HashKey, RecordedDependentSurface>*
|
||||
aDependentSurfaces) {
|
||||
mDependentSurfaces = aDependentSurfaces;
|
||||
void SetReferenceDrawTargetTransform(const Matrix& aTransform) {
|
||||
mBaseDTTransform = aTransform;
|
||||
}
|
||||
|
||||
DrawTarget* LookupDrawTarget(ReferencePtr aRefPtr) final {
|
||||
|
@ -163,12 +160,14 @@ class InlineTranslator : public Translator {
|
|||
MOZ_ASSERT(mBaseDT, "mBaseDT has not been initialized.");
|
||||
return mBaseDT;
|
||||
}
|
||||
Matrix GetReferenceDrawTargetTransform() final { return mBaseDTTransform; }
|
||||
|
||||
void* GetFontContext() final { return mFontContext; }
|
||||
std::string GetError() { return mError; }
|
||||
|
||||
protected:
|
||||
RefPtr<DrawTarget> mBaseDT;
|
||||
Matrix mBaseDTTransform;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, DrawTarget> mDrawTargets;
|
||||
|
||||
private:
|
||||
|
@ -184,8 +183,6 @@ class InlineTranslator : public Translator {
|
|||
nsRefPtrHashtable<nsUint64HashKey, NativeFontResource> mNativeFontResources;
|
||||
nsRefPtrHashtable<nsUint64HashKey, SourceSurface>* mExternalSurfaces =
|
||||
nullptr;
|
||||
nsRefPtrHashtable<nsUint64HashKey, RecordedDependentSurface>*
|
||||
mDependentSurfaces = nullptr;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "Logging.h"
|
||||
#include "ScaledFontBase.h"
|
||||
#include "SFNTData.h"
|
||||
#include "InlineTranslator.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
@ -170,5 +171,39 @@ already_AddRefed<DrawTarget> Translator::CreateDrawTarget(
|
|||
return newDT.forget();
|
||||
}
|
||||
|
||||
void Translator::DrawDependentSurface(ReferencePtr aDrawTarget, uint64_t aKey,
|
||||
const Rect& aRect) {
|
||||
if (!mDependentSurfaces) {
|
||||
return;
|
||||
}
|
||||
|
||||
DrawTarget* dt = LookupDrawTarget(aDrawTarget);
|
||||
if (!dt) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<RecordedDependentSurface> recordedSurface =
|
||||
mDependentSurfaces->Get(aKey);
|
||||
if (!recordedSurface) {
|
||||
return;
|
||||
}
|
||||
|
||||
dt->PushClipRect(aRect);
|
||||
|
||||
// Construct a new translator, so we can recurse into translating this
|
||||
// sub-recording into the same DT. Set an initial transform for the
|
||||
// translator, so that all commands get moved into the rect we want to draw.
|
||||
Matrix transform = dt->GetTransform();
|
||||
transform.PreTranslate(aRect.TopLeft());
|
||||
InlineTranslator translator(dt, nullptr);
|
||||
translator.SetReferenceDrawTargetTransform(transform);
|
||||
|
||||
translator.SetDependentSurfaces(mDependentSurfaces);
|
||||
translator.TranslateRecording((char*)recordedSurface->mRecording.mData,
|
||||
recordedSurface->mRecording.mLen);
|
||||
|
||||
dt->PopClip();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "mozilla/gfx/Point.h"
|
||||
#include "mozilla/gfx/Types.h"
|
||||
#include "mozilla/ipc/ByteBuf.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
@ -101,6 +102,8 @@ class Translator {
|
|||
virtual already_AddRefed<SourceSurface> LookupExternalSurface(uint64_t aKey) {
|
||||
return nullptr;
|
||||
}
|
||||
void DrawDependentSurface(ReferencePtr aDrawTarget, uint64_t aKey,
|
||||
const Rect& aRect);
|
||||
virtual void AddDrawTarget(ReferencePtr aRefPtr, DrawTarget* aDT) = 0;
|
||||
virtual void RemoveDrawTarget(ReferencePtr aRefPtr) = 0;
|
||||
virtual void AddPath(ReferencePtr aRefPtr, Path* aPath) = 0;
|
||||
|
@ -137,7 +140,17 @@ class Translator {
|
|||
const IntSize& aSize,
|
||||
SurfaceFormat aFormat);
|
||||
virtual DrawTarget* GetReferenceDrawTarget() = 0;
|
||||
virtual Matrix GetReferenceDrawTargetTransform() { return Matrix(); }
|
||||
virtual void* GetFontContext() { return nullptr; }
|
||||
|
||||
void SetDependentSurfaces(
|
||||
nsRefPtrHashtable<nsUint64HashKey, RecordedDependentSurface>*
|
||||
aDependentSurfaces) {
|
||||
mDependentSurfaces = aDependentSurfaces;
|
||||
}
|
||||
|
||||
nsRefPtrHashtable<nsUint64HashKey, RecordedDependentSurface>*
|
||||
mDependentSurfaces = nullptr;
|
||||
};
|
||||
|
||||
struct ColorPatternStorage {
|
||||
|
|
|
@ -706,14 +706,10 @@ class RecordedDrawSurface : public RecordedDrawingEvent<RecordedDrawSurface> {
|
|||
class RecordedDrawDependentSurface
|
||||
: public RecordedDrawingEvent<RecordedDrawDependentSurface> {
|
||||
public:
|
||||
RecordedDrawDependentSurface(DrawTarget* aDT, uint64_t aId, const Rect& aDest,
|
||||
const DrawSurfaceOptions& aDSOptions,
|
||||
const DrawOptions& aOptions)
|
||||
RecordedDrawDependentSurface(DrawTarget* aDT, uint64_t aId, const Rect& aDest)
|
||||
: RecordedDrawingEvent(DRAWDEPENDENTSURFACE, aDT),
|
||||
mId(aId),
|
||||
mDest(aDest),
|
||||
mDSOptions(aDSOptions),
|
||||
mOptions(aOptions) {}
|
||||
mDest(aDest) {}
|
||||
|
||||
bool PlayEvent(Translator* aTranslator) const override;
|
||||
|
||||
|
@ -731,8 +727,6 @@ class RecordedDrawDependentSurface
|
|||
|
||||
uint64_t mId;
|
||||
Rect mDest;
|
||||
DrawSurfaceOptions mDSOptions;
|
||||
DrawOptions mOptions;
|
||||
};
|
||||
|
||||
class RecordedDrawSurfaceWithShadow
|
||||
|
@ -2780,7 +2774,16 @@ inline bool RecordedSetTransform::PlayEvent(Translator* aTranslator) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
dt->SetTransform(mTransform);
|
||||
// If we're drawing to the reference DT, then we need to manually apply
|
||||
// its initial transform, otherwise we'll just clobber it with only the
|
||||
// the transform that was visible to the code doing the recording.
|
||||
if (dt == aTranslator->GetReferenceDrawTarget()) {
|
||||
dt->SetTransform(mTransform *
|
||||
aTranslator->GetReferenceDrawTargetTransform());
|
||||
} else {
|
||||
dt->SetTransform(mTransform);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2846,20 +2849,7 @@ inline void RecordedDrawSurface::OutputSimpleEventInfo(
|
|||
|
||||
inline bool RecordedDrawDependentSurface::PlayEvent(
|
||||
Translator* aTranslator) const {
|
||||
DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
|
||||
if (!dt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We still return true even if this fails, since dependent surfaces are
|
||||
// used for cross-origin iframe drawing and can fail.
|
||||
RefPtr<SourceSurface> surface = aTranslator->LookupExternalSurface(mId);
|
||||
if (!surface) {
|
||||
return true;
|
||||
}
|
||||
|
||||
dt->DrawSurface(surface, mDest, Rect(Point(), Size(surface->GetSize())),
|
||||
mDSOptions, mOptions);
|
||||
aTranslator->DrawDependentSurface(mDT, mId, mDest);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2868,8 +2858,6 @@ void RecordedDrawDependentSurface::Record(S& aStream) const {
|
|||
RecordedDrawingEvent::Record(aStream);
|
||||
WriteElement(aStream, mId);
|
||||
WriteElement(aStream, mDest);
|
||||
WriteElement(aStream, mDSOptions);
|
||||
WriteElement(aStream, mOptions);
|
||||
}
|
||||
|
||||
template <class S>
|
||||
|
@ -2877,8 +2865,6 @@ RecordedDrawDependentSurface::RecordedDrawDependentSurface(S& aStream)
|
|||
: RecordedDrawingEvent(DRAWDEPENDENTSURFACE, aStream) {
|
||||
ReadElement(aStream, mId);
|
||||
ReadElement(aStream, mDest);
|
||||
ReadDrawSurfaceOptions(aStream, mDSOptions);
|
||||
ReadDrawOptions(aStream, mOptions);
|
||||
}
|
||||
|
||||
inline void RecordedDrawDependentSurface::OutputSimpleEventInfo(
|
||||
|
|
|
@ -1372,9 +1372,19 @@ void nsDisplayRemote::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Rendering the inner document will apply a scale to account for its
|
||||
// app units per dev pixel ratio. We want to apply the inverse scaling
|
||||
// using our app units per dev pixel ratio, so that no actual scaling
|
||||
// will be applied if they match. For in-process rendering,
|
||||
// nsSubDocumentFrame creates an nsDisplayZoom item if the app units
|
||||
// per dev pixel ratio changes.
|
||||
int32_t appUnitsPerDevPixel = pc->AppUnitsPerDevPixel();
|
||||
gfxFloat scale = gfxFloat(AppUnitsPerCSSPixel()) / appUnitsPerDevPixel;
|
||||
gfxContextMatrixAutoSaveRestore saveMatrix(aCtx);
|
||||
aCtx->Multiply(gfxMatrix::Scaling(scale, scale));
|
||||
|
||||
Rect destRect =
|
||||
NSRectToSnappedRect(GetContentRect(), appUnitsPerDevPixel, *target);
|
||||
NSRectToSnappedRect(GetContentRect(), AppUnitsPerCSSPixel(), *target);
|
||||
target->DrawDependentSurface(mPaintData.mTabId, destRect);
|
||||
}
|
||||
|
||||
|
|
|
@ -82,26 +82,5 @@ already_AddRefed<DrawTarget> PrintTranslator::CreateDrawTarget(
|
|||
return drawTarget.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<SourceSurface> PrintTranslator::LookupExternalSurface(
|
||||
uint64_t aKey) {
|
||||
RefPtr<RecordedDependentSurface> surface = mDependentSurfaces.Get(aKey);
|
||||
if (!surface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> newDT = GetReferenceDrawTarget()->CreateSimilarDrawTarget(
|
||||
surface->mSize, SurfaceFormat::B8G8R8A8);
|
||||
|
||||
InlineTranslator translator(newDT, nullptr);
|
||||
translator.SetDependentSurfaces(&mDependentSurfaces);
|
||||
if (!translator.TranslateRecording((char*)surface->mRecording.mData,
|
||||
surface->mRecording.mLen)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<SourceSurface> snapshot = newDT->Snapshot();
|
||||
return snapshot.forget();
|
||||
}
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Filters.h"
|
||||
#include "mozilla/gfx/RecordedEvent.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
class nsDeviceContext;
|
||||
|
||||
|
@ -38,12 +37,6 @@ class PrintTranslator final : public Translator {
|
|||
|
||||
bool TranslateRecording(PRFileDescStream& aRecording);
|
||||
|
||||
void SetDependentSurfaces(
|
||||
nsRefPtrHashtable<nsUint64HashKey, RecordedDependentSurface>&&
|
||||
aDependentSurfaces) {
|
||||
mDependentSurfaces = std::move(aDependentSurfaces);
|
||||
}
|
||||
|
||||
DrawTarget* LookupDrawTarget(ReferencePtr aRefPtr) final {
|
||||
DrawTarget* result = mDrawTargets.GetWeak(aRefPtr);
|
||||
MOZ_ASSERT(result);
|
||||
|
@ -91,8 +84,6 @@ class PrintTranslator final : public Translator {
|
|||
return result;
|
||||
}
|
||||
|
||||
already_AddRefed<SourceSurface> LookupExternalSurface(uint64_t aKey) final;
|
||||
|
||||
void AddDrawTarget(ReferencePtr aRefPtr, DrawTarget* aDT) final {
|
||||
mDrawTargets.InsertOrUpdate(aRefPtr, RefPtr{aDT});
|
||||
}
|
||||
|
@ -171,8 +162,6 @@ class PrintTranslator final : public Translator {
|
|||
nsRefPtrHashtable<nsPtrHashKey<void>, ScaledFont> mScaledFonts;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, UnscaledFont> mUnscaledFonts;
|
||||
nsRefPtrHashtable<nsUint64HashKey, NativeFontResource> mNativeFontResources;
|
||||
nsRefPtrHashtable<nsUint64HashKey, RecordedDependentSurface>
|
||||
mDependentSurfaces;
|
||||
};
|
||||
|
||||
} // namespace layout
|
||||
|
|
|
@ -162,11 +162,13 @@ nsresult RemotePrintJobParent::PrintPage(
|
|||
return rv;
|
||||
}
|
||||
if (aFragments) {
|
||||
mPrintTranslator->SetDependentSurfaces(std::move(*aFragments));
|
||||
mPrintTranslator->SetDependentSurfaces(aFragments);
|
||||
}
|
||||
if (!mPrintTranslator->TranslateRecording(aRecording)) {
|
||||
mPrintTranslator->SetDependentSurfaces(nullptr);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mPrintTranslator->SetDependentSurfaces(nullptr);
|
||||
|
||||
rv = mPrintDeviceContext->EndPage();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[iframe-cross-origin-scaled-print.sub.html]
|
||||
expected:
|
||||
if fission and (os == "linux"): FAIL
|
|
@ -0,0 +1,17 @@
|
|||
<!doctype html>
|
||||
<link rel=match href="iframe-nested-scaled-print-ref.html">
|
||||
<style>
|
||||
body { margin: 0 }
|
||||
div {
|
||||
transform-origin: top left;
|
||||
transform: scale(2);
|
||||
overflow: hidden;
|
||||
}
|
||||
iframe {
|
||||
width: 100px;
|
||||
height: 50px;
|
||||
}
|
||||
</style>
|
||||
<div>
|
||||
<iframe frameborder=0 scrolling=no src="//{{hosts[alt][www]}}:{{ports[http][0]}}{{location[path]}}/../resources/iframe-nested-printing-pass.html"></iframe>
|
||||
</div>
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<style>
|
||||
body { margin: 0 }
|
||||
div {
|
||||
transform-origin: top left;
|
||||
transform: scale(2);
|
||||
}
|
||||
iframe {
|
||||
width: 100px;
|
||||
height: 50px;
|
||||
}
|
||||
</style>
|
||||
<div>
|
||||
<iframe frameborder=0 scrolling=no src="resources/iframe-nested-printing-pass.html"></iframe>
|
||||
</div>
|
|
@ -0,0 +1,9 @@
|
|||
<!doctype html>
|
||||
<style>
|
||||
body {
|
||||
margin: calc(0.5px * 2 / 3);
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
PASS
|
||||
</body>
|
Загрузка…
Ссылка в новой задаче