Skip to content

Commit

Permalink
Determine the rasterization type of paths during the rendering stage. (
Browse files Browse the repository at this point in the history
  • Loading branch information
domchen authored Nov 11, 2024
1 parent cced96a commit 0ee494a
Show file tree
Hide file tree
Showing 75 changed files with 1,265 additions and 750 deletions.
2 changes: 1 addition & 1 deletion include/tgfx/core/Mask.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,6 @@ class Mask {
bool fillText(const GlyphRunList* glyphRunList, const Stroke* stroke = nullptr);

friend class ImageReader;
friend class TextRasterizer;
friend class GlyphRasterizer;
};
} // namespace tgfx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// Tencent is pleased to support the open source community by making tgfx available.
//
// Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
Expand All @@ -16,15 +16,23 @@
//
/////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

#include "gpu/tasks/ResourceTask.h"
#include "DataProvider.h"

namespace tgfx {
class GLVertexArrayCreateTask : public ResourceTask {
class DataWrapper : public DataProvider {
public:
explicit GLVertexArrayCreateTask(UniqueKey uniqueKey);
explicit DataWrapper(std::shared_ptr<Data> data) : data(std::move(data)) {
}

std::shared_ptr<Data> getData() const override {
return data;
}

std::shared_ptr<Resource> onMakeResource(Context* context) override;
private:
std::shared_ptr<Data> data = nullptr;
};
} // namespace tgfx

std::shared_ptr<DataProvider> DataProvider::Wrap(std::shared_ptr<Data> data) {
return std::make_shared<DataWrapper>(std::move(data));
}
} // namespace tgfx
5 changes: 5 additions & 0 deletions src/core/DataProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ namespace tgfx {
*/
class DataProvider {
public:
/**
* Wraps the existing data into a DataProvider.
*/
static std::shared_ptr<DataProvider> Wrap(std::shared_ptr<Data> data);

virtual ~DataProvider() = default;

/**
Expand Down
22 changes: 5 additions & 17 deletions src/core/ImageDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
/////////////////////////////////////////////////////////////////////////////////////////////////

#include "ImageDecoder.h"
#include "tgfx/core/Task.h"
#include "core/utils/DataTask.h"

namespace tgfx {

Expand Down Expand Up @@ -74,22 +74,12 @@ class ImageGeneratorWrapper : public ImageDecoder {
bool tryHardware = true;
};

struct ImageBufferHolder {
std::shared_ptr<ImageBuffer> imageBuffer;
};

class AsyncImageDecoder : public ImageDecoder {
public:
AsyncImageDecoder(std::shared_ptr<ImageGenerator> generator, bool tryHardware)
: imageGenerator(std::move(generator)) {
holder = std::make_shared<ImageBufferHolder>();
task = Task::Run([result = holder, generator = imageGenerator, tryHardware]() {
result->imageBuffer = generator->makeBuffer(tryHardware);
});
}

~AsyncImageDecoder() override {
task->cancel();
task = DataTask<ImageBuffer>::Run(
[generator = imageGenerator, tryHardware]() { return generator->makeBuffer(tryHardware); });
}

int width() const override {
Expand All @@ -105,14 +95,12 @@ class AsyncImageDecoder : public ImageDecoder {
}

std::shared_ptr<ImageBuffer> decode() const override {
task->wait();
return holder->imageBuffer;
return task->wait();
}

private:
std::shared_ptr<ImageGenerator> imageGenerator = nullptr;
std::shared_ptr<ImageBufferHolder> holder = nullptr;
std::shared_ptr<Task> task = nullptr;
std::shared_ptr<DataTask<ImageBuffer>> task = nullptr;
};

std::shared_ptr<ImageDecoder> ImageDecoder::Wrap(std::shared_ptr<ImageBuffer> imageBuffer) {
Expand Down
2 changes: 1 addition & 1 deletion src/core/ImageFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ std::shared_ptr<TextureProxy> ImageFilter::lockTextureProxy(std::shared_ptr<Imag
if (!processor) {
return nullptr;
}
OpContext opContext(renderTarget);
OpContext opContext(renderTarget, args.renderFlags);
opContext.fillWithFP(std::move(processor), Matrix::I(), true);
return renderTarget->getTextureProxy();
}
Expand Down
1 change: 0 additions & 1 deletion src/core/Mask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "tgfx/core/Mask.h"
#include "core/GlyphRunList.h"
#include "core/ImageStream.h"
#include "tgfx/core/PathEffect.h"

namespace tgfx {
void Mask::fillPath(const Path& path, const Stroke* stroke) {
Expand Down
2 changes: 1 addition & 1 deletion src/core/Matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void Matrix::setTranslate(float tx, float ty) {
}
}

static inline float sdot(float a, float b, float c, float d) {
inline float sdot(float a, float b, float c, float d) {
return a * b + c * d;
}

Expand Down
4 changes: 2 additions & 2 deletions src/core/Pixmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@

namespace tgfx {

static inline void* AddOffset(void* pixels, size_t offset) {
inline void* AddOffset(void* pixels, size_t offset) {
return reinterpret_cast<uint8_t*>(pixels) + offset;
}

static inline const void* AddOffset(const void* pixels, size_t offset) {
inline const void* AddOffset(const void* pixels, size_t offset) {
return reinterpret_cast<const uint8_t*>(pixels) + offset;
}

Expand Down
55 changes: 13 additions & 42 deletions src/core/Rasterizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,55 +19,37 @@
#include "Rasterizer.h"

namespace tgfx {
class TextRasterizer : public Rasterizer {
class GlyphRasterizer : public Rasterizer {
public:
TextRasterizer(std::shared_ptr<GlyphRunList> glyphRunList, const ISize& clipSize,
const Matrix& matrix, bool antiAlias, const Stroke* stroke)
GlyphRasterizer(std::shared_ptr<GlyphRunList> glyphRunList, const ISize& clipSize,
const Matrix& matrix, bool antiAlias, const Stroke* stroke)
: Rasterizer(clipSize, matrix, antiAlias, stroke), glyphRunList(std::move(glyphRunList)) {
}

protected:
void onRasterize(Mask* mask, const Stroke* stroke) const override {
std::shared_ptr<ImageBuffer> onMakeBuffer(bool tryHardware) const override {
auto mask = Mask::Make(width(), height(), tryHardware);
if (!mask) {
return nullptr;
}
mask->setAntiAlias(antiAlias);
mask->setMatrix(matrix);
mask->fillText(glyphRunList.get(), stroke);
return mask->makeBuffer();
}

private:
std::shared_ptr<GlyphRunList> glyphRunList = nullptr;
};

class PathRasterizer : public Rasterizer {
public:
PathRasterizer(Path path, const ISize& clipSize, const Matrix& matrix, bool antiAlias,
const Stroke* stroke)
: Rasterizer(clipSize, matrix, antiAlias, stroke), path(std::move(path)) {
}

protected:
void onRasterize(Mask* mask, const Stroke* stroke) const override {
mask->fillPath(path, stroke);
}

private:
Path path = {};
};

std::shared_ptr<Rasterizer> Rasterizer::MakeFrom(std::shared_ptr<GlyphRunList> glyphRunList,
const ISize& clipSize, const Matrix& matrix,
bool antiAlias, const Stroke* stroke) {
if (glyphRunList == nullptr || clipSize.isEmpty()) {
return nullptr;
}
return std::make_shared<TextRasterizer>(std::move(glyphRunList), clipSize, matrix, antiAlias,
stroke);
}

std::shared_ptr<Rasterizer> Rasterizer::MakeFrom(Path path, const ISize& clipSize,
const Matrix& matrix, bool antiAlias,
const Stroke* stroke) {
if (path.isEmpty() || clipSize.isEmpty()) {
return nullptr;
}
return std::make_shared<PathRasterizer>(std::move(path), clipSize, matrix, antiAlias, stroke);
return std::make_shared<GlyphRasterizer>(std::move(glyphRunList), clipSize, matrix, antiAlias,
stroke);
}

Rasterizer::Rasterizer(const ISize& clipSize, const Matrix& matrix, bool antiAlias, const Stroke* s)
Expand All @@ -88,15 +70,4 @@ bool Rasterizer::asyncSupport() const {
return true;
#endif
}

std::shared_ptr<ImageBuffer> Rasterizer::onMakeBuffer(bool tryHardware) const {
auto mask = Mask::Make(width(), height(), tryHardware);
if (!mask) {
return nullptr;
}
mask->setAntiAlias(antiAlias);
mask->setMatrix(matrix);
onRasterize(mask.get(), stroke);
return mask->makeBuffer();
}
} // namespace tgfx
26 changes: 11 additions & 15 deletions src/core/Rasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,28 @@
#include "tgfx/core/Mask.h"

namespace tgfx {
class ShapeRasterizer;

/**
* An ImageGenerator that can take vector graphics (paths, texts) and convert them into a raster
* image.
* Rasterizer is the base class for converting vector graphics (shapes and glyphs) into their
* rasterized forms.
*/
class Rasterizer : public ImageGenerator {
public:
/**
* Creates a Rasterizer from a TextBlob.
* Creates a Rasterizer from a GlyphRunList.
*/
static std::shared_ptr<Rasterizer> MakeFrom(std::shared_ptr<GlyphRunList> glyphRunList,
const ISize& clipSize, const Matrix& matrix,
bool antiAlias, const Stroke* stroke = nullptr);

/**
* Creates a Rasterizer from a Path.
*/
static std::shared_ptr<Rasterizer> MakeFrom(Path path, const ISize& clipSize,
const Matrix& matrix, bool antiAlias,
const Stroke* stroke = nullptr);
static std::shared_ptr<ShapeRasterizer> MakeFrom(Path path, const ISize& clipSize,
const Matrix& matrix, bool antiAlias,
const Stroke* stroke = nullptr);

virtual ~Rasterizer();
~Rasterizer() override;

bool isAlphaOnly() const override {
return true;
Expand All @@ -52,15 +53,10 @@ class Rasterizer : public ImageGenerator {
bool asyncSupport() const override;

protected:
Rasterizer(const ISize& clipSize, const Matrix& matrix, bool antiAlias, const Stroke* stroke);

std::shared_ptr<ImageBuffer> onMakeBuffer(bool tryHardware) const override;

virtual void onRasterize(Mask* mask, const Stroke* stroke) const = 0;

private:
Matrix matrix = Matrix::I();
bool antiAlias = true;
Stroke* stroke = nullptr;

Rasterizer(const ISize& clipSize, const Matrix& matrix, bool antiAlias, const Stroke* stroke);
};
} // namespace tgfx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// Tencent is pleased to support the open source community by making tgfx available.
//
// Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
Expand All @@ -16,19 +16,20 @@
//
/////////////////////////////////////////////////////////////////////////////////////////////////

#include "GLVertexArrayCreateTask.h"
#include "GLVertexArray.h"
#include "ShapeBuffer.h"

namespace tgfx {
GLVertexArrayCreateTask::GLVertexArrayCreateTask(UniqueKey uniqueKey)
: ResourceTask(std::move(uniqueKey)) {
std::shared_ptr<ShapeBuffer> ShapeBuffer::MakeFrom(std::shared_ptr<Data> triangles) {
if (triangles == nullptr || triangles->empty()) {
return nullptr;
}
return std::shared_ptr<ShapeBuffer>(new ShapeBuffer(std::move(triangles)));
}

std::shared_ptr<Resource> GLVertexArrayCreateTask::onMakeResource(Context* context) {
auto vertexArray = GLVertexArray::Make(context);
if (vertexArray == nullptr) {
LOGE("GLVertexArrayCreateTask::onMakeResource() Failed to create the vertex array!");
std::shared_ptr<ShapeBuffer> ShapeBuffer::MakeFrom(std::shared_ptr<ImageBuffer> imageBuffer) {
if (imageBuffer == nullptr) {
return nullptr;
}
return vertexArray;
return std::shared_ptr<ShapeBuffer>(new ShapeBuffer(std::move(imageBuffer)));
}
} // namespace tgfx
68 changes: 68 additions & 0 deletions src/core/ShapeBuffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Tencent is pleased to support the open source community by making tgfx available.
//
// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// unless required by applicable law or agreed to in writing, software distributed under the
// license is distributed on an "as is" basis, without warranties or conditions of any kind,
// either express or implied. see the license for the specific language governing permissions
// and limitations under the license.
//
/////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

#include "tgfx/core/Data.h"
#include "tgfx/core/ImageBuffer.h"

namespace tgfx {
/**
* ShapeBuffer is a container for the rasterized shape data, either as triangles or as an image
* buffer.
*/
class ShapeBuffer {
public:
/**
* Creates a new ShapeBuffer from a set of triangles. Returns nullptr if the triangles are empty.
*/
static std::shared_ptr<ShapeBuffer> MakeFrom(std::shared_ptr<Data> triangles);

/**
* Creates a new ShapeBuffer from an image buffer. Returns nullptr if the image buffer is nullptr.
*/
static std::shared_ptr<ShapeBuffer> MakeFrom(std::shared_ptr<ImageBuffer> imageBuffer);

/**
* Returns the triangles data of the shape buffer. Returns nullptr if the shape buffer is backed
* by an image buffer.
*/
std::shared_ptr<Data> triangles() const {
return _triangles;
}

/**
* Returns the image buffer of the shape buffer. Returns nullptr if the shape buffer is backed by
* triangles.
*/
std::shared_ptr<ImageBuffer> imageBuffer() const {
return _imageBuffer;
}

private:
std::shared_ptr<Data> _triangles = nullptr;
std::shared_ptr<ImageBuffer> _imageBuffer = nullptr;

explicit ShapeBuffer(std::shared_ptr<Data> triangles) : _triangles(std::move(triangles)) {
}

explicit ShapeBuffer(std::shared_ptr<ImageBuffer> imageBuffer)
: _imageBuffer(std::move(imageBuffer)) {
}
};
} // namespace tgfx
Loading

0 comments on commit 0ee494a

Please sign in to comment.