Skip to content

Commit

Permalink
Cache the bounds in LayerContents for text and shape layers. (#340)
Browse files Browse the repository at this point in the history
  • Loading branch information
domchen authored Nov 26, 2024
1 parent 297a650 commit 2bf38d0
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 29 deletions.
15 changes: 10 additions & 5 deletions include/tgfx/gpu/RuntimeEffect.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ class RuntimeEffect {
* to define the UniqueType. The UniqueType should be static for each effect class, ensuring all
* instances of the same class share the same UniqueType. This allows the RuntimeProgram created
* by the effect to be cached and reused.
* @param type The UniqueType of the effect. Must use the DEFINE_RUNTIME_EFFECT_TYPE macro to define it.
* @param extraInputs Represents a collection of additional input images that will be used during rendering.
* When onDraw is called, these extraInputs will be converted to inputTextures. The inputTextures[0] is
* the source of ImageFilter, and extraInputs correspond to inputTextures[1...n] in order.
* @param type The UniqueType of the effect. Must use the DEFINE_RUNTIME_EFFECT_TYPE macro to
* define it.
* @param extraInputs A collection of additional input images used during rendering. When the
* onDraw() method is called, these extraInputs will be converted to inputTextures.
* inputTextures[0] represents the source image for the ImageFilter, and extraInputs correspond to
* inputTextures[1...n] in order.
*/
explicit RuntimeEffect(UniqueType type,
const std::vector<std::shared_ptr<Image>>& extraInputs = {});
Expand Down Expand Up @@ -82,13 +84,16 @@ class RuntimeEffect {

/**
* Applies the effect to the input textures and draws the result to the specified render target.
* The inputTextures[0] is the source of ImageFilter, and extraInputs correspond to inputTextures[1...n] in order.
* inputTextures[0] represents the source image for the ImageFilter, and extraInputs correspond to
* inputTextures[1...n] in order.
*/
virtual bool onDraw(const RuntimeProgram* program,
const std::vector<BackendTexture>& inputTextures,
const BackendRenderTarget& target, const Point& offset) const = 0;

private:
// Each effect instance holds a valid reference to the UniqueType, so the corresponding
// RuntimeProgram will not be released.
UniqueType uniqueType = {};

std::vector<std::shared_ptr<Image>> extraInputs;
Expand Down
18 changes: 9 additions & 9 deletions include/tgfx/layers/Layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -525,28 +525,28 @@ class Layer {

bool hasValidMask() const;

struct {
bool contentDirty : 1; // need to update content
bool childrenDirty : 1; // need to redraw child layers
bool visible : 1;
bool shouldRasterize : 1;
bool allowsEdgeAntialiasing : 1;
bool allowsGroupOpacity : 1;
} bitFields = {};
std::string _name;
float _alpha = 1.0f;
BlendMode _blendMode = BlendMode::SrcOver;
Matrix _matrix = Matrix::I();
float _rasterizationScale = 1.0f;
std::vector<std::shared_ptr<LayerFilter>> _filters = {};
std::shared_ptr<Layer> _mask = nullptr;
Layer* maskOwner = nullptr;
std::unique_ptr<Rect> _scrollRect = nullptr;
Layer* _root = nullptr;
Layer* _parent = nullptr;
Layer* maskOwner = nullptr;
std::unique_ptr<LayerContent> layerContent = nullptr;
std::unique_ptr<LayerContent> rasterizedContent = nullptr;
std::vector<std::shared_ptr<Layer>> _children = {};
struct {
bool contentDirty : 1; // need to update content
bool childrenDirty : 1; // need to redraw child layers
bool visible : 1;
bool shouldRasterize : 1;
bool allowsEdgeAntialiasing : 1;
bool allowsGroupOpacity : 1;
} bitFields = {};

friend class DisplayList;
friend class LayerProperty;
Expand Down
3 changes: 1 addition & 2 deletions src/layers/contents/ShapeContent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

namespace tgfx {
ShapeContent::ShapeContent(std::shared_ptr<Shape> shape, std::shared_ptr<Shader> shader)
: shape(std::move(shape)), shader(std::move(shader)) {
: bounds(shape->getBounds()), shape(std::move(shape)), shader(std::move(shader)) {
}

void ShapeContent::draw(Canvas* canvas, const Paint& paint) const {
Expand All @@ -36,7 +36,6 @@ bool ShapeContent::hitTestPoint(float localX, float localY, bool pixelHitTest) {
auto path = shape->getPath();
return path.contains(localX, localY);
}
const auto bounds = shape->getBounds();
return bounds.contains(localX, localY);
}
} // namespace tgfx
4 changes: 2 additions & 2 deletions src/layers/contents/ShapeContent.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ class ShapeContent : public LayerContent {
ShapeContent(std::shared_ptr<Shape> shape, std::shared_ptr<Shader> shader);

Rect getBounds() const override {
TRACE_EVENT;
return shape->getBounds();
return bounds;
}

void draw(Canvas* canvas, const Paint& paint) const override;

bool hitTestPoint(float localX, float localY, bool pixelHitTest) override;

private:
Rect bounds = Rect::MakeEmpty();
std::shared_ptr<Shape> shape = nullptr;
std::shared_ptr<Shader> shader = nullptr;
};
Expand Down
2 changes: 1 addition & 1 deletion src/layers/contents/SolidContent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
/////////////////////////////////////////////////////////////////////////////////////////////////

#include "SolidContent.h"
#include <tgfx/layers/SolidLayer.h>
#include "core/utils/Profiling.h"

namespace tgfx {
SolidContent::SolidContent(const RRect& rRect, const Color& color) : _rRect(rRect), _color(color) {
Expand Down
1 change: 0 additions & 1 deletion src/layers/contents/SolidContent.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

#pragma once

#include "core/utils/Profiling.h"
#include "tgfx/layers/LayerContent.h"

namespace tgfx {
Expand Down
8 changes: 3 additions & 5 deletions src/layers/contents/TextContent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@
#include "core/utils/Profiling.h"

namespace tgfx {
Rect TextContent::getBounds() const {
TRACE_EVENT;
return textBlob->getBounds();
TextContent::TextContent(std::shared_ptr<TextBlob> textBlob, Color textColor)
: bounds(textBlob->getBounds()), textBlob(std::move(textBlob)), textColor(textColor) {
}

void TextContent::draw(Canvas* canvas, const Paint& paint) const {
Expand Down Expand Up @@ -53,8 +52,7 @@ bool TextContent::hitTestPoint(float localX, float localY, bool pixelHitTest) {
return false;
}

const Rect textBounds = textBlob->getBounds();
return textBounds.contains(localX, localY);
return bounds.contains(localX, localY);
}

bool TextContent::hitTestPointInternal(float localX, float localY,
Expand Down
9 changes: 5 additions & 4 deletions src/layers/contents/TextContent.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@
namespace tgfx {
class TextContent : public LayerContent {
public:
TextContent(std::shared_ptr<TextBlob> textBlob, Color textColor)
: textBlob(std::move(textBlob)), textColor(textColor) {
}
TextContent(std::shared_ptr<TextBlob> textBlob, Color textColor);

Rect getBounds() const override;
Rect getBounds() const override {
return bounds;
}

void draw(Canvas* canvas, const Paint& paint) const override;

bool hitTestPoint(float localX, float localY, bool pixelHitTest) override;

private:
Rect bounds = Rect::MakeEmpty();
std::shared_ptr<TextBlob> textBlob = nullptr;
Color textColor = Color::White();

Expand Down

0 comments on commit 2bf38d0

Please sign in to comment.