Skip to content

Commit

Permalink
LayerStyle supports deferred rendering. (#2607)
Browse files Browse the repository at this point in the history
Co-authored-by: libpag <[email protected]>
  • Loading branch information
Hparty and libpag-pag authored Dec 11, 2024
1 parent 504de7f commit 238ff8e
Show file tree
Hide file tree
Showing 27 changed files with 1,700 additions and 1,504 deletions.
8 changes: 1 addition & 7 deletions src/rendering/caches/RenderCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,12 +568,6 @@ void RenderCache::clearSequenceCache(ID uniqueID) {

//===================================== filter caches =====================================

LayerFilter* RenderCache::getFilterCache(LayerStyle* layerStyle) {
return getLayerFilterCache(layerStyle->uniqueID, [=]() -> LayerFilter* {
return LayerFilter::Make(layerStyle).release();
});
}

LayerFilter* RenderCache::getFilterCache(Effect* effect) {
return getLayerFilterCache(effect->uniqueID,
[=]() -> LayerFilter* { return LayerFilter::Make(effect).release(); });
Expand Down Expand Up @@ -620,7 +614,7 @@ LayerStylesFilter* RenderCache::getLayerStylesFilter(Layer* layer) {
LayerStylesFilter* filter = nullptr;
auto result = filterCaches.find(layer->uniqueID);
if (result == filterCaches.end()) {
filter = new LayerStylesFilter(this);
filter = new LayerStylesFilter();
if (initFilter(filter)) {
filterCaches.insert(std::make_pair(layer->uniqueID, filter));
} else {
Expand Down
2 changes: 0 additions & 2 deletions src/rendering/caches/RenderCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@ class RenderCache : public Performance {
std::shared_ptr<tgfx::Image> getSequenceImage(std::shared_ptr<SequenceInfo> sequence,
Frame targetFrame);

LayerFilter* getFilterCache(LayerStyle* layerStyle);

LayerFilter* getFilterCache(Effect* effect);

MotionBlurFilter* getMotionBlurFilter();
Expand Down
2 changes: 1 addition & 1 deletion src/rendering/filters/Filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#pragma once

#include <array>
#include "tgfx/core/Matrix.h"
#include "tgfx/core/Point.h"
#include "tgfx/gpu/Backend.h"
#include "tgfx/gpu/Context.h"

Expand Down
24 changes: 0 additions & 24 deletions src/rendering/filters/LayerFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include "BulgeFilter.h"
#include "CornerPinFilter.h"
#include "DisplacementMapFilter.h"
#include "GradientOverlayFilter.h"
#include "HueSaturationFilter.h"
#include "LevelsIndividualFilter.h"
#include "MosaicFilter.h"
Expand All @@ -30,8 +29,6 @@
#include "rendering/filters/gaussianblur/GaussianBlurFilter.h"
#include "rendering/filters/glow/GlowFilter.h"
#include "rendering/filters/layerstyle/DropShadowFilter.h"
#include "rendering/filters/layerstyle/OuterGlowFilter.h"
#include "rendering/filters/layerstyle/StrokeFilter.h"
#include "rendering/filters/utils/FilterHelper.h"

namespace pag {
Expand Down Expand Up @@ -116,27 +113,6 @@ void FilterProgram::onReleaseGPU() {
}
}

std::unique_ptr<LayerFilter> LayerFilter::Make(LayerStyle* layerStyle) {
LayerFilter* filter = nullptr;
switch (layerStyle->type()) {
case LayerStyleType::DropShadow:
filter = new DropShadowFilter(reinterpret_cast<DropShadowStyle*>(layerStyle));
break;
case LayerStyleType::OuterGlow:
filter = new OuterGlowFilter(reinterpret_cast<OuterGlowStyle*>(layerStyle));
break;
case LayerStyleType::Stroke:
filter = new StrokeFilter(reinterpret_cast<StrokeStyle*>(layerStyle));
break;
case LayerStyleType::GradientOverlay:
filter = new GradientOverlayFilter(reinterpret_cast<GradientOverlayStyle*>(layerStyle));
break;
default:
break;
}
return std::unique_ptr<LayerFilter>(filter);
}

std::unique_ptr<LayerFilter> LayerFilter::Make(Effect* effect) {
LayerFilter* filter = nullptr;
switch (effect->type()) {
Expand Down
2 changes: 0 additions & 2 deletions src/rendering/filters/LayerFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ class FilterProgram : public tgfx::GLResource {

class LayerFilter : public Filter {
public:
static std::unique_ptr<LayerFilter> Make(LayerStyle* layerStyle);

static std::unique_ptr<LayerFilter> Make(Effect* effect);

bool initialize(tgfx::Context* context) override;
Expand Down
55 changes: 31 additions & 24 deletions src/rendering/filters/LayerStylesFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
/////////////////////////////////////////////////////////////////////////////////////////////////

#include "LayerStylesFilter.h"
#include "layerstyle/LayerStyleFilter.h"
#include "rendering/caches/RenderCache.h"
#include "rendering/renderers/FilterRenderer.h"
#include "tgfx/core/Surface.h"

namespace pag {
void LayerStylesFilter::TransformBounds(tgfx::Rect* bounds, const FilterList* filterList) {
Expand All @@ -31,55 +33,60 @@ void LayerStylesFilter::TransformBounds(tgfx::Rect* bounds, const FilterList* fi
}
}

LayerStylesFilter::LayerStylesFilter(RenderCache* renderCache) : renderCache(renderCache) {
drawFilter = new LayerFilter();
bool LayerStylesFilter::initialize(tgfx::Context*) {
return true;
}

LayerStylesFilter::~LayerStylesFilter() {
delete drawFilter;
}

bool LayerStylesFilter::initialize(tgfx::Context* context) {
return drawFilter->initialize(context);
}

void LayerStylesFilter::update(const FilterList* list, const tgfx::Rect& inputBounds,
const tgfx::Rect& outputBounds, const tgfx::Point& extraScale) {
void LayerStylesFilter::update(const FilterList* list, const tgfx::Point& extraScale) {
filterList = list;
contentBounds = inputBounds;
transformedBounds = outputBounds;
filterScale = extraScale;
}

void LayerStylesFilter::draw(tgfx::Context* context, const FilterSource* source,
const FilterTarget* target) {
tgfx::BackendTexture backendTexture = {source->sampler, source->width, source->height};
auto sourceMatrix = ToMatrix(source->textureMatrix);
auto origin = tgfx::ImageOrigin::TopLeft;
if (!sourceMatrix.isIdentity()) {
origin = tgfx::ImageOrigin::BottomLeft;
}
auto sourceImage = tgfx::Image::MakeFrom(context, backendTexture, origin);
if (sourceImage == nullptr) {
return;
}

tgfx::BackendRenderTarget renderTarget = {target->frameBuffer, target->width, target->height};
auto surface = tgfx::Surface::MakeFrom(context, renderTarget, tgfx::ImageOrigin::TopLeft);
if (surface == nullptr) {
return;
}
auto canvas = surface->getCanvas();
canvas->concat(ToMatrix(target));
for (auto& layerStyle : filterList->layerStyles) {
if (layerStyle->drawPosition() == LayerStylePosition::Blow) {
auto filter = renderCache->getFilterCache(layerStyle);
auto filter = LayerStyleFilter::Make(layerStyle);
if (filter) {
filter->update(filterList->layerFrame, contentBounds, transformedBounds, filterScale);
filter->draw(context, source, target);
filter->update(filterList->layerFrame, filterScale, source->scale);
filter->draw(canvas, sourceImage);
}
}
}

// The above layer style is only GradientOverlayFilter, and the GradientOverlayFilter has drawn
// the source with blend.
// The filter above source will draw the source with blend.
bool drawSource = true;
for (auto& layerStyle : filterList->layerStyles) {
if (layerStyle->drawPosition() == LayerStylePosition::Above) {
auto filter = renderCache->getFilterCache(layerStyle);
auto filter = LayerStyleFilter::Make(layerStyle);
if (filter) {
filter->update(filterList->layerFrame, contentBounds, transformedBounds, filterScale);
filter->draw(context, source, target);
filter->update(filterList->layerFrame, filterScale, source->scale);
filter->draw(canvas, sourceImage);
drawSource = false;
}
}
}

if (drawSource) {
drawFilter->update(filterList->layerFrame, contentBounds, contentBounds, filterScale);
drawFilter->draw(context, source, target);
canvas->drawImage(sourceImage);
}
}
} // namespace pag
13 changes: 1 addition & 12 deletions src/rendering/filters/LayerStylesFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,21 @@
#include "rendering/filters/LayerFilter.h"

namespace pag {
class RenderCache;

struct FilterList;

class LayerStylesFilter : public Filter {
public:
static void TransformBounds(tgfx::Rect* bounds, const FilterList* filterList);

explicit LayerStylesFilter(RenderCache* renderCache);

~LayerStylesFilter() override;

bool initialize(tgfx::Context* context) override;

void update(const FilterList* filterList, const tgfx::Rect& contentBounds,
const tgfx::Rect& transformedBounds, const tgfx::Point& filterScale);
void update(const FilterList* filterList, const tgfx::Point& filterScale);

void draw(tgfx::Context* context, const FilterSource* source,
const FilterTarget* target) override;

private:
const FilterList* filterList = nullptr;
RenderCache* renderCache = nullptr;
LayerFilter* drawFilter = nullptr;
tgfx::Rect contentBounds = {};
tgfx::Rect transformedBounds = {};
tgfx::Point filterScale = {};
};
} // namespace pag
Loading

0 comments on commit 238ff8e

Please sign in to comment.