painter.setDrawRegion(
VRect(int(surface.drawRegionPosX()), int(surface.drawRegionPosY()),
int(surface.drawRegionWidth()), int(surface.drawRegionHeight())));
- mRootLayer->render(&painter, {}, {});
+ mRootLayer->render(&painter, {}, {}, mSurfaceCache);
painter.end();
return true;
}
}
void LOTLayerItem::render(VPainter *painter, const VRle &inheritMask,
- const VRle &matteRle)
+ const VRle &matteRle, SurfaceCache& cache)
{
auto renderlist = renderList();
}
void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask,
- const VRle &matteRle)
+ const VRle &matteRle, SurfaceCache& cache)
{
if (vIsZero(combinedAlpha())) return;
if (vCompare(combinedAlpha(), 1.0)) {
- renderHelper(painter, inheritMask, matteRle);
+ renderHelper(painter, inheritMask, matteRle, cache);
} else {
if (complexContent()) {
VSize size = painter->clipBoundingRect().size();
VPainter srcPainter;
- VBitmap srcBitmap(size.width(), size.height(),
- VBitmap::Format::ARGB32_Premultiplied);
+ VBitmap srcBitmap = cache.make_surface(size.width(), size.height());
srcPainter.begin(&srcBitmap);
- renderHelper(&srcPainter, inheritMask, matteRle);
+ renderHelper(&srcPainter, inheritMask, matteRle, cache);
srcPainter.end();
painter->drawBitmap(VPoint(), srcBitmap, uchar(combinedAlpha() * 255.0f));
+ cache.release_surface(srcBitmap);
} else {
- renderHelper(painter, inheritMask, matteRle);
+ renderHelper(painter, inheritMask, matteRle, cache);
}
}
}
void LOTCompLayerItem::renderHelper(VPainter *painter, const VRle &inheritMask,
- const VRle &matteRle)
+ const VRle &matteRle, SurfaceCache& cache)
{
VRle mask;
if (mLayerMask) {
if (matte) {
if (matte->visible())
renderMatteLayer(painter, mask, matteRle, matte,
- layer);
+ layer, cache);
} else {
- layer->render(painter, mask, matteRle);
+ layer->render(painter, mask, matteRle, cache);
}
}
matte = nullptr;
void LOTCompLayerItem::renderMatteLayer(VPainter *painter, const VRle &mask,
const VRle & matteRle,
- LOTLayerItem *layer, LOTLayerItem *src)
+ LOTLayerItem *layer, LOTLayerItem *src, SurfaceCache& cache)
{
VSize size = painter->clipBoundingRect().size();
// Decide if we can use fast matte.
// 1. draw src layer to matte buffer
VPainter srcPainter;
- src->bitmap().reset(size.width(), size.height(),
- VBitmap::Format::ARGB32_Premultiplied);
- srcPainter.begin(&src->bitmap());
- src->render(&srcPainter, mask, matteRle);
+ VBitmap srcBitmap = cache.make_surface(size.width(), size.height());
+ srcPainter.begin(&srcBitmap);
+ src->render(&srcPainter, mask, matteRle, cache);
srcPainter.end();
// 2. draw layer to layer buffer
VPainter layerPainter;
- layer->bitmap().reset(size.width(), size.height(),
- VBitmap::Format::ARGB32_Premultiplied);
- layerPainter.begin(&layer->bitmap());
- layer->render(&layerPainter, mask, matteRle);
+ VBitmap layerBitmap = cache.make_surface(size.width(), size.height());
+ layerPainter.begin(&layerBitmap);
+ layer->render(&layerPainter, mask, matteRle, cache);
// 2.1update composition mode
switch (layer->matteType()) {
// 2.2 update srcBuffer if the matte is luma type
if (layer->matteType() == MatteType::Luma ||
layer->matteType() == MatteType::LumaInv) {
- src->bitmap().updateLuma();
+ srcBitmap.updateLuma();
}
// 2.3 draw src buffer as mask
- layerPainter.drawBitmap(VPoint(), src->bitmap());
+ layerPainter.drawBitmap(VPoint(), srcBitmap);
layerPainter.end();
// 3. draw the result buffer into painter
- painter->drawBitmap(VPoint(), layer->bitmap());
+ painter->drawBitmap(VPoint(), layerBitmap);
+
+ cache.release_surface(srcBitmap);
+ cache.release_surface(layerBitmap);
}
void LOTClipperItem::update(const VMatrix &matrix)
}
};
+class SurfaceCache
+{
+public:
+ SurfaceCache(){mCache.reserve(10);}
+
+ VBitmap make_surface(size_t width, size_t height, VBitmap::Format format=VBitmap::Format::ARGB32_Premultiplied)
+ {
+ if (mCache.empty()) return {width, height, format};
+
+ auto surface = mCache.back();
+ surface.reset(width, height, format);
+
+ mCache.pop_back();
+ return surface;
+ }
+
+ void release_surface(VBitmap& surface)
+ {
+ mCache.push_back(surface);
+ }
+
+private:
+ std::vector<VBitmap> mCache;
+};
+
class LOTCompItem
{
public:
bool render(const rlottie::Surface &surface);
void setValue(const std::string &keypath, LOTVariant &value);
private:
+ SurfaceCache mSurfaceCache;
VBitmap mSurface;
VMatrix mScaleMatrix;
VSize mViewSize;
VMatrix matrix(int frameNo) const;
void preprocess(const VRect& clip);
virtual DrawableList renderList(){ return {};}
- virtual void render(VPainter *painter, const VRle &mask, const VRle &matteRle);
+ virtual void render(VPainter *painter, const VRle &mask, const VRle &matteRle, SurfaceCache& cache);
bool hasMatte() { if (mLayerData->mMatteType == MatteType::None) return false; return true; }
MatteType matteType() const { return mLayerData->mMatteType;}
bool visible() const;
std::vector<LOTNode *>& cnodes() {return mCApiData->mCNodeList;}
const char* name() const {return mLayerData->name();}
virtual bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value);
- VBitmap& bitmap() {return mRenderBuffer;}
protected:
virtual void preprocessStage(const VRect& clip) = 0;
virtual void updateContent() = 0;
LOTLayerData *mLayerData{nullptr};
LOTLayerItem *mParentLayer{nullptr};
VMatrix mCombinedMatrix;
- VBitmap mRenderBuffer;
float mCombinedAlpha{0.0};
int mFrameNo{-1};
DirtyFlag mDirtyFlag{DirtyFlagBit::All};
public:
explicit LOTCompLayerItem(LOTLayerData *layerData, VArenaAlloc* allocator);
- void render(VPainter *painter, const VRle &mask, const VRle &matteRle) final;
+ void render(VPainter *painter, const VRle &mask, const VRle &matteRle, SurfaceCache& cache) final;
void buildLayerNode() final;
bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value) override;
protected:
void preprocessStage(const VRect& clip) final;
void updateContent() final;
private:
- void renderHelper(VPainter *painter, const VRle &mask, const VRle &matteRle);
+ void renderHelper(VPainter *painter, const VRle &mask, const VRle &matteRle, SurfaceCache& cache);
void renderMatteLayer(VPainter *painter, const VRle &inheritMask, const VRle &matteRle,
- LOTLayerItem *layer, LOTLayerItem *src);
+ LOTLayerItem *layer, LOTLayerItem *src, SurfaceCache& cache);
private:
std::vector<LOTLayerItem*> mLayers;
std::unique_ptr<LOTClipperItem> mClipper;