зеркало из https://github.com/mozilla/gecko-dev.git
Bug 761397 - Part 1: Cache ID2D1Layers for D2D Azure backend. r=jrmuizel
This commit is contained in:
Родитель
fecc69df4f
Коммит
a76e2ac169
|
@ -152,7 +152,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
DrawTargetD2D::DrawTargetD2D()
|
DrawTargetD2D::DrawTargetD2D()
|
||||||
: mClipsArePushed(false)
|
: mCurrentCachedLayer(0)
|
||||||
|
, mClipsArePushed(false)
|
||||||
, mPrivateData(NULL)
|
, mPrivateData(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -183,6 +184,13 @@ DrawTargetD2D::~DrawTargetD2D()
|
||||||
// mSnapshot will be cleared now.
|
// mSnapshot will be cleared now.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < kLayerCacheSize; i++) {
|
||||||
|
if (mCachedLayers[i]) {
|
||||||
|
mCachedLayers[i] = NULL;
|
||||||
|
mVRAMUsageDT -= GetByteSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Targets depending on us can break that dependency, since we're obviously not going to
|
// Targets depending on us can break that dependency, since we're obviously not going to
|
||||||
// be modified in the future.
|
// be modified in the future.
|
||||||
for (TargetSet::iterator iter = mDependentTargets.begin();
|
for (TargetSet::iterator iter = mDependentTargets.begin();
|
||||||
|
@ -914,7 +922,9 @@ DrawTargetD2D::Mask(const Pattern &aSource,
|
||||||
RefPtr<ID2D1Brush> maskBrush = CreateBrushForPattern(aMask, 1.0f);
|
RefPtr<ID2D1Brush> maskBrush = CreateBrushForPattern(aMask, 1.0f);
|
||||||
|
|
||||||
RefPtr<ID2D1Layer> layer;
|
RefPtr<ID2D1Layer> layer;
|
||||||
rt->CreateLayer(byRef(layer));
|
|
||||||
|
layer = GetCachedLayer();
|
||||||
|
|
||||||
rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), NULL,
|
rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), NULL,
|
||||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
||||||
D2D1::IdentityMatrix(),
|
D2D1::IdentityMatrix(),
|
||||||
|
@ -926,7 +936,7 @@ DrawTargetD2D::Mask(const Pattern &aSource,
|
||||||
mat.Invert();
|
mat.Invert();
|
||||||
|
|
||||||
rt->FillRectangle(D2DRect(mat.TransformBounds(rect)), brush);
|
rt->FillRectangle(D2DRect(mat.TransformBounds(rect)), brush);
|
||||||
rt->PopLayer();
|
PopCachedLayer(rt);
|
||||||
|
|
||||||
FinalizeRTForOperation(aOptions.mCompositionOp, aSource, Rect(0, 0, (Float)mSize.width, (Float)mSize.height));
|
FinalizeRTForOperation(aOptions.mCompositionOp, aSource, Rect(0, 0, (Float)mSize.width, (Float)mSize.height));
|
||||||
}
|
}
|
||||||
|
@ -948,12 +958,10 @@ DrawTargetD2D::PushClip(const Path *aPath)
|
||||||
clip.mTransform = D2DMatrix(mTransform);
|
clip.mTransform = D2DMatrix(mTransform);
|
||||||
clip.mPath = pathD2D;
|
clip.mPath = pathD2D;
|
||||||
|
|
||||||
RefPtr<ID2D1Layer> layer;
|
|
||||||
pathD2D->mGeometry->GetBounds(clip.mTransform, &clip.mBounds);
|
pathD2D->mGeometry->GetBounds(clip.mTransform, &clip.mBounds);
|
||||||
|
|
||||||
|
clip.mLayer = GetCachedLayer();
|
||||||
|
|
||||||
mRT->CreateLayer( byRef(layer));
|
|
||||||
|
|
||||||
clip.mLayer = layer;
|
|
||||||
mPushedClips.push_back(clip);
|
mPushedClips.push_back(clip);
|
||||||
|
|
||||||
// The transform of clips is relative to the world matrix, since we use the total
|
// The transform of clips is relative to the world matrix, since we use the total
|
||||||
|
@ -971,7 +979,7 @@ DrawTargetD2D::PushClip(const Path *aPath)
|
||||||
mRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), pathD2D->mGeometry,
|
mRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), pathD2D->mGeometry,
|
||||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
||||||
clip.mTransform, 1.0f, NULL,
|
clip.mTransform, 1.0f, NULL,
|
||||||
options), layer);
|
options), clip.mLayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,7 +1023,7 @@ DrawTargetD2D::PopClip()
|
||||||
mCurrentClippedGeometry = NULL;
|
mCurrentClippedGeometry = NULL;
|
||||||
if (mClipsArePushed) {
|
if (mClipsArePushed) {
|
||||||
if (mPushedClips.back().mLayer) {
|
if (mPushedClips.back().mLayer) {
|
||||||
mRT->PopLayer();
|
PopCachedLayer(mRT);
|
||||||
} else {
|
} else {
|
||||||
mRT->PopAxisAlignedClip();
|
mRT->PopAxisAlignedClip();
|
||||||
}
|
}
|
||||||
|
@ -1286,6 +1294,32 @@ DrawTargetD2D::GetByteSize() const
|
||||||
return mSize.width * mSize.height * BytesPerPixel(mFormat);
|
return mSize.width * mSize.height * BytesPerPixel(mFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TemporaryRef<ID2D1Layer>
|
||||||
|
DrawTargetD2D::GetCachedLayer()
|
||||||
|
{
|
||||||
|
RefPtr<ID2D1Layer> layer;
|
||||||
|
|
||||||
|
if (mCurrentCachedLayer < 5) {
|
||||||
|
if (!mCachedLayers[mCurrentCachedLayer]) {
|
||||||
|
mRT->CreateLayer(byRef(mCachedLayers[mCurrentCachedLayer]));
|
||||||
|
mVRAMUsageDT += GetByteSize();
|
||||||
|
}
|
||||||
|
layer = mCachedLayers[mCurrentCachedLayer];
|
||||||
|
} else {
|
||||||
|
mRT->CreateLayer(byRef(layer));
|
||||||
|
}
|
||||||
|
|
||||||
|
mCurrentCachedLayer++;
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DrawTargetD2D::PopCachedLayer(ID2D1RenderTarget *aRT)
|
||||||
|
{
|
||||||
|
aRT->PopLayer();
|
||||||
|
mCurrentCachedLayer--;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DrawTargetD2D::InitD2DRenderTarget()
|
DrawTargetD2D::InitD2DRenderTarget()
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,6 +30,8 @@ class SourceSurfaceD2D;
|
||||||
class GradientStopsD2D;
|
class GradientStopsD2D;
|
||||||
class ScaledFontDWrite;
|
class ScaledFontDWrite;
|
||||||
|
|
||||||
|
const int32_t kLayerCacheSize = 5;
|
||||||
|
|
||||||
struct PrivateD3D10DataD2D
|
struct PrivateD3D10DataD2D
|
||||||
{
|
{
|
||||||
RefPtr<ID3D10Effect> mEffect;
|
RefPtr<ID3D10Effect> mEffect;
|
||||||
|
@ -122,6 +124,8 @@ public:
|
||||||
bool Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
|
bool Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
|
||||||
bool InitD3D10Data();
|
bool InitD3D10Data();
|
||||||
uint32_t GetByteSize() const;
|
uint32_t GetByteSize() const;
|
||||||
|
TemporaryRef<ID2D1Layer> GetCachedLayer();
|
||||||
|
void PopCachedLayer(ID2D1RenderTarget *aRT);
|
||||||
|
|
||||||
static ID2D1Factory *factory();
|
static ID2D1Factory *factory();
|
||||||
static TemporaryRef<ID2D1StrokeStyle> CreateStrokeStyleForOptions(const StrokeOptions &aStrokeOptions);
|
static TemporaryRef<ID2D1StrokeStyle> CreateStrokeStyleForOptions(const StrokeOptions &aStrokeOptions);
|
||||||
|
@ -219,6 +223,13 @@ private:
|
||||||
RefPtr<PathD2D> mPath;
|
RefPtr<PathD2D> mPath;
|
||||||
};
|
};
|
||||||
std::vector<PushedClip> mPushedClips;
|
std::vector<PushedClip> mPushedClips;
|
||||||
|
|
||||||
|
// We cache ID2D1Layer objects as it causes D2D to keep around textures that
|
||||||
|
// serve as the temporary surfaces for these operations. As texture creation
|
||||||
|
// is quite expensive this considerably improved performance.
|
||||||
|
// Careful here, RAII will not ensure destruction of the RefPtrs.
|
||||||
|
RefPtr<ID2D1Layer> mCachedLayers[kLayerCacheSize];
|
||||||
|
uint32_t mCurrentCachedLayer;
|
||||||
|
|
||||||
// The latest snapshot of this surface. This needs to be told when this
|
// The latest snapshot of this surface. This needs to be told when this
|
||||||
// target is modified. We keep it alive as a cache.
|
// target is modified. We keep it alive as a cache.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче