diff --git a/.idea/misc.xml b/.idea/misc.xml
index 91398c79..ae66e0cd 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,20 +3,21 @@
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/gpu/Gpu.h b/src/gpu/Gpu.h
index b25cc244..b3b9faed 100644
--- a/src/gpu/Gpu.h
+++ b/src/gpu/Gpu.h
@@ -34,10 +34,12 @@ class Gpu {
public:
virtual ~Gpu() = default;
- Context* context() {
- return _context;
+ Context* getContext() {
+ return context;
}
+ virtual std::shared_ptr getRenderPass() = 0;
+
virtual std::unique_ptr createSampler(int width, int height, PixelFormat format,
int mipLevelCount) = 0;
@@ -55,9 +57,6 @@ class Gpu {
virtual bool waitSemaphore(const Semaphore* semaphore) = 0;
- virtual RenderPass* getRenderPass(std::shared_ptr renderTarget,
- std::shared_ptr renderTargetTexture) = 0;
-
virtual bool submitToGpu(bool syncCpu) = 0;
virtual void submit(RenderPass* renderPass) = 0;
@@ -65,11 +64,11 @@ class Gpu {
void regenerateMipMapLevels(const TextureSampler* sampler);
protected:
- explicit Gpu(Context* context) : _context(context) {
+ Context* context;
+
+ explicit Gpu(Context* context) : context(context) {
}
virtual void onRegenerateMipMapLevels(const TextureSampler* sampler) = 0;
-
- Context* _context;
};
} // namespace tgfx
diff --git a/src/gpu/RenderPass.cpp b/src/gpu/RenderPass.cpp
index 4e0b8a1b..fbf9352a 100644
--- a/src/gpu/RenderPass.cpp
+++ b/src/gpu/RenderPass.cpp
@@ -19,11 +19,22 @@
#include "RenderPass.h"
namespace tgfx {
-void RenderPass::begin() {
+bool RenderPass::begin(std::shared_ptr renderTargetProxy) {
+ if (renderTargetProxy == nullptr) {
+ return false;
+ }
+ _renderTarget = renderTargetProxy->getRenderTarget();
+ if (_renderTarget == nullptr) {
+ return false;
+ }
+ _renderTargetTexture = renderTargetProxy->getTexture();
drawPipelineStatus = DrawPipelineStatus::NotConfigured;
+ return true;
}
void RenderPass::end() {
+ _renderTarget = nullptr;
+ _renderTargetTexture = nullptr;
resetActiveBuffers();
}
diff --git a/src/gpu/RenderPass.h b/src/gpu/RenderPass.h
index c03db06c..dc05e3f4 100644
--- a/src/gpu/RenderPass.h
+++ b/src/gpu/RenderPass.h
@@ -25,6 +25,7 @@
#include "gpu/RenderTarget.h"
#include "gpu/processors/GeometryProcessor.h"
#include "gpu/proxies/GpuBufferProxy.h"
+#include "gpu/proxies/RenderTargetProxy.h"
#include "tgfx/core/BlendMode.h"
#include "tgfx/core/Color.h"
#include "tgfx/gpu/Context.h"
@@ -40,11 +41,10 @@ enum class PrimitiveType {
class RenderPass {
public:
- explicit RenderPass(Context* context) : _context(context) {
- }
+ virtual ~RenderPass() = default;
- Context* context() {
- return _context;
+ Context* getContext() {
+ return context;
}
std::shared_ptr renderTarget() {
@@ -55,9 +55,7 @@ class RenderPass {
return _renderTargetTexture;
}
- virtual ~RenderPass() = default;
-
- void begin();
+ bool begin(std::shared_ptr renderTargetProxy);
void end();
void bindProgramAndScissorClip(const ProgramInfo* programInfo, const Rect& drawBounds);
void bindBuffers(std::shared_ptr indexBuffer, std::shared_ptr vertexBuffer);
@@ -66,6 +64,9 @@ class RenderPass {
void clear(const Rect& scissor, Color color);
protected:
+ explicit RenderPass(Context* context) : context(context) {
+ }
+
virtual bool onBindProgramAndScissorClip(const ProgramInfo* programInfo,
const Rect& drawBounds) = 0;
virtual void onBindBuffers(std::shared_ptr indexBuffer,
@@ -74,7 +75,7 @@ class RenderPass {
virtual void onDrawIndexed(PrimitiveType primitiveType, size_t baseIndex, size_t indexCount) = 0;
virtual void onClear(const Rect& scissor, Color color) = 0;
- Context* _context = nullptr;
+ Context* context = nullptr;
std::shared_ptr _renderTarget = nullptr;
std::shared_ptr _renderTargetTexture = nullptr;
Program* _program = nullptr;
diff --git a/src/gpu/ops/DrawOp.cpp b/src/gpu/ops/DrawOp.cpp
index 8fbf0d4d..d2ae6adf 100644
--- a/src/gpu/ops/DrawOp.cpp
+++ b/src/gpu/ops/DrawOp.cpp
@@ -23,7 +23,8 @@
namespace tgfx {
static DstTextureInfo CreateDstTextureInfo(RenderPass* renderPass, Rect dstRect) {
DstTextureInfo dstTextureInfo = {};
- if (renderPass->context()->caps()->textureBarrierSupport && renderPass->renderTargetTexture()) {
+ auto context = renderPass->getContext();
+ if (context->caps()->textureBarrierSupport && renderPass->renderTargetTexture()) {
dstTextureInfo.texture = renderPass->renderTargetTexture();
dstTextureInfo.requiresBarrier = true;
return dstTextureInfo;
@@ -40,7 +41,7 @@ static DstTextureInfo CreateDstTextureInfo(RenderPass* renderPass, Rect dstRect)
}
dstRect.roundOut();
dstTextureInfo.offset = {dstRect.x(), dstRect.y()};
- auto dstTexture = Texture::MakeRGBA(renderPass->context(), static_cast(dstRect.width()),
+ auto dstTexture = Texture::MakeRGBA(context, static_cast(dstRect.width()),
static_cast(dstRect.height()), false,
renderPass->renderTarget()->origin());
if (dstTexture == nullptr) {
@@ -48,8 +49,8 @@ static DstTextureInfo CreateDstTextureInfo(RenderPass* renderPass, Rect dstRect)
return {};
}
dstTextureInfo.texture = dstTexture;
- renderPass->context()->gpu()->copyRenderTargetToTexture(renderPass->renderTarget().get(),
- dstTexture.get(), dstRect, Point::Zero());
+ context->gpu()->copyRenderTargetToTexture(renderPass->renderTarget().get(), dstTexture.get(),
+ dstRect, Point::Zero());
return dstTextureInfo;
}
@@ -62,7 +63,7 @@ std::unique_ptr DrawOp::createPipeline(RenderPass* renderPass,
std::move(_masks.begin(), _masks.end(),
fragmentProcessors.begin() + static_cast(numColorProcessors));
DstTextureInfo dstTextureInfo = {};
- auto caps = renderPass->context()->caps();
+ auto caps = renderPass->getContext()->caps();
if (!BlendModeAsCoeff(blendMode) && !caps->frameBufferFetchSupport) {
dstTextureInfo = CreateDstTextureInfo(renderPass, bounds());
}
diff --git a/src/gpu/ops/RRectOp.cpp b/src/gpu/ops/RRectOp.cpp
index 67d6c519..65339802 100644
--- a/src/gpu/ops/RRectOp.cpp
+++ b/src/gpu/ops/RRectOp.cpp
@@ -330,7 +330,7 @@ void RRectOp::execute(RenderPass* renderPass) {
auto pipeline = createPipeline(
renderPass, EllipseGeometryProcessor::Make(renderPass->renderTarget()->width(),
renderPass->renderTarget()->height(), false,
- UseScale(renderPass->context()), localMatrix));
+ UseScale(renderPass->getContext()), localMatrix));
renderPass->bindProgramAndScissorClip(pipeline.get(), scissorRect());
renderPass->bindBuffers(indexBuffer, vertexBuffer);
renderPass->drawIndexed(PrimitiveType::Triangles, 0, rRectPaints.size() * kIndicesPerFillRRect);
diff --git a/src/gpu/tasks/OpsRenderTask.cpp b/src/gpu/tasks/OpsRenderTask.cpp
index 2b507784..0d2c31bd 100644
--- a/src/gpu/tasks/OpsRenderTask.cpp
+++ b/src/gpu/tasks/OpsRenderTask.cpp
@@ -29,6 +29,7 @@ void OpsRenderTask::addOp(std::unique_ptr op) {
}
void OpsRenderTask::prepare(Context* context) {
+ renderPass = context->gpu()->getRenderPass();
for (auto& op : ops) {
op->prepare(context);
}
@@ -38,20 +39,16 @@ bool OpsRenderTask::execute(Gpu* gpu) {
if (ops.empty()) {
return false;
}
- auto renderTarget = renderTargetProxy->getRenderTarget();
- auto texture = renderTargetProxy->getTexture();
- auto renderPass = gpu->getRenderPass(renderTarget, texture);
- if (renderPass == nullptr) {
- LOGE("OpsTask::execute() Failed to create render pass!");
+ if (!renderPass->begin(renderTargetProxy)) {
+ LOGE("OpsTask::execute() Failed to initialize the render pass!");
return false;
}
- renderPass->begin();
auto tempOps = std::move(ops);
for (auto& op : tempOps) {
- op->execute(renderPass);
+ op->execute(renderPass.get());
}
+ gpu->submit(renderPass.get());
renderPass->end();
- gpu->submit(renderPass);
return true;
}
} // namespace tgfx
diff --git a/src/gpu/tasks/OpsRenderTask.h b/src/gpu/tasks/OpsRenderTask.h
index d68a61c0..c63147d5 100644
--- a/src/gpu/tasks/OpsRenderTask.h
+++ b/src/gpu/tasks/OpsRenderTask.h
@@ -36,6 +36,7 @@ class OpsRenderTask : public RenderTask {
bool execute(Gpu* gpu) override;
private:
- std::vector> ops;
+ std::shared_ptr renderPass = nullptr;
+ std::vector> ops = {};
};
} // namespace tgfx
diff --git a/src/gpu/tasks/RenderTargetCreateTask.cpp b/src/gpu/tasks/RenderTargetCreateTask.cpp
index 6e7ac40c..02fe0a30 100644
--- a/src/gpu/tasks/RenderTargetCreateTask.cpp
+++ b/src/gpu/tasks/RenderTargetCreateTask.cpp
@@ -39,16 +39,16 @@ RenderTargetCreateTask::RenderTargetCreateTask(ResourceKey strongKey, ResourceKe
std::shared_ptr RenderTargetCreateTask::onMakeResource(Context* context) {
auto texture = Resource::Get(context, textureKey);
if (texture == nullptr) {
- LOGE("RenderTargetCreateTask::onMakeResource() Failed to get texture!");
+ LOGE("RenderTargetCreateTask::onMakeResource() Failed to get the associated texture!");
return nullptr;
}
if (texture->getSampler()->format != pixelFormat) {
- LOGE("RenderTargetCreateTask::onMakeResource() texture format mismatch!");
+ LOGE("RenderTargetCreateTask::onMakeResource() the texture format mismatch!");
return nullptr;
}
auto renderTarget = RenderTarget::MakeFrom(texture.get(), sampleCount);
if (renderTarget == nullptr) {
- LOGE("RenderTargetCreateTask::onMakeResource() Failed to create render target!");
+ LOGE("RenderTargetCreateTask::onMakeResource() Failed to create the render target!");
}
return renderTarget;
}
diff --git a/src/gpu/tasks/TextureCreateTask.cpp b/src/gpu/tasks/TextureCreateTask.cpp
index 544ecfa8..a389f928 100644
--- a/src/gpu/tasks/TextureCreateTask.cpp
+++ b/src/gpu/tasks/TextureCreateTask.cpp
@@ -31,7 +31,7 @@ class EmptyTextureTask : public TextureCreateTask {
std::shared_ptr onMakeResource(Context* context) override {
auto texture = Texture::MakeFormat(context, width, height, format, mipMapped, origin);
if (texture == nullptr) {
- LOGE("EmptyTextureTask::onMakeResource() Failed to create texture!");
+ LOGE("EmptyTextureTask::onMakeResource() Failed to create the texture!");
}
return texture;
}
@@ -66,12 +66,12 @@ class ImageDecoderTask : public TextureCreateTask {
}
auto imageBuffer = decoder->decode();
if (imageBuffer == nullptr) {
- LOGE("ImageDecoderTask::onMakeResource() Failed to decode image!");
+ LOGE("ImageDecoderTask::onMakeResource() Failed to decode the image!");
return nullptr;
}
auto texture = Texture::MakeFrom(context, imageBuffer, mipMapped);
if (texture == nullptr) {
- LOGE("ImageDecoderTask::onMakeResource() Failed to create texture!");
+ LOGE("ImageDecoderTask::onMakeResource() Failed to create the texture!");
} else {
// Free the decoded image buffer immediately to reduce memory pressure.
decoder = nullptr;
diff --git a/src/opengl/GLGpu.cpp b/src/opengl/GLGpu.cpp
index 98545951..03ccf2ab 100644
--- a/src/opengl/GLGpu.cpp
+++ b/src/opengl/GLGpu.cpp
@@ -27,14 +27,21 @@ std::unique_ptr GLGpu::Make(Context* context) {
return std::unique_ptr(new GLGpu(context));
}
+std::shared_ptr GLGpu::getRenderPass() {
+ if (renderPass == nullptr) {
+ renderPass = std::make_shared(context);
+ }
+ return renderPass;
+}
+
std::unique_ptr GLGpu::createSampler(int width, int height, PixelFormat format,
int mipLevelCount) {
// Texture memory must be allocated first on the web platform then can write pixels.
DEBUG_ASSERT(mipLevelCount > 0);
// Clear the previously generated GLError, causing the subsequent CheckGLError to return an
// incorrect result.
- CheckGLError(_context);
- auto gl = GLFunctions::Get(_context);
+ CheckGLError(context);
+ auto gl = GLFunctions::Get(context);
auto sampler = std::make_unique();
gl->genTextures(1, &(sampler->id));
if (sampler->id == 0) {
@@ -48,7 +55,7 @@ std::unique_ptr GLGpu::createSampler(int width, int height, Pixe
gl->texParameteri(sampler->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
gl->texParameteri(sampler->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gl->texParameteri(sampler->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- const auto& textureFormat = GLCaps::Get(_context)->getTextureFormat(format);
+ const auto& textureFormat = GLCaps::Get(context)->getTextureFormat(format);
bool success = true;
for (int level = 0; level < mipLevelCount && success; level++) {
const int twoToTheMipLevel = 1 << level;
@@ -57,7 +64,7 @@ std::unique_ptr GLGpu::createSampler(int width, int height, Pixe
gl->texImage2D(sampler->target, level, static_cast(textureFormat.internalFormatTexImage),
currentWidth, currentHeight, 0, textureFormat.externalFormat, GL_UNSIGNED_BYTE,
nullptr);
- success = CheckGLError(_context);
+ success = CheckGLError(context);
}
if (!success) {
gl->deleteTextures(1, &(sampler->id));
@@ -71,7 +78,7 @@ void GLGpu::deleteSampler(TextureSampler* sampler) {
if (glSampler == nullptr || glSampler->id == 0) {
return;
}
- GLFunctions::Get(_context)->deleteTextures(1, &glSampler->id);
+ GLFunctions::Get(context)->deleteTextures(1, &glSampler->id);
glSampler->id = 0;
}
@@ -80,12 +87,12 @@ void GLGpu::writePixels(const TextureSampler* sampler, Rect rect, const void* pi
if (sampler == nullptr) {
return;
}
- auto gl = GLFunctions::Get(_context);
+ auto gl = GLFunctions::Get(context);
// https://skia-review.googlesource.com/c/skia/+/571418
// HUAWEI nova9 pro(Adreno 642L), iqoo neo5(Adreno 650), Redmi K30pro(Adreno 650),
// Xiaomi 8(Adreno 630), glaxy s9(Adreno 630)
gl->flush();
- auto caps = GLCaps::Get(_context);
+ auto caps = GLCaps::Get(context);
auto glSampler = static_cast(sampler);
gl->bindTexture(glSampler->target, glSampler->id);
const auto& format = caps->getTextureFormat(sampler->format);
@@ -173,14 +180,14 @@ void GLGpu::bindTexture(int unitIndex, const TextureSampler* sampler, SamplerSta
return;
}
auto glSampler = static_cast(sampler);
- auto gl = GLFunctions::Get(_context);
+ auto gl = GLFunctions::Get(context);
gl->activeTexture(static_cast(GL_TEXTURE0 + unitIndex));
gl->bindTexture(glSampler->target, glSampler->id);
gl->texParameteri(glSampler->target, GL_TEXTURE_WRAP_S,
GetGLWrap(glSampler->target, samplerState.wrapModeX));
gl->texParameteri(glSampler->target, GL_TEXTURE_WRAP_T,
GetGLWrap(glSampler->target, samplerState.wrapModeY));
- if (samplerState.mipMapped() && (!_context->caps()->mipMapSupport || !glSampler->hasMipmaps())) {
+ if (samplerState.mipMapped() && (!context->caps()->mipMapSupport || !glSampler->hasMipmaps())) {
samplerState.mipMapMode = MipMapMode::None;
}
gl->texParameteri(glSampler->target, GL_TEXTURE_MIN_FILTER,
@@ -191,7 +198,7 @@ void GLGpu::bindTexture(int unitIndex, const TextureSampler* sampler, SamplerSta
void GLGpu::copyRenderTargetToTexture(const RenderTarget* renderTarget, Texture* texture,
const Rect& srcRect, const Point& dstPoint) {
- auto gl = GLFunctions::Get(_context);
+ auto gl = GLFunctions::Get(context);
auto glRenderTarget = static_cast(renderTarget);
gl->bindFramebuffer(GL_FRAMEBUFFER, glRenderTarget->getFrameBufferID(false));
auto glSampler = static_cast(texture->getSampler());
@@ -212,8 +219,8 @@ void GLGpu::resolveRenderTarget(RenderTarget* renderTarget) {
if (renderTarget->sampleCount() <= 1) {
return;
}
- auto gl = GLFunctions::Get(_context);
- auto caps = GLCaps::Get(_context);
+ auto gl = GLFunctions::Get(context);
+ auto caps = GLCaps::Get(context);
if (!caps->usesMSAARenderBuffers()) {
return;
}
@@ -239,7 +246,7 @@ bool GLGpu::insertSemaphore(Semaphore* semaphore) {
if (semaphore == nullptr) {
return false;
}
- auto gl = GLFunctions::Get(_context);
+ auto gl = GLFunctions::Get(context);
auto* sync = gl->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
if (sync) {
static_cast(semaphore)->glSync = sync;
@@ -255,28 +262,14 @@ bool GLGpu::waitSemaphore(const Semaphore* semaphore) {
if (glSync == nullptr) {
return false;
}
- auto gl = GLFunctions::Get(_context);
+ auto gl = GLFunctions::Get(context);
gl->waitSync(glSync, 0, GL_TIMEOUT_IGNORED);
gl->deleteSync(glSync);
return true;
}
-RenderPass* GLGpu::getRenderPass(std::shared_ptr renderTarget,
- std::shared_ptr renderTargetTexture) {
- if (renderTarget == nullptr) {
- return nullptr;
- }
- if (glRenderPass == nullptr) {
- glRenderPass = GLRenderPass::Make(_context);
- }
- if (glRenderPass) {
- glRenderPass->set(renderTarget, renderTargetTexture);
- }
- return glRenderPass.get();
-}
-
bool GLGpu::submitToGpu(bool syncCpu) {
- auto gl = GLFunctions::Get(_context);
+ auto gl = GLFunctions::Get(context);
if (syncCpu) {
gl->finish();
} else {
@@ -286,11 +279,11 @@ bool GLGpu::submitToGpu(bool syncCpu) {
}
void GLGpu::submit(RenderPass*) {
- glRenderPass->reset();
+ // does nothing for opengl.
}
void GLGpu::onRegenerateMipMapLevels(const TextureSampler* sampler) {
- auto gl = GLFunctions::Get(_context);
+ auto gl = GLFunctions::Get(context);
auto glSampler = static_cast(sampler);
if (glSampler->target != GL_TEXTURE_2D) {
return;
diff --git a/src/opengl/GLGpu.h b/src/opengl/GLGpu.h
index e993290e..4f641f9f 100644
--- a/src/opengl/GLGpu.h
+++ b/src/opengl/GLGpu.h
@@ -26,6 +26,8 @@ class GLGpu : public Gpu {
public:
static std::unique_ptr Make(Context* context);
+ std::shared_ptr getRenderPass() override;
+
std::unique_ptr createSampler(int width, int height, PixelFormat format,
int mipLevelCount) override;
@@ -45,19 +47,16 @@ class GLGpu : public Gpu {
bool waitSemaphore(const Semaphore* semaphore) override;
- RenderPass* getRenderPass(std::shared_ptr renderTarget,
- std::shared_ptr renderTargetTexture) override;
-
bool submitToGpu(bool syncCpu) override;
void submit(RenderPass* renderPass) override;
private:
+ std::shared_ptr renderPass = nullptr;
+
explicit GLGpu(Context* context) : Gpu(context) {
}
void onRegenerateMipMapLevels(const TextureSampler* sampler) override;
-
- std::unique_ptr glRenderPass;
};
} // namespace tgfx
diff --git a/src/opengl/GLRenderPass.cpp b/src/opengl/GLRenderPass.cpp
index ffbbfe3a..6d642a80 100644
--- a/src/opengl/GLRenderPass.cpp
+++ b/src/opengl/GLRenderPass.cpp
@@ -17,9 +17,11 @@
/////////////////////////////////////////////////////////////////////////////////////////////////
#include "GLRenderPass.h"
-#include "GLGpu.h"
#include "GLUtil.h"
+#include "gpu/DrawingManager.h"
#include "gpu/ProgramCache.h"
+#include "opengl/GLVertexArray.h"
+#include "opengl/GLVertexArrayCreateTask.h"
namespace tgfx {
struct AttribLayout {
@@ -43,47 +45,13 @@ static AttribLayout GetAttribLayout(SLType type) {
return {false, 0, 0};
}
-class VertexArrayObject : public Resource {
- public:
- static std::shared_ptr Make(Context* context) {
- auto gl = GLFunctions::Get(context);
- unsigned id = 0;
- // Using VAO is required in the core profile.
- gl->genVertexArrays(1, &id);
- if (id == 0) {
- return nullptr;
- }
- return Resource::AddToContext(context, new VertexArrayObject(id));
- }
-
- explicit VertexArrayObject(unsigned id) : id(id) {
- }
-
- size_t memoryUsage() const override {
- return 0;
- }
-
- unsigned id = 0;
-
- private:
- void onReleaseGPU() override {
- auto gl = GLFunctions::Get(context);
- if (id > 0) {
- gl->deleteVertexArrays(1, &id);
- id = 0;
- }
- }
-};
-
-std::unique_ptr GLRenderPass::Make(Context* context) {
- std::shared_ptr vertexArrayObject;
+GLRenderPass::GLRenderPass(Context* context) : RenderPass(context) {
if (GLCaps::Get(context)->vertexArrayObjectSupport) {
- vertexArrayObject = VertexArrayObject::Make(context);
- if (vertexArrayObject == nullptr) {
- return nullptr;
- }
+ vertexArrayKey = ResourceKey::NewStrong();
+ // Using VAO is required in the core profile.
+ auto task = std::make_shared(vertexArrayKey);
+ context->drawingManager()->addResourceTask(std::move(task));
}
- return std::unique_ptr(new GLRenderPass(context, vertexArrayObject));
}
static void UpdateScissor(Context* context, const Rect& scissorRect) {
@@ -121,32 +89,21 @@ static void UpdateBlend(Context* context, const BlendInfo* blendFactors) {
}
}
-void GLRenderPass::set(std::shared_ptr renderTarget,
- std::shared_ptr renderTargetTexture) {
- _renderTarget = std::move(renderTarget);
- _renderTargetTexture = std::move(renderTargetTexture);
-}
-
-void GLRenderPass::reset() {
- _renderTarget = nullptr;
- _renderTargetTexture = nullptr;
-}
-
bool GLRenderPass::onBindProgramAndScissorClip(const ProgramInfo* programInfo,
const Rect& drawBounds) {
- _program = static_cast(_context->programCache()->getProgram(programInfo));
+ _program = static_cast(context->programCache()->getProgram(programInfo));
if (_program == nullptr) {
return false;
}
- auto gl = GLFunctions::Get(_context);
- CheckGLError(_context);
+ auto gl = GLFunctions::Get(context);
+ CheckGLError(context);
auto glRT = static_cast(_renderTarget.get());
auto* program = static_cast(_program);
gl->useProgram(program->programID());
gl->bindFramebuffer(GL_FRAMEBUFFER, glRT->getFrameBufferID());
gl->viewport(0, 0, glRT->width(), glRT->height());
- UpdateScissor(_context, drawBounds);
- UpdateBlend(_context, programInfo->blendInfo());
+ UpdateScissor(context, drawBounds);
+ UpdateBlend(context, programInfo->blendInfo());
if (programInfo->requiresBarrier()) {
gl->textureBarrier();
}
@@ -164,7 +121,7 @@ static const unsigned gPrimitiveType[] = {GL_TRIANGLES, GL_TRIANGLE_STRIP};
void GLRenderPass::onDraw(PrimitiveType primitiveType, size_t baseVertex, size_t vertexCount) {
auto func = [&]() {
- auto gl = GLFunctions::Get(_context);
+ auto gl = GLFunctions::Get(context);
gl->drawArrays(gPrimitiveType[static_cast(primitiveType)], static_cast(baseVertex),
static_cast(vertexCount));
};
@@ -173,7 +130,7 @@ void GLRenderPass::onDraw(PrimitiveType primitiveType, size_t baseVertex, size_t
void GLRenderPass::onDrawIndexed(PrimitiveType primitiveType, size_t baseIndex, size_t indexCount) {
auto func = [&]() {
- auto gl = GLFunctions::Get(_context);
+ auto gl = GLFunctions::Get(context);
gl->bindBuffer(GL_ELEMENT_ARRAY_BUFFER,
std::static_pointer_cast(_indexBuffer)->bufferID());
gl->drawElements(gPrimitiveType[static_cast(primitiveType)], static_cast(indexCount),
@@ -184,9 +141,10 @@ void GLRenderPass::onDrawIndexed(PrimitiveType primitiveType, size_t baseIndex,
}
void GLRenderPass::draw(const std::function& func) {
- auto gl = GLFunctions::Get(_context);
- if (vertexArrayObject) {
- gl->bindVertexArray(vertexArrayObject->id);
+ auto gl = GLFunctions::Get(context);
+ auto vertexArray = Resource::Get(context, vertexArrayKey);
+ if (vertexArray) {
+ gl->bindVertexArray(vertexArray->id());
}
gl->bindBuffer(GL_ARRAY_BUFFER, std::static_pointer_cast(_vertexBuffer)->bufferID());
auto* program = static_cast(_program);
@@ -198,19 +156,19 @@ void GLRenderPass::draw(const std::function& func) {
gl->enableVertexAttribArray(static_cast(attribute.location));
}
func();
- if (vertexArrayObject) {
+ if (vertexArray) {
gl->bindVertexArray(0);
}
gl->bindBuffer(GL_ARRAY_BUFFER, 0);
- CheckGLError(_context);
+ CheckGLError(context);
}
void GLRenderPass::onClear(const Rect& scissor, Color color) {
- auto gl = GLFunctions::Get(_context);
+ auto gl = GLFunctions::Get(context);
auto glRT = static_cast(_renderTarget.get());
gl->bindFramebuffer(GL_FRAMEBUFFER, glRT->getFrameBufferID());
gl->viewport(0, 0, glRT->width(), glRT->height());
- UpdateScissor(_context, scissor);
+ UpdateScissor(context, scissor);
gl->clearColor(color.red, color.green, color.blue, color.alpha);
gl->clear(GL_COLOR_BUFFER_BIT);
}
diff --git a/src/opengl/GLRenderPass.h b/src/opengl/GLRenderPass.h
index c7b9e8a1..33a0f384 100644
--- a/src/opengl/GLRenderPass.h
+++ b/src/opengl/GLRenderPass.h
@@ -30,16 +30,10 @@
#include "tgfx/core/BlendMode.h"
namespace tgfx {
-class VertexArrayObject;
class GLRenderPass : public RenderPass {
public:
- static std::unique_ptr Make(Context* context);
-
- void set(std::shared_ptr renderTarget,
- std::shared_ptr renderTargetTexture);
-
- void reset();
+ explicit GLRenderPass(Context* context);
protected:
bool onBindProgramAndScissorClip(const ProgramInfo* programInfo, const Rect& drawBounds) override;
@@ -50,12 +44,8 @@ class GLRenderPass : public RenderPass {
void onClear(const Rect& scissor, Color color) override;
private:
- GLRenderPass(Context* context, std::shared_ptr vertexArrayObject)
- : RenderPass(context), vertexArrayObject(std::move(vertexArrayObject)) {
- }
+ ResourceKey vertexArrayKey = {};
void draw(const std::function& func);
-
- std::shared_ptr vertexArrayObject;
};
} // namespace tgfx
diff --git a/src/opengl/GLVertexArray.cpp b/src/opengl/GLVertexArray.cpp
new file mode 100644
index 00000000..670b8ef1
--- /dev/null
+++ b/src/opengl/GLVertexArray.cpp
@@ -0,0 +1,43 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// 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.
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "GLVertexArray.h"
+#include "tgfx/opengl/GLFunctions.h"
+
+namespace tgfx {
+std::shared_ptr GLVertexArray::Make(Context* context) {
+ auto gl = GLFunctions::Get(context);
+ unsigned id = 0;
+ gl->genVertexArrays(1, &id);
+ if (id == 0) {
+ return nullptr;
+ }
+ return Resource::AddToContext(context, new GLVertexArray(id));
+}
+
+GLVertexArray::GLVertexArray(unsigned int id) : _id(id) {
+}
+
+void GLVertexArray::onReleaseGPU() {
+ auto gl = GLFunctions::Get(context);
+ if (_id > 0) {
+ gl->deleteVertexArrays(1, &_id);
+ _id = 0;
+ }
+}
+} // namespace tgfx
diff --git a/src/opengl/GLVertexArray.h b/src/opengl/GLVertexArray.h
new file mode 100644
index 00000000..d0945166
--- /dev/null
+++ b/src/opengl/GLVertexArray.h
@@ -0,0 +1,43 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// 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.
+//
+// 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 "gpu/Resource.h"
+
+namespace tgfx {
+class GLVertexArray : public Resource {
+ public:
+ static std::shared_ptr Make(Context* context);
+
+ explicit GLVertexArray(unsigned id);
+
+ size_t memoryUsage() const override {
+ return 0;
+ }
+
+ unsigned id() const {
+ return _id;
+ }
+
+ private:
+ unsigned _id = 0;
+
+ void onReleaseGPU() override;
+};
+} // namespace tgfx
diff --git a/src/opengl/GLVertexArrayCreateTask.cpp b/src/opengl/GLVertexArrayCreateTask.cpp
new file mode 100644
index 00000000..d1ad1f93
--- /dev/null
+++ b/src/opengl/GLVertexArrayCreateTask.cpp
@@ -0,0 +1,34 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// 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.
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "GLVertexArrayCreateTask.h"
+#include "GLVertexArray.h"
+
+namespace tgfx {
+GLVertexArrayCreateTask::GLVertexArrayCreateTask(ResourceKey strongKey)
+ : ResourceTask(std::move(strongKey)) {
+}
+
+std::shared_ptr GLVertexArrayCreateTask::onMakeResource(Context* context) {
+ auto vertexArray = GLVertexArray::Make(context);
+ if (vertexArray == nullptr) {
+ LOGE("GLVertexArrayCreateTask::onMakeResource() Failed to create the vertex array!");
+ }
+ return vertexArray;
+}
+} // namespace tgfx
diff --git a/src/opengl/GLVertexArrayCreateTask.h b/src/opengl/GLVertexArrayCreateTask.h
new file mode 100644
index 00000000..5bc7fdd7
--- /dev/null
+++ b/src/opengl/GLVertexArrayCreateTask.h
@@ -0,0 +1,30 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// 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.
+//
+// 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 "gpu/tasks/ResourceTask.h"
+
+namespace tgfx {
+class GLVertexArrayCreateTask : public ResourceTask {
+ public:
+ explicit GLVertexArrayCreateTask(ResourceKey strongKey);
+
+ std::shared_ptr onMakeResource(Context* context) override;
+};
+} // namespace tgfx