diff --git a/src/platform/android/VideoSurface.cpp b/src/platform/android/VideoSurface.cpp index eb7b06b01f..0f8bc969e1 100644 --- a/src/platform/android/VideoSurface.cpp +++ b/src/platform/android/VideoSurface.cpp @@ -84,10 +84,10 @@ tgfx::Point OESTexture::getTextureCoord(float x, float y) const { return {x / static_cast(width()) * sx + tx, y / static_cast(height()) * sy + ty}; } -void OESTexture::onRelease(tgfx::Context* context) { +void OESTexture::onReleaseGPU() { if (sampler.id > 0) { - auto gl = tgfx::GLInterface::Get(context); - gl->functions->deleteTextures(1, &sampler.id); + auto gl = tgfx::GLFunctions::Get(context); + gl->deleteTextures(1, &sampler.id); } } @@ -162,18 +162,18 @@ bool VideoSurface::attachToContext(JNIEnv* env, tgfx::Context* context) { } return true; } - auto gl = tgfx::GLInterface::Get(context); + auto gl = tgfx::GLFunctions::Get(context); tgfx::GLSampler sampler = {}; sampler.target = GL_TEXTURE_EXTERNAL_OES; sampler.format = tgfx::PixelFormat::RGBA_8888; - gl->functions->genTextures(1, &sampler.id); + gl->genTextures(1, &sampler.id); if (sampler.id == 0) { return false; } auto result = env->CallBooleanMethod(videoSurface.get(), VideoSurface_attachToGLContext, sampler.id); if (!result) { - gl->functions->deleteTextures(1, &sampler.id); + gl->deleteTextures(1, &sampler.id); LOGE("VideoSurface::attachToGLContext(): failed to attached to a Surface!"); return false; } diff --git a/src/platform/android/VideoSurface.h b/src/platform/android/VideoSurface.h index d52995acd7..f014a94a32 100644 --- a/src/platform/android/VideoSurface.h +++ b/src/platform/android/VideoSurface.h @@ -28,14 +28,13 @@ class OESTexture : public tgfx::GLTexture { tgfx::Point getTextureCoord(float x, float y) const override; - protected: - void onRelease(tgfx::Context* context) override; - private: void setTextureSize(int width, int height); void computeTransform(); + void onReleaseGPU() override; + int textureWidth = 0; int textureHeight = 0; // 持有 Java 的 Surface,确保即使 GPUDecoder 提前释放也能正常被使用。 diff --git a/src/platform/qt/GPUDrawable.cpp b/src/platform/qt/GPUDrawable.cpp index d072213e24..0fd600aa0f 100644 --- a/src/platform/qt/GPUDrawable.cpp +++ b/src/platform/qt/GPUDrawable.cpp @@ -18,7 +18,6 @@ #include "GPUDrawable.h" #include -#include "gpu/opengl/GLInterface.h" #include "gpu/opengl/qt/QGLWindow.h" namespace pag { diff --git a/src/rendering/Drawable.cpp b/src/rendering/Drawable.cpp index bc66f0a8dd..e62670bdfc 100644 --- a/src/rendering/Drawable.cpp +++ b/src/rendering/Drawable.cpp @@ -34,7 +34,7 @@ std::shared_ptr RenderTargetDrawable::createSurface(tgfx::Context } auto glRT = tgfx::GLRenderTarget::MakeFrom(context, frameBuffer, renderTarget.width(), renderTarget.height(), origin); - return tgfx::Surface::MakeFrom(context, std::move(glRT)); + return tgfx::Surface::MakeFrom(std::move(glRT)); } TextureDrawable::TextureDrawable(std::shared_ptr device, @@ -49,7 +49,7 @@ std::shared_ptr TextureDrawable::createSurface(tgfx::Context* con } auto glTexture = tgfx::GLTexture::MakeFrom(context, sampler, texture.width(), texture.height(), origin); - return tgfx::Surface::MakeFrom(context, std::move(glTexture)); + return tgfx::Surface::MakeFrom(std::move(glTexture)); } OffscreenDrawable::OffscreenDrawable(int width, int height, std::shared_ptr device) diff --git a/src/rendering/PAGSurface.cpp b/src/rendering/PAGSurface.cpp index 02655e1711..b379bb5b9e 100644 --- a/src/rendering/PAGSurface.cpp +++ b/src/rendering/PAGSurface.cpp @@ -245,6 +245,7 @@ tgfx::Context* PAGSurface::lockContext() { auto context = device->lockContext(); if (context != nullptr && contextAdopted) { glRestorer = new GLRestorer(tgfx::GLFunctions::Get(context)); + context->resetState(); } return context; } diff --git a/src/rendering/filters/BulgeFilter.cpp b/src/rendering/filters/BulgeFilter.cpp index 5375c212df..d9277d01b1 100644 --- a/src/rendering/filters/BulgeFilter.cpp +++ b/src/rendering/filters/BulgeFilter.cpp @@ -91,15 +91,16 @@ std::string BulgeFilter::onBuildFragmentShader() { return BULGE_FRAGMENT_SHADER; } -void BulgeFilter::onPrepareProgram(const tgfx::GLInterface* gl, unsigned int program) { - horizontalRadiusHandle = gl->functions->getUniformLocation(program, "uHorizontalRadius"); - verticalRadiusHandle = gl->functions->getUniformLocation(program, "uVerticalRadius"); - bulgeCenterHandle = gl->functions->getUniformLocation(program, "uBulgeCenter"); - bulgeHeightHandle = gl->functions->getUniformLocation(program, "uBulgeHeight"); - pinningHandle = gl->functions->getUniformLocation(program, "uPinning"); +void BulgeFilter::onPrepareProgram(tgfx::Context* context, unsigned int program) { + auto gl = tgfx::GLFunctions::Get(context); + horizontalRadiusHandle = gl->getUniformLocation(program, "uHorizontalRadius"); + verticalRadiusHandle = gl->getUniformLocation(program, "uVerticalRadius"); + bulgeCenterHandle = gl->getUniformLocation(program, "uBulgeCenter"); + bulgeHeightHandle = gl->getUniformLocation(program, "uBulgeHeight"); + pinningHandle = gl->getUniformLocation(program, "uPinning"); } -void BulgeFilter::onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, +void BulgeFilter::onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point&) { auto* bulgeEffect = reinterpret_cast(effect); auto horizontalRadius = bulgeEffect->horizontalRadius->getValueAt(layerFrame); @@ -107,14 +108,13 @@ void BulgeFilter::onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& auto bulgeCenter = bulgeEffect->bulgeCenter->getValueAt(layerFrame); auto bulgeHeight = bulgeEffect->bulgeHeight->getValueAt(layerFrame); auto pinning = bulgeEffect->pinning->getValueAt(layerFrame); - - gl->functions->uniform1f(horizontalRadiusHandle, horizontalRadius / contentBounds.width()); - gl->functions->uniform1f(verticalRadiusHandle, verticalRadius / contentBounds.height()); - gl->functions->uniform2f(bulgeCenterHandle, - (bulgeCenter.x - contentBounds.x()) / contentBounds.width(), - 1.0f - (bulgeCenter.y - contentBounds.y()) / contentBounds.height()); - gl->functions->uniform1f(bulgeHeightHandle, bulgeHeight); - gl->functions->uniform1i(pinningHandle, pinning); + auto gl = tgfx::GLFunctions::Get(context); + gl->uniform1f(horizontalRadiusHandle, horizontalRadius / contentBounds.width()); + gl->uniform1f(verticalRadiusHandle, verticalRadius / contentBounds.height()); + gl->uniform2f(bulgeCenterHandle, (bulgeCenter.x - contentBounds.x()) / contentBounds.width(), + 1.0f - (bulgeCenter.y - contentBounds.y()) / contentBounds.height()); + gl->uniform1f(bulgeHeightHandle, bulgeHeight); + gl->uniform1i(pinningHandle, pinning); } std::vector BulgeFilter::computeVertices(const tgfx::Rect& inputBounds, diff --git a/src/rendering/filters/BulgeFilter.h b/src/rendering/filters/BulgeFilter.h index 375213d993..c58eeabd8d 100644 --- a/src/rendering/filters/BulgeFilter.h +++ b/src/rendering/filters/BulgeFilter.h @@ -31,9 +31,9 @@ class BulgeFilter : public LayerFilter { std::string onBuildFragmentShader() override; - void onPrepareProgram(const tgfx::GLInterface* gl, unsigned program) override; + void onPrepareProgram(tgfx::Context* context, unsigned program) override; - void onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, + void onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) override; std::vector computeVertices(const tgfx::Rect& contentBounds, diff --git a/src/rendering/filters/CornerPinFilter.cpp b/src/rendering/filters/CornerPinFilter.cpp index 5da7eb6680..55f6194861 100644 --- a/src/rendering/filters/CornerPinFilter.cpp +++ b/src/rendering/filters/CornerPinFilter.cpp @@ -125,7 +125,7 @@ std::vector CornerPinFilter::computeVertices(const tgfx::Rect& cont return vertices; } -void CornerPinFilter::bindVertices(const tgfx::GLInterface* gl, const FilterSource* source, +void CornerPinFilter::bindVertices(tgfx::Context* context, const FilterSource* source, const FilterTarget* target, const std::vector& points) { std::vector vertices = {}; @@ -139,20 +139,19 @@ void CornerPinFilter::bindVertices(const tgfx::GLInterface* gl, const FilterSour vertices.push_back(texturePoint.y * vertexQs[j]); vertices.push_back(vertexQs[j]); } - + auto gl = tgfx::GLFunctions::Get(context); if (filterProgram->vertexArray > 0) { - gl->functions->bindVertexArray(filterProgram->vertexArray); + gl->bindVertexArray(filterProgram->vertexArray); } - gl->functions->bindBuffer(GL_ARRAY_BUFFER, filterProgram->vertexBuffer); - gl->functions->bufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], - GL_STREAM_DRAW); - gl->functions->vertexAttribPointer(static_cast(positionHandle), 2, GL_FLOAT, GL_FALSE, - 5 * sizeof(float), static_cast(0)); - gl->functions->enableVertexAttribArray(static_cast(positionHandle)); + gl->bindBuffer(GL_ARRAY_BUFFER, filterProgram->vertexBuffer); + gl->bufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STREAM_DRAW); + gl->vertexAttribPointer(static_cast(positionHandle), 2, GL_FLOAT, GL_FALSE, + 5 * sizeof(float), static_cast(0)); + gl->enableVertexAttribArray(static_cast(positionHandle)); - gl->functions->vertexAttribPointer(textureCoordHandle, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), - reinterpret_cast(2 * sizeof(float))); - gl->functions->enableVertexAttribArray(textureCoordHandle); - gl->functions->bindBuffer(GL_ARRAY_BUFFER, 0); + gl->vertexAttribPointer(textureCoordHandle, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), + reinterpret_cast(2 * sizeof(float))); + gl->enableVertexAttribArray(textureCoordHandle); + gl->bindBuffer(GL_ARRAY_BUFFER, 0); } } // namespace pag diff --git a/src/rendering/filters/CornerPinFilter.h b/src/rendering/filters/CornerPinFilter.h index ec0eebb90a..4bbf04c338 100644 --- a/src/rendering/filters/CornerPinFilter.h +++ b/src/rendering/filters/CornerPinFilter.h @@ -35,8 +35,8 @@ class CornerPinFilter : public LayerFilter { const tgfx::Rect& transformedBounds, const tgfx::Point& filterScale) override; - void bindVertices(const tgfx::GLInterface* gl, const FilterSource* source, - const FilterTarget* target, const std::vector& points) override; + void bindVertices(tgfx::Context* context, const FilterSource* source, const FilterTarget* target, + const std::vector& points) override; bool needsMSAA() const override { return true; diff --git a/src/rendering/filters/DisplacementMapFilter.cpp b/src/rendering/filters/DisplacementMapFilter.cpp index 550ad0ad52..8cc7bbbe8a 100644 --- a/src/rendering/filters/DisplacementMapFilter.cpp +++ b/src/rendering/filters/DisplacementMapFilter.cpp @@ -96,15 +96,15 @@ std::string DisplacementMapFilter::onBuildFragmentShader() { return FRAGMENT_SHADER; } -void DisplacementMapFilter::onPrepareProgram(const tgfx::GLInterface* gl, unsigned int program) { - useForDisplacementHandle = gl->functions->getUniformLocation(program, "uUseForDisplacement"); - maxDisplacementHandle = gl->functions->getUniformLocation(program, "uMaxDisplacement"); - displacementMapBehaviorHandle = - gl->functions->getUniformLocation(program, "uDisplacementMapBehavior"); - edgeBehaviorHandle = gl->functions->getUniformLocation(program, "uEdgeBehavior"); - expandOutputHandle = gl->functions->getUniformLocation(program, "uExpandOutput"); - mapTextureHandle = gl->functions->getUniformLocation(program, "mapTexture"); - mapTextureSizeHandle = gl->functions->getUniformLocation(program, "mapTextureSize"); +void DisplacementMapFilter::onPrepareProgram(tgfx::Context* context, unsigned int program) { + auto gl = tgfx::GLFunctions::Get(context); + useForDisplacementHandle = gl->getUniformLocation(program, "uUseForDisplacement"); + maxDisplacementHandle = gl->getUniformLocation(program, "uMaxDisplacement"); + displacementMapBehaviorHandle = gl->getUniformLocation(program, "uDisplacementMapBehavior"); + edgeBehaviorHandle = gl->getUniformLocation(program, "uEdgeBehavior"); + expandOutputHandle = gl->getUniformLocation(program, "uExpandOutput"); + mapTextureHandle = gl->getUniformLocation(program, "mapTexture"); + mapTextureSizeHandle = gl->getUniformLocation(program, "mapTextureSize"); } void DisplacementMapFilter::updateMapTexture(RenderCache* cache, const Graphic* mapGraphic, @@ -118,23 +118,22 @@ void DisplacementMapFilter::updateMapTexture(RenderCache* cache, const Graphic* mapGraphic->draw(mapSurface->getCanvas(), cache); } -void DisplacementMapFilter::onUpdateParams(const tgfx::GLInterface* gl, - const tgfx::Rect& contentBounds, const tgfx::Point&) { +void DisplacementMapFilter::onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, + const tgfx::Point&) { auto* pagEffect = reinterpret_cast(effect); - auto mapTextureID = GetTextureID(mapSurface->getTexture().get()); - ActiveGLTexture(gl, GL_TEXTURE1, GL_TEXTURE_2D, mapTextureID); - gl->functions->uniform2f(useForDisplacementHandle, - pagEffect->useForHorizontalDisplacement->getValueAt(layerFrame), - pagEffect->useForVerticalDisplacement->getValueAt(layerFrame)); - gl->functions->uniform2f(maxDisplacementHandle, - pagEffect->maxHorizontalDisplacement->getValueAt(layerFrame), - pagEffect->maxVerticalDisplacement->getValueAt(layerFrame)); - gl->functions->uniform1i(displacementMapBehaviorHandle, - pagEffect->displacementMapBehavior->getValueAt(layerFrame)); - gl->functions->uniform1i(edgeBehaviorHandle, pagEffect->edgeBehavior->getValueAt(layerFrame)); - gl->functions->uniform1i(expandOutputHandle, pagEffect->expandOutput->getValueAt(layerFrame)); - gl->functions->uniform1i(mapTextureHandle, 1); - gl->functions->uniform2f(mapTextureSizeHandle, mapBounds.width() / contentBounds.width(), - mapBounds.height() / contentBounds.height()); + tgfx::GLContext::Unwrap(context)->bindTexture(1, mapSurface->getTexture()->getSampler()); + auto gl = tgfx::GLFunctions::Get(context); + gl->uniform2f(useForDisplacementHandle, + pagEffect->useForHorizontalDisplacement->getValueAt(layerFrame), + pagEffect->useForVerticalDisplacement->getValueAt(layerFrame)); + gl->uniform2f(maxDisplacementHandle, pagEffect->maxHorizontalDisplacement->getValueAt(layerFrame), + pagEffect->maxVerticalDisplacement->getValueAt(layerFrame)); + gl->uniform1i(displacementMapBehaviorHandle, + pagEffect->displacementMapBehavior->getValueAt(layerFrame)); + gl->uniform1i(edgeBehaviorHandle, pagEffect->edgeBehavior->getValueAt(layerFrame)); + gl->uniform1i(expandOutputHandle, pagEffect->expandOutput->getValueAt(layerFrame)); + gl->uniform1i(mapTextureHandle, 1); + gl->uniform2f(mapTextureSizeHandle, mapBounds.width() / contentBounds.width(), + mapBounds.height() / contentBounds.height()); } } // namespace pag diff --git a/src/rendering/filters/DisplacementMapFilter.h b/src/rendering/filters/DisplacementMapFilter.h index 8ca107747a..8705d1ec14 100644 --- a/src/rendering/filters/DisplacementMapFilter.h +++ b/src/rendering/filters/DisplacementMapFilter.h @@ -33,9 +33,9 @@ class DisplacementMapFilter : public LayerFilter { protected: std::string onBuildFragmentShader() override; - void onPrepareProgram(const tgfx::GLInterface* gl, unsigned program) override; + void onPrepareProgram(tgfx::Context* context, unsigned program) override; - void onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, + void onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) override; private: diff --git a/src/rendering/filters/Filter.h b/src/rendering/filters/Filter.h index 50a5f728d3..affc61fcdb 100644 --- a/src/rendering/filters/Filter.h +++ b/src/rendering/filters/Filter.h @@ -20,14 +20,15 @@ #include #include "core/Matrix.h" -#include "gpu/opengl/GLContext.h" +#include "gpu/opengl/GLFrameBuffer.h" +#include "gpu/opengl/GLSampler.h" namespace pag { struct FilterSource { /** - * the id of source texture. + * The source texture sampler. */ - unsigned textureID = 0; + tgfx::GLSampler sampler = {}; /** * The width of source texture in pixels after textureMatrix and scale being applied. @@ -59,9 +60,9 @@ struct FilterSource { struct FilterTarget { /** - * the id of target frame buffer. + * The target frame buffer. */ - unsigned frameBufferID = 0; + tgfx::GLFrameBuffer frameBuffer = {}; /** * The width of target frame buffer in pixels. diff --git a/src/rendering/filters/LayerFilter.cpp b/src/rendering/filters/LayerFilter.cpp index 924289bb4a..8065d24bab 100644 --- a/src/rendering/filters/LayerFilter.cpp +++ b/src/rendering/filters/LayerFilter.cpp @@ -80,32 +80,33 @@ std::vector ComputeVerticesForMotionBlurAndBulge(const tgfx::Rect& std::shared_ptr FilterProgram::Make(tgfx::Context* context, const std::string& vertex, const std::string& fragment) { - auto gl = tgfx::GLInterface::Get(context); - auto program = tgfx::CreateGLProgram(gl, vertex, fragment); + auto gl = tgfx::GLFunctions::Get(context); + auto caps = tgfx::GLCaps::Get(context); + auto program = tgfx::CreateGLProgram(context, vertex, fragment); if (program == 0) { return nullptr; } auto filterProgram = new FilterProgram(); filterProgram->program = program; - if (gl->caps->vertexArrayObjectSupport) { - gl->functions->genVertexArrays(1, &filterProgram->vertexArray); + if (caps->vertexArrayObjectSupport) { + gl->genVertexArrays(1, &filterProgram->vertexArray); } - gl->functions->genBuffers(1, &filterProgram->vertexBuffer); + gl->genBuffers(1, &filterProgram->vertexBuffer); return Resource::Wrap(context, filterProgram); } -void FilterProgram::onRelease(tgfx::Context* context) { - auto gl = tgfx::GLInterface::Get(context); +void FilterProgram::onReleaseGPU() { + auto gl = tgfx::GLFunctions::Get(context); if (program > 0) { - gl->functions->deleteProgram(program); + gl->deleteProgram(program); program = 0; } if (vertexArray > 0) { - gl->functions->deleteVertexArrays(1, &vertexArray); + gl->deleteVertexArrays(1, &vertexArray); vertexArray = 0; } if (vertexBuffer > 0) { - gl->functions->deleteBuffers(1, &vertexBuffer); + gl->deleteBuffers(1, &vertexBuffer); vertexBuffer = 0; } } @@ -158,9 +159,8 @@ std::unique_ptr LayerFilter::Make(Effect* effect) { } bool LayerFilter::initialize(tgfx::Context* context) { - auto gl = tgfx::GLInterface::Get(context); // 防止前面产生的GLError,导致后面CheckGLError逻辑返回错误结果 - CheckGLError(gl); + CheckGLError(context); auto vertex = onBuildVertexShader(); auto fragment = onBuildFragmentShader(); @@ -168,13 +168,14 @@ bool LayerFilter::initialize(tgfx::Context* context) { if (filterProgram == nullptr) { return false; } + auto gl = tgfx::GLFunctions::Get(context); auto program = filterProgram->program; - positionHandle = gl->functions->getAttribLocation(program, "aPosition"); - textureCoordHandle = gl->functions->getAttribLocation(program, "aTextureCoord"); - vertexMatrixHandle = gl->functions->getUniformLocation(program, "uVertexMatrix"); - textureMatrixHandle = gl->functions->getUniformLocation(program, "uTextureMatrix"); - onPrepareProgram(gl, program); - if (!CheckGLError(gl)) { + positionHandle = gl->getAttribLocation(program, "aPosition"); + textureCoordHandle = gl->getAttribLocation(program, "aTextureCoord"); + vertexMatrixHandle = gl->getUniformLocation(program, "uVertexMatrix"); + textureMatrixHandle = gl->getUniformLocation(program, "uTextureMatrix"); + onPrepareProgram(context, program); + if (!CheckGLError(context)) { filterProgram = nullptr; return false; } @@ -189,10 +190,10 @@ std::string LayerFilter::onBuildFragmentShader() { return FRAGMENT_SHADER; } -void LayerFilter::onPrepareProgram(const tgfx::GLInterface*, unsigned) { +void LayerFilter::onPrepareProgram(tgfx::Context*, unsigned) { } -void LayerFilter::onUpdateParams(const tgfx::GLInterface*, const tgfx::Rect&, const tgfx::Point&) { +void LayerFilter::onUpdateParams(tgfx::Context*, const tgfx::Rect&, const tgfx::Point&) { } void LayerFilter::update(Frame frame, const tgfx::Rect& inputBounds, const tgfx::Rect& outputBounds, @@ -203,15 +204,19 @@ void LayerFilter::update(Frame frame, const tgfx::Rect& inputBounds, const tgfx: filterScale = extraScale; } -static void EnableMultisample(const tgfx::GLInterface* gl, bool usesMSAA) { - if (usesMSAA && gl->caps->multisampleDisableSupport) { - gl->functions->enable(GL_MULTISAMPLE); +static void EnableMultisample(tgfx::Context* context, bool usesMSAA) { + auto caps = tgfx::GLCaps::Get(context); + if (usesMSAA && caps->multisampleDisableSupport) { + auto gl = tgfx::GLFunctions::Get(context); + gl->enable(GL_MULTISAMPLE); } } -static void DisableMultisample(const tgfx::GLInterface* gl, bool usesMSAA) { - if (usesMSAA && gl->caps->multisampleDisableSupport) { - gl->functions->disable(GL_MULTISAMPLE); +static void DisableMultisample(tgfx::Context* context, bool usesMSAA) { + auto caps = tgfx::GLCaps::Get(context); + if (usesMSAA && caps->multisampleDisableSupport) { + auto gl = tgfx::GLFunctions::Get(context); + gl->disable(GL_MULTISAMPLE); } } @@ -223,28 +228,27 @@ void LayerFilter::draw(tgfx::Context* context, const FilterSource* source, "because the argument(source/target) is null"); return; } - auto gl = tgfx::GLInterface::Get(context); - EnableMultisample(gl, needsMSAA()); - gl->functions->useProgram(filterProgram->program); - gl->functions->disable(GL_SCISSOR_TEST); - gl->functions->enable(GL_BLEND); - gl->functions->blendEquation(GL_FUNC_ADD); - gl->functions->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, target->frameBufferID); - gl->functions->viewport(0, 0, target->width, target->height); - - ActiveGLTexture(gl, GL_TEXTURE0, GL_TEXTURE_2D, source->textureID); - gl->functions->uniformMatrix3fv(vertexMatrixHandle, 1, GL_FALSE, target->vertexMatrix.data()); - gl->functions->uniformMatrix3fv(textureMatrixHandle, 1, GL_FALSE, source->textureMatrix.data()); - onUpdateParams(gl, contentBounds, filterScale); + auto gl = tgfx::GLFunctions::Get(context); + EnableMultisample(context, needsMSAA()); + gl->useProgram(filterProgram->program); + gl->disable(GL_SCISSOR_TEST); + gl->enable(GL_BLEND); + gl->blendEquation(GL_FUNC_ADD); + gl->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + gl->bindFramebuffer(GL_FRAMEBUFFER, target->frameBuffer.id); + gl->viewport(0, 0, target->width, target->height); + tgfx::GLContext::Unwrap(context)->bindTexture(0, &source->sampler); + gl->uniformMatrix3fv(vertexMatrixHandle, 1, GL_FALSE, target->vertexMatrix.data()); + gl->uniformMatrix3fv(textureMatrixHandle, 1, GL_FALSE, source->textureMatrix.data()); + onUpdateParams(context, contentBounds, filterScale); auto vertices = computeVertices(contentBounds, transformedBounds, filterScale); - bindVertices(gl, source, target, vertices); - gl->functions->drawArrays(GL_TRIANGLE_STRIP, 0, 4); + bindVertices(context, source, target, vertices); + gl->drawArrays(GL_TRIANGLE_STRIP, 0, 4); if (filterProgram->vertexArray > 0) { - gl->functions->bindVertexArray(0); + gl->bindVertexArray(0); } - DisableMultisample(gl, needsMSAA()); - CheckGLError(gl); + DisableMultisample(context, needsMSAA()); + CheckGLError(context); } std::vector LayerFilter::computeVertices(const tgfx::Rect& bounds, @@ -266,7 +270,7 @@ std::vector LayerFilter::computeVertices(const tgfx::Rect& bounds, return vertices; } -void LayerFilter::bindVertices(const tgfx::GLInterface* gl, const FilterSource* source, +void LayerFilter::bindVertices(tgfx::Context* context, const FilterSource* source, const FilterTarget* target, const std::vector& points) { std::vector vertices = {}; for (size_t i = 0; i < points.size();) { @@ -277,21 +281,20 @@ void LayerFilter::bindVertices(const tgfx::GLInterface* gl, const FilterSource* vertices.push_back(texturePoint.x); vertices.push_back(texturePoint.y); } - + auto gl = tgfx::GLFunctions::Get(context); if (filterProgram->vertexArray > 0) { - gl->functions->bindVertexArray(filterProgram->vertexArray); + gl->bindVertexArray(filterProgram->vertexArray); } - gl->functions->bindBuffer(GL_ARRAY_BUFFER, filterProgram->vertexBuffer); - gl->functions->bufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], - GL_STREAM_DRAW); - gl->functions->vertexAttribPointer(static_cast(positionHandle), 2, GL_FLOAT, GL_FALSE, - 4 * sizeof(float), static_cast(0)); - gl->functions->enableVertexAttribArray(static_cast(positionHandle)); + gl->bindBuffer(GL_ARRAY_BUFFER, filterProgram->vertexBuffer); + gl->bufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STREAM_DRAW); + gl->vertexAttribPointer(static_cast(positionHandle), 2, GL_FLOAT, GL_FALSE, + 4 * sizeof(float), static_cast(0)); + gl->enableVertexAttribArray(static_cast(positionHandle)); - gl->functions->vertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), - reinterpret_cast(2 * sizeof(float))); - gl->functions->enableVertexAttribArray(textureCoordHandle); - gl->functions->bindBuffer(GL_ARRAY_BUFFER, 0); + gl->vertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), + reinterpret_cast(2 * sizeof(float))); + gl->enableVertexAttribArray(textureCoordHandle); + gl->bindBuffer(GL_ARRAY_BUFFER, 0); } bool LayerFilter::needsMSAA() const { diff --git a/src/rendering/filters/LayerFilter.h b/src/rendering/filters/LayerFilter.h index c4631355ce..52452b9cb4 100644 --- a/src/rendering/filters/LayerFilter.h +++ b/src/rendering/filters/LayerFilter.h @@ -38,11 +38,10 @@ class FilterProgram : public tgfx::Resource { unsigned int vertexArray = 0; unsigned int vertexBuffer = 0; - protected: - void onRelease(tgfx::Context* context) override; - private: FilterProgram() = default; + + void onReleaseGPU() override; }; class LayerFilter : public Filter { @@ -90,7 +89,7 @@ class LayerFilter : public Filter { virtual std::string onBuildFragmentShader(); - virtual void onPrepareProgram(const tgfx::GLInterface* gl, unsigned program); + virtual void onPrepareProgram(tgfx::Context* context, unsigned program); /** * filter的给shader上传数据接口 @@ -99,7 +98,7 @@ class LayerFilter : public Filter { * bounds来计算shader中的参数,比如:bulge、MotionTile * @param filterScale : 滤镜效果的scale */ - virtual void onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, + virtual void onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale); /** @@ -115,7 +114,7 @@ class LayerFilter : public Filter { const tgfx::Rect& transformedBounds, const tgfx::Point& filterScale); - virtual void bindVertices(const tgfx::GLInterface* gl, const FilterSource* source, + virtual void bindVertices(tgfx::Context* context, const FilterSource* source, const FilterTarget* target, const std::vector& points); private: diff --git a/src/rendering/filters/LevelsIndividualFilter.cpp b/src/rendering/filters/LevelsIndividualFilter.cpp index 57d1d379b8..61f7ea2a75 100644 --- a/src/rendering/filters/LevelsIndividualFilter.cpp +++ b/src/rendering/filters/LevelsIndividualFilter.cpp @@ -86,76 +86,69 @@ std::string LevelsIndividualFilter::onBuildFragmentShader() { return FRAGMENT_SHADER; } -void LevelsIndividualFilter::onPrepareProgram(const tgfx::GLInterface* gl, unsigned int program) { - inputBlackHandle = gl->functions->getUniformLocation(program, "inputBlack"); - inputWhiteHandle = gl->functions->getUniformLocation(program, "inputWhite"); - gammaHandle = gl->functions->getUniformLocation(program, "gamma"); - outputBlackHandle = gl->functions->getUniformLocation(program, "outputBlack"); - outputWhiteHandle = gl->functions->getUniformLocation(program, "outputWhite"); - - redInputBlackHandle = gl->functions->getUniformLocation(program, "redInputBlack"); - redInputWhiteHandle = gl->functions->getUniformLocation(program, "redInputWhite"); - redGammaHandle = gl->functions->getUniformLocation(program, "redGamma"); - redOutputBlackHandle = gl->functions->getUniformLocation(program, "redOutputBlack"); - redOutputWhiteHandle = gl->functions->getUniformLocation(program, "redOutputWhite"); - - greenInputBlackHandle = gl->functions->getUniformLocation(program, "greenInputBlack"); - greenInputWhiteHandle = gl->functions->getUniformLocation(program, "greenInputWhite"); - greenGammaHandle = gl->functions->getUniformLocation(program, "greenGamma"); - greenOutputBlackHandle = gl->functions->getUniformLocation(program, "greenOutputBlack"); - greenOutputWhiteHandle = gl->functions->getUniformLocation(program, "greenOutputWhite"); - - blueInputBlackHandle = gl->functions->getUniformLocation(program, "blueInputBlack"); - blueInputWhiteHandle = gl->functions->getUniformLocation(program, "blueInputWhite"); - blueGammaHandle = gl->functions->getUniformLocation(program, "blueGamma"); - blueOutputBlackHandle = gl->functions->getUniformLocation(program, "blueOutputBlack"); - blueOutputWhiteHandle = gl->functions->getUniformLocation(program, "blueOutputWhite"); +void LevelsIndividualFilter::onPrepareProgram(tgfx::Context* context, unsigned int program) { + auto gl = tgfx::GLFunctions::Get(context); + inputBlackHandle = gl->getUniformLocation(program, "inputBlack"); + inputWhiteHandle = gl->getUniformLocation(program, "inputWhite"); + gammaHandle = gl->getUniformLocation(program, "gamma"); + outputBlackHandle = gl->getUniformLocation(program, "outputBlack"); + outputWhiteHandle = gl->getUniformLocation(program, "outputWhite"); + + redInputBlackHandle = gl->getUniformLocation(program, "redInputBlack"); + redInputWhiteHandle = gl->getUniformLocation(program, "redInputWhite"); + redGammaHandle = gl->getUniformLocation(program, "redGamma"); + redOutputBlackHandle = gl->getUniformLocation(program, "redOutputBlack"); + redOutputWhiteHandle = gl->getUniformLocation(program, "redOutputWhite"); + + greenInputBlackHandle = gl->getUniformLocation(program, "greenInputBlack"); + greenInputWhiteHandle = gl->getUniformLocation(program, "greenInputWhite"); + greenGammaHandle = gl->getUniformLocation(program, "greenGamma"); + greenOutputBlackHandle = gl->getUniformLocation(program, "greenOutputBlack"); + greenOutputWhiteHandle = gl->getUniformLocation(program, "greenOutputWhite"); + + blueInputBlackHandle = gl->getUniformLocation(program, "blueInputBlack"); + blueInputWhiteHandle = gl->getUniformLocation(program, "blueInputWhite"); + blueGammaHandle = gl->getUniformLocation(program, "blueGamma"); + blueOutputBlackHandle = gl->getUniformLocation(program, "blueOutputBlack"); + blueOutputWhiteHandle = gl->getUniformLocation(program, "blueOutputWhite"); } -void LevelsIndividualFilter::onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect&, +void LevelsIndividualFilter::onUpdateParams(tgfx::Context* context, const tgfx::Rect&, const tgfx::Point&) { + auto gl = tgfx::GLFunctions::Get(context); auto* levelsIndividualFilter = reinterpret_cast(effect); - gl->functions->uniform1f(inputBlackHandle, - levelsIndividualFilter->inputBlack->getValueAt(layerFrame)); - gl->functions->uniform1f(inputWhiteHandle, - levelsIndividualFilter->inputWhite->getValueAt(layerFrame)); - gl->functions->uniform1f(gammaHandle, levelsIndividualFilter->gamma->getValueAt(layerFrame)); - gl->functions->uniform1f(outputBlackHandle, - levelsIndividualFilter->outputBlack->getValueAt(layerFrame)); - gl->functions->uniform1f(outputWhiteHandle, - levelsIndividualFilter->outputWhite->getValueAt(layerFrame)); - - gl->functions->uniform1f(redInputBlackHandle, - levelsIndividualFilter->redInputBlack->getValueAt(layerFrame)); - gl->functions->uniform1f(redInputWhiteHandle, - levelsIndividualFilter->redInputWhite->getValueAt(layerFrame)); - gl->functions->uniform1f(redGammaHandle, - levelsIndividualFilter->redGamma->getValueAt(layerFrame)); - gl->functions->uniform1f(redOutputBlackHandle, - levelsIndividualFilter->redOutputBlack->getValueAt(layerFrame)); - gl->functions->uniform1f(redOutputWhiteHandle, - levelsIndividualFilter->redOutputWhite->getValueAt(layerFrame)); - - gl->functions->uniform1f(greenInputBlackHandle, - levelsIndividualFilter->greenInputBlack->getValueAt(layerFrame)); - gl->functions->uniform1f(greenInputWhiteHandle, - levelsIndividualFilter->greenInputWhite->getValueAt(layerFrame)); - gl->functions->uniform1f(greenGammaHandle, - levelsIndividualFilter->greenGamma->getValueAt(layerFrame)); - gl->functions->uniform1f(greenOutputBlackHandle, - levelsIndividualFilter->greenOutputBlack->getValueAt(layerFrame)); - gl->functions->uniform1f(greenOutputWhiteHandle, - levelsIndividualFilter->greenOutputWhite->getValueAt(layerFrame)); - - gl->functions->uniform1f(blueInputBlackHandle, - levelsIndividualFilter->blueInputBlack->getValueAt(layerFrame)); - gl->functions->uniform1f(blueInputWhiteHandle, - levelsIndividualFilter->blueInputWhite->getValueAt(layerFrame)); - gl->functions->uniform1f(blueGammaHandle, - levelsIndividualFilter->blueGamma->getValueAt(layerFrame)); - gl->functions->uniform1f(blueOutputBlackHandle, - levelsIndividualFilter->blueOutputBlack->getValueAt(layerFrame)); - gl->functions->uniform1f(blueOutputWhiteHandle, - levelsIndividualFilter->blueOutputWhite->getValueAt(layerFrame)); + gl->uniform1f(inputBlackHandle, levelsIndividualFilter->inputBlack->getValueAt(layerFrame)); + gl->uniform1f(inputWhiteHandle, levelsIndividualFilter->inputWhite->getValueAt(layerFrame)); + gl->uniform1f(gammaHandle, levelsIndividualFilter->gamma->getValueAt(layerFrame)); + gl->uniform1f(outputBlackHandle, levelsIndividualFilter->outputBlack->getValueAt(layerFrame)); + gl->uniform1f(outputWhiteHandle, levelsIndividualFilter->outputWhite->getValueAt(layerFrame)); + + gl->uniform1f(redInputBlackHandle, levelsIndividualFilter->redInputBlack->getValueAt(layerFrame)); + gl->uniform1f(redInputWhiteHandle, levelsIndividualFilter->redInputWhite->getValueAt(layerFrame)); + gl->uniform1f(redGammaHandle, levelsIndividualFilter->redGamma->getValueAt(layerFrame)); + gl->uniform1f(redOutputBlackHandle, + levelsIndividualFilter->redOutputBlack->getValueAt(layerFrame)); + gl->uniform1f(redOutputWhiteHandle, + levelsIndividualFilter->redOutputWhite->getValueAt(layerFrame)); + + gl->uniform1f(greenInputBlackHandle, + levelsIndividualFilter->greenInputBlack->getValueAt(layerFrame)); + gl->uniform1f(greenInputWhiteHandle, + levelsIndividualFilter->greenInputWhite->getValueAt(layerFrame)); + gl->uniform1f(greenGammaHandle, levelsIndividualFilter->greenGamma->getValueAt(layerFrame)); + gl->uniform1f(greenOutputBlackHandle, + levelsIndividualFilter->greenOutputBlack->getValueAt(layerFrame)); + gl->uniform1f(greenOutputWhiteHandle, + levelsIndividualFilter->greenOutputWhite->getValueAt(layerFrame)); + + gl->uniform1f(blueInputBlackHandle, + levelsIndividualFilter->blueInputBlack->getValueAt(layerFrame)); + gl->uniform1f(blueInputWhiteHandle, + levelsIndividualFilter->blueInputWhite->getValueAt(layerFrame)); + gl->uniform1f(blueGammaHandle, levelsIndividualFilter->blueGamma->getValueAt(layerFrame)); + gl->uniform1f(blueOutputBlackHandle, + levelsIndividualFilter->blueOutputBlack->getValueAt(layerFrame)); + gl->uniform1f(blueOutputWhiteHandle, + levelsIndividualFilter->blueOutputWhite->getValueAt(layerFrame)); } } // namespace pag diff --git a/src/rendering/filters/LevelsIndividualFilter.h b/src/rendering/filters/LevelsIndividualFilter.h index 555f4a231b..f4889989e5 100644 --- a/src/rendering/filters/LevelsIndividualFilter.h +++ b/src/rendering/filters/LevelsIndividualFilter.h @@ -29,9 +29,9 @@ class LevelsIndividualFilter : public LayerFilter { protected: std::string onBuildFragmentShader() override; - void onPrepareProgram(const tgfx::GLInterface* gl, unsigned program) override; + void onPrepareProgram(tgfx::Context* context, unsigned program) override; - void onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, + void onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) override; private: diff --git a/src/rendering/filters/MosaicFilter.cpp b/src/rendering/filters/MosaicFilter.cpp index a78f8fbe43..caff2f517f 100644 --- a/src/rendering/filters/MosaicFilter.cpp +++ b/src/rendering/filters/MosaicFilter.cpp @@ -43,13 +43,14 @@ std::string MosaicFilter::onBuildFragmentShader() { return FRAGMENT_SHADER; } -void MosaicFilter::onPrepareProgram(const tgfx::GLInterface* gl, unsigned int program) { - horizontalBlocksHandle = gl->functions->getUniformLocation(program, "mHorizontalBlocks"); - verticalBlocksHandle = gl->functions->getUniformLocation(program, "mVerticalBlocks"); - sharpColorsHandle = gl->functions->getUniformLocation(program, "mSharpColors"); +void MosaicFilter::onPrepareProgram(tgfx::Context* context, unsigned int program) { + auto gl = tgfx::GLFunctions::Get(context); + horizontalBlocksHandle = gl->getUniformLocation(program, "mHorizontalBlocks"); + verticalBlocksHandle = gl->getUniformLocation(program, "mVerticalBlocks"); + sharpColorsHandle = gl->getUniformLocation(program, "mSharpColors"); } -void MosaicFilter::onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, +void MosaicFilter::onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point&) { auto* mosaicEffect = reinterpret_cast(effect); horizontalBlocks = 1.0f / mosaicEffect->horizontalBlocks->getValueAt(layerFrame); @@ -69,9 +70,9 @@ void MosaicFilter::onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& } else { verticalBlocks *= 1.0f * placeHolderHeight / contentHeight; } - - gl->functions->uniform1f(horizontalBlocksHandle, horizontalBlocks); - gl->functions->uniform1f(verticalBlocksHandle, verticalBlocks); - gl->functions->uniform1f(sharpColorsHandle, sharpColors); + auto gl = tgfx::GLFunctions::Get(context); + gl->uniform1f(horizontalBlocksHandle, horizontalBlocks); + gl->uniform1f(verticalBlocksHandle, verticalBlocks); + gl->uniform1f(sharpColorsHandle, sharpColors); } } // namespace pag diff --git a/src/rendering/filters/MosaicFilter.h b/src/rendering/filters/MosaicFilter.h index ad7106ea8f..1f748c1b99 100644 --- a/src/rendering/filters/MosaicFilter.h +++ b/src/rendering/filters/MosaicFilter.h @@ -29,9 +29,9 @@ class MosaicFilter : public LayerFilter { protected: std::string onBuildFragmentShader() override; - void onPrepareProgram(const tgfx::GLInterface* gl, unsigned program) override; + void onPrepareProgram(tgfx::Context* context, unsigned program) override; - void onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, + void onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) override; private: diff --git a/src/rendering/filters/MotionBlurFilter.cpp b/src/rendering/filters/MotionBlurFilter.cpp index 7c9a213038..be92a2cfb9 100644 --- a/src/rendering/filters/MotionBlurFilter.cpp +++ b/src/rendering/filters/MotionBlurFilter.cpp @@ -107,11 +107,12 @@ std::string MotionBlurFilter::onBuildFragmentShader() { return MOTIONBLUR_FRAGMENT_SHADER; } -void MotionBlurFilter::onPrepareProgram(const tgfx::GLInterface* gl, unsigned int program) { - prevTransformHandle = gl->functions->getUniformLocation(program, "uPrevTransform"); - transformHandle = gl->functions->getUniformLocation(program, "uTransform"); - velCenterHandle = gl->functions->getUniformLocation(program, "uVelCenter"); - maxDistanceHandle = gl->functions->getUniformLocation(program, "maxDistance"); +void MotionBlurFilter::onPrepareProgram(tgfx::Context* context, unsigned int program) { + auto gl = tgfx::GLFunctions::Get(context); + prevTransformHandle = gl->getUniformLocation(program, "uPrevTransform"); + transformHandle = gl->getUniformLocation(program, "uTransform"); + velCenterHandle = gl->getUniformLocation(program, "uVelCenter"); + maxDistanceHandle = gl->getUniformLocation(program, "maxDistance"); } bool MotionBlurFilter::updateLayer(Layer* targetLayer, Frame layerFrame) { @@ -122,7 +123,7 @@ bool MotionBlurFilter::updateLayer(Layer* targetLayer, Frame layerFrame) { return previousMatrix != currentMatrix; } -void MotionBlurFilter::onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, +void MotionBlurFilter::onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point&) { auto width = static_cast(contentBounds.width()); auto height = static_cast(contentBounds.height()); @@ -137,11 +138,11 @@ void MotionBlurFilter::onUpdateParams(const tgfx::GLInterface* gl, const tgfx::R auto scaling = (previousMatrix.getScaleX() != currentMatrix.getScaleX() || previousMatrix.getScaleY() != currentMatrix.getScaleY()); - - gl->functions->uniformMatrix3fv(prevTransformHandle, 1, GL_FALSE, previousGLMatrix.data()); - gl->functions->uniformMatrix3fv(transformHandle, 1, GL_FALSE, currentGLMatrix.data()); - gl->functions->uniform1f(velCenterHandle, scaling ? 0.0f : 0.5f); - gl->functions->uniform1f(maxDistanceHandle, (MOTION_BLUR_SCALE_FACTOR - 1.0) * 0.5f); + auto gl = tgfx::GLFunctions::Get(context); + gl->uniformMatrix3fv(prevTransformHandle, 1, GL_FALSE, previousGLMatrix.data()); + gl->uniformMatrix3fv(transformHandle, 1, GL_FALSE, currentGLMatrix.data()); + gl->uniform1f(velCenterHandle, scaling ? 0.0f : 0.5f); + gl->uniform1f(maxDistanceHandle, (MOTION_BLUR_SCALE_FACTOR - 1.0) * 0.5f); } std::vector MotionBlurFilter::computeVertices(const tgfx::Rect& inputBounds, diff --git a/src/rendering/filters/MotionBlurFilter.h b/src/rendering/filters/MotionBlurFilter.h index 620fa35696..6224c9c90c 100644 --- a/src/rendering/filters/MotionBlurFilter.h +++ b/src/rendering/filters/MotionBlurFilter.h @@ -36,9 +36,9 @@ class MotionBlurFilter : public LayerFilter { std::string onBuildFragmentShader() override; - void onPrepareProgram(const tgfx::GLInterface* gl, unsigned program) override; + void onPrepareProgram(tgfx::Context* context, unsigned program) override; - void onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, + void onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) override; std::vector computeVertices(const tgfx::Rect& contentBounds, diff --git a/src/rendering/filters/MotionTileFilter.cpp b/src/rendering/filters/MotionTileFilter.cpp index e0dc320b0d..9b4fedfc6c 100644 --- a/src/rendering/filters/MotionTileFilter.cpp +++ b/src/rendering/filters/MotionTileFilter.cpp @@ -98,19 +98,19 @@ std::string MotionTileFilter::onBuildFragmentShader() { return MOTIONTILE_FRAGMENT_SHADER; } -void MotionTileFilter::onPrepareProgram(const tgfx::GLInterface* gl, unsigned int program) { - tileCenterHandle = gl->functions->getUniformLocation(program, "uTileCenter"); - tileWidthHandle = gl->functions->getUniformLocation(program, "uTileWidth"); - tileHeightHandle = gl->functions->getUniformLocation(program, "uTileHeight"); - outputWidthHandle = gl->functions->getUniformLocation(program, "uOutputWidth"); - outputHeightHandle = gl->functions->getUniformLocation(program, "uOutputHeight"); - mirrorEdgesHandle = gl->functions->getUniformLocation(program, "uMirrorEdges"); - phaseHandle = gl->functions->getUniformLocation(program, "uPhase"); - isHorizontalPhaseShiftHandle = - gl->functions->getUniformLocation(program, "uIsHorizontalPhaseShift"); +void MotionTileFilter::onPrepareProgram(tgfx::Context* context, unsigned int program) { + auto gl = tgfx::GLFunctions::Get(context); + tileCenterHandle = gl->getUniformLocation(program, "uTileCenter"); + tileWidthHandle = gl->getUniformLocation(program, "uTileWidth"); + tileHeightHandle = gl->getUniformLocation(program, "uTileHeight"); + outputWidthHandle = gl->getUniformLocation(program, "uOutputWidth"); + outputHeightHandle = gl->getUniformLocation(program, "uOutputHeight"); + mirrorEdgesHandle = gl->getUniformLocation(program, "uMirrorEdges"); + phaseHandle = gl->getUniformLocation(program, "uPhase"); + isHorizontalPhaseShiftHandle = gl->getUniformLocation(program, "uIsHorizontalPhaseShift"); } -void MotionTileFilter::onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, +void MotionTileFilter::onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point&) { auto* pagEffect = reinterpret_cast(effect); auto tileCenter = pagEffect->tileCenter->getValueAt(layerFrame); @@ -121,16 +121,15 @@ void MotionTileFilter::onUpdateParams(const tgfx::GLInterface* gl, const tgfx::R auto mirrorEdges = pagEffect->mirrorEdges->getValueAt(layerFrame); auto phase = pagEffect->phase->getValueAt(layerFrame); auto isHorizontalPhaseShift = pagEffect->horizontalPhaseShift->getValueAt(layerFrame); - - gl->functions->uniform2f(tileCenterHandle, - (tileCenter.x - contentBounds.x()) / contentBounds.width(), - 1.0f - (tileCenter.y - contentBounds.y()) / contentBounds.height()); - gl->functions->uniform1f(tileWidthHandle, tileWidth / 100.f); - gl->functions->uniform1f(tileHeightHandle, tileHeight / 100.f); - gl->functions->uniform1f(outputWidthHandle, outputWidth / 100.f); - gl->functions->uniform1f(outputHeightHandle, outputHeight / 100.f); - gl->functions->uniform1i(mirrorEdgesHandle, mirrorEdges); - gl->functions->uniform1f(phaseHandle, phase); - gl->functions->uniform1i(isHorizontalPhaseShiftHandle, isHorizontalPhaseShift); + auto gl = tgfx::GLFunctions::Get(context); + gl->uniform2f(tileCenterHandle, (tileCenter.x - contentBounds.x()) / contentBounds.width(), + 1.0f - (tileCenter.y - contentBounds.y()) / contentBounds.height()); + gl->uniform1f(tileWidthHandle, tileWidth / 100.f); + gl->uniform1f(tileHeightHandle, tileHeight / 100.f); + gl->uniform1f(outputWidthHandle, outputWidth / 100.f); + gl->uniform1f(outputHeightHandle, outputHeight / 100.f); + gl->uniform1i(mirrorEdgesHandle, mirrorEdges); + gl->uniform1f(phaseHandle, phase); + gl->uniform1i(isHorizontalPhaseShiftHandle, isHorizontalPhaseShift); } } // namespace pag diff --git a/src/rendering/filters/MotionTileFilter.h b/src/rendering/filters/MotionTileFilter.h index dfdbe33f03..976cd66d09 100644 --- a/src/rendering/filters/MotionTileFilter.h +++ b/src/rendering/filters/MotionTileFilter.h @@ -31,9 +31,9 @@ class MotionTileFilter : public LayerFilter { std::string onBuildFragmentShader() override; - void onPrepareProgram(const tgfx::GLInterface* gl, unsigned program) override; + void onPrepareProgram(tgfx::Context* context, unsigned program) override; - void onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, + void onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) override; private: diff --git a/src/rendering/filters/RadialBlurFilter.cpp b/src/rendering/filters/RadialBlurFilter.cpp index 91e9b674ed..37a06012fa 100644 --- a/src/rendering/filters/RadialBlurFilter.cpp +++ b/src/rendering/filters/RadialBlurFilter.cpp @@ -61,21 +61,22 @@ std::string RadialBlurFilter::onBuildFragmentShader() { return RADIAL_BLUR_FRAGMENT_SHADER; } -void RadialBlurFilter::onPrepareProgram(const tgfx::GLInterface* gl, unsigned int program) { - amountHandle = gl->functions->getUniformLocation(program, "uAmount"); - centerHandle = gl->functions->getUniformLocation(program, "uCenter"); +void RadialBlurFilter::onPrepareProgram(tgfx::Context* context, unsigned int program) { + auto gl = tgfx::GLFunctions::Get(context); + amountHandle = gl->getUniformLocation(program, "uAmount"); + centerHandle = gl->getUniformLocation(program, "uCenter"); } -void RadialBlurFilter::onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, +void RadialBlurFilter::onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point&) { auto* radialBlurEffect = reinterpret_cast(effect); auto amount = radialBlurEffect->amount->getValueAt(layerFrame) * 0.00625; auto center = radialBlurEffect->center->getValueAt(layerFrame); amount = amount < 0.25 ? amount : 0.25; - - gl->functions->uniform1f(amountHandle, amount); - gl->functions->uniform2f(centerHandle, (center.x - contentBounds.x()) / contentBounds.width(), - (center.y - contentBounds.y()) / contentBounds.height()); + auto gl = tgfx::GLFunctions::Get(context); + gl->uniform1f(amountHandle, amount); + gl->uniform2f(centerHandle, (center.x - contentBounds.x()) / contentBounds.width(), + (center.y - contentBounds.y()) / contentBounds.height()); } } // namespace pag diff --git a/src/rendering/filters/RadialBlurFilter.h b/src/rendering/filters/RadialBlurFilter.h index 0aaa4791e7..fd21e05af3 100644 --- a/src/rendering/filters/RadialBlurFilter.h +++ b/src/rendering/filters/RadialBlurFilter.h @@ -29,9 +29,9 @@ class RadialBlurFilter : public LayerFilter { protected: std::string onBuildFragmentShader() override; - void onPrepareProgram(const tgfx::GLInterface* gl, unsigned program) override; + void onPrepareProgram(tgfx::Context* context, unsigned program) override; - void onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, + void onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) override; private: diff --git a/src/rendering/filters/dropshadow/DropShadowFilter.cpp b/src/rendering/filters/dropshadow/DropShadowFilter.cpp index 150e2b900e..98a0c4f563 100644 --- a/src/rendering/filters/dropshadow/DropShadowFilter.cpp +++ b/src/rendering/filters/dropshadow/DropShadowFilter.cpp @@ -176,8 +176,7 @@ void DropShadowFilter::onDrawModeNotSpread(tgfx::Context* context, const FilterS if (blurFilterBuffer == nullptr) { return; } - auto gl = tgfx::GLInterface::Get(context); - blurFilterBuffer->clearColor(gl); + blurFilterBuffer->clearColor(); auto offsetMatrix = tgfx::Matrix::MakeTrans((contentBounds.left - filterBounds.left) * source->scale.x, @@ -215,8 +214,7 @@ void DropShadowFilter::onDrawModeNotFullSpread(tgfx::Context* context, const Fil if (spreadFilterBuffer == nullptr) { return; } - auto gl = tgfx::GLInterface::Get(context); - spreadFilterBuffer->clearColor(gl); + spreadFilterBuffer->clearColor(); auto offsetMatrix = tgfx::Matrix::MakeTrans((lastBounds.left - filterBounds.left) * source->scale.x, (lastBounds.top - filterBounds.top) * source->scale.y); @@ -239,7 +237,7 @@ void DropShadowFilter::onDrawModeNotFullSpread(tgfx::Context* context, const Fil if (blurFilterBuffer == nullptr) { return; } - blurFilterBuffer->clearColor(gl); + blurFilterBuffer->clearColor(); offsetMatrix = tgfx::Matrix::MakeTrans((lastBounds.left - filterBounds.left) * source->scale.x, (lastBounds.top - filterBounds.top) * source->scale.y); auto targetV = blurFilterBuffer->toFilterTarget(offsetMatrix); diff --git a/src/rendering/filters/dropshadow/DropShadowSpreadFilter.cpp b/src/rendering/filters/dropshadow/DropShadowSpreadFilter.cpp index 37b900b4b1..2538586d1e 100644 --- a/src/rendering/filters/dropshadow/DropShadowSpreadFilter.cpp +++ b/src/rendering/filters/dropshadow/DropShadowSpreadFilter.cpp @@ -88,14 +88,14 @@ std::string DropShadowSpreadFilter::onBuildFragmentShader() { return DROPSHADOW_SPREAD_FRAGMENT_SHADER; } -void DropShadowSpreadFilter::onPrepareProgram(const tgfx::GLInterface* gl, unsigned program) { - spreadColorHandle = gl->functions->getUniformLocation(program, "uColor"); - spreadAlphaHandle = gl->functions->getUniformLocation(program, "uAlpha"); - spreadSizeHandle = gl->functions->getUniformLocation(program, "uSize"); +void DropShadowSpreadFilter::onPrepareProgram(tgfx::Context* context, unsigned program) { + auto gl = tgfx::GLFunctions::Get(context); + spreadColorHandle = gl->getUniformLocation(program, "uColor"); + spreadAlphaHandle = gl->getUniformLocation(program, "uAlpha"); + spreadSizeHandle = gl->getUniformLocation(program, "uSize"); } -void DropShadowSpreadFilter::onUpdateParams(const tgfx::GLInterface* gl, - const tgfx::Rect& contentBounds, +void DropShadowSpreadFilter::onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) { auto color = ToTGFX(layerStyle->color->getValueAt(layerFrame)); auto alpha = ToAlpha(layerStyle->opacity->getValueAt(layerFrame)); @@ -107,11 +107,11 @@ void DropShadowSpreadFilter::onUpdateParams(const tgfx::GLInterface* gl, auto spreadSizeY = size * spread * filterScale.y; spreadSizeX = std::min(spreadSizeX, DROPSHADOW_MAX_SPREAD_SIZE); spreadSizeY = std::min(spreadSizeY, DROPSHADOW_MAX_SPREAD_SIZE); - - gl->functions->uniform3f(spreadColorHandle, color.red, color.green, color.blue); - gl->functions->uniform1f(spreadAlphaHandle, alpha); - gl->functions->uniform2f(spreadSizeHandle, spreadSizeX / contentBounds.width(), - spreadSizeY / contentBounds.height()); + auto gl = tgfx::GLFunctions::Get(context); + gl->uniform3f(spreadColorHandle, color.red, color.green, color.blue); + gl->uniform1f(spreadAlphaHandle, alpha); + gl->uniform2f(spreadSizeHandle, spreadSizeX / contentBounds.width(), + spreadSizeY / contentBounds.height()); } std::vector DropShadowSpreadFilter::computeVertices(const tgfx::Rect&, diff --git a/src/rendering/filters/dropshadow/DropShadowSpreadFilter.h b/src/rendering/filters/dropshadow/DropShadowSpreadFilter.h index a0573217d6..74b1ef6a70 100644 --- a/src/rendering/filters/dropshadow/DropShadowSpreadFilter.h +++ b/src/rendering/filters/dropshadow/DropShadowSpreadFilter.h @@ -31,9 +31,9 @@ class DropShadowSpreadFilter : public LayerFilter { protected: std::string onBuildFragmentShader() override; - void onPrepareProgram(const tgfx::GLInterface* gl, unsigned program) override; + void onPrepareProgram(tgfx::Context* context, unsigned program) override; - void onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, + void onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) override; std::vector computeVertices(const tgfx::Rect& contentBounds, diff --git a/src/rendering/filters/gaussblur/GaussBlurFilter.cpp b/src/rendering/filters/gaussblur/GaussBlurFilter.cpp index 377dfefb99..1b7e253530 100644 --- a/src/rendering/filters/gaussblur/GaussBlurFilter.cpp +++ b/src/rendering/filters/gaussblur/GaussBlurFilter.cpp @@ -101,8 +101,7 @@ void GaussBlurFilter::draw(tgfx::Context* context, const FilterSource* source, if (blurFilterBuffer == nullptr) { return; } - auto gl = tgfx::GLInterface::Get(context); - blurFilterBuffer->clearColor(gl); + blurFilterBuffer->clearColor(); auto offsetMatrix = tgfx::Matrix::MakeTrans((contentBounds.left - blurVBounds.left) * source->scale.x, diff --git a/src/rendering/filters/gaussblur/SinglePassBlurFilter.cpp b/src/rendering/filters/gaussblur/SinglePassBlurFilter.cpp index dc9a67ba5f..06a9e2b8dd 100644 --- a/src/rendering/filters/gaussblur/SinglePassBlurFilter.cpp +++ b/src/rendering/filters/gaussblur/SinglePassBlurFilter.cpp @@ -83,13 +83,14 @@ std::string SinglePassBlurFilter::onBuildFragmentShader() { return BLUR_FRAGMENT_SHADER; } -void SinglePassBlurFilter::onPrepareProgram(const tgfx::GLInterface* gl, unsigned int program) { - radiusHandle = gl->functions->getUniformLocation(program, "uRadius"); - levelHandle = gl->functions->getUniformLocation(program, "uLevel"); - repeatEdgeHandle = gl->functions->getUniformLocation(program, "uRepeatEdge"); - colorHandle = gl->functions->getUniformLocation(program, "uColor"); - colorValidHandle = gl->functions->getUniformLocation(program, "uColorValid"); - alphaHandle = gl->functions->getUniformLocation(program, "uAlpha"); +void SinglePassBlurFilter::onPrepareProgram(tgfx::Context* context, unsigned int program) { + auto gl = tgfx::GLFunctions::Get(context); + radiusHandle = gl->getUniformLocation(program, "uRadius"); + levelHandle = gl->getUniformLocation(program, "uLevel"); + repeatEdgeHandle = gl->getUniformLocation(program, "uRepeatEdge"); + colorHandle = gl->getUniformLocation(program, "uColor"); + colorValidHandle = gl->getUniformLocation(program, "uColorValid"); + alphaHandle = gl->getUniformLocation(program, "uAlpha"); } void SinglePassBlurFilter::updateParams(float blurrinessValue, float blurAlphaValue, @@ -121,25 +122,24 @@ void SinglePassBlurFilter::disableBlurColor() { color = tgfx::Color::Black(); } -void SinglePassBlurFilter::onUpdateParams(const tgfx::GLInterface* gl, - const tgfx::Rect& contentBounds, +void SinglePassBlurFilter::onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) { auto scale = direction == BlurDirection::Horizontal ? filterScale.x : filterScale.y; auto blurValue = std::min(blurriness * scale, BLUR_LIMIT_BLURRINESS); auto blurRadius = blurValue / BLUR_LIMIT_BLURRINESS * (maxRadius - 1.0) + 1.0; auto blurLevel = blurValue / BLUR_LIMIT_BLURRINESS * (maxLevel - 1.0) + 1.0; - - gl->functions->uniform1f(radiusHandle, blurRadius); - gl->functions->uniform2f(levelHandle, - blurLevel / static_cast(contentBounds.width()) * - (direction == BlurDirection::Horizontal), - blurLevel / static_cast(contentBounds.height()) * - (direction == BlurDirection::Vertical)); - gl->functions->uniform1f(repeatEdgeHandle, repeatEdge); - gl->functions->uniform3f(colorHandle, color.red, color.green, color.blue); - gl->functions->uniform1f(colorValidHandle, isColorValid); - gl->functions->uniform1f(alphaHandle, alpha); + auto gl = tgfx::GLFunctions::Get(context); + gl->uniform1f(radiusHandle, blurRadius); + gl->uniform2f(levelHandle, + blurLevel / static_cast(contentBounds.width()) * + (direction == BlurDirection::Horizontal), + blurLevel / static_cast(contentBounds.height()) * + (direction == BlurDirection::Vertical)); + gl->uniform1f(repeatEdgeHandle, repeatEdge); + gl->uniform3f(colorHandle, color.red, color.green, color.blue); + gl->uniform1f(colorValidHandle, isColorValid); + gl->uniform1f(alphaHandle, alpha); } std::vector SinglePassBlurFilter::computeVertices(const tgfx::Rect& inputBounds, diff --git a/src/rendering/filters/gaussblur/SinglePassBlurFilter.h b/src/rendering/filters/gaussblur/SinglePassBlurFilter.h index 38cde6a267..6fefe38dd1 100644 --- a/src/rendering/filters/gaussblur/SinglePassBlurFilter.h +++ b/src/rendering/filters/gaussblur/SinglePassBlurFilter.h @@ -35,9 +35,9 @@ class SinglePassBlurFilter : public LayerFilter { protected: std::string onBuildFragmentShader() override; - void onPrepareProgram(const tgfx::GLInterface* gl, unsigned program) override; + void onPrepareProgram(tgfx::Context* context, unsigned program) override; - void onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, + void onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) override; std::vector computeVertices(const tgfx::Rect& contentBounds, diff --git a/src/rendering/filters/glow/GlowBlurFilter.cpp b/src/rendering/filters/glow/GlowBlurFilter.cpp index cbf82da639..0c2f7fa5c3 100644 --- a/src/rendering/filters/glow/GlowBlurFilter.cpp +++ b/src/rendering/filters/glow/GlowBlurFilter.cpp @@ -71,20 +71,21 @@ std::string GlowBlurFilter::onBuildFragmentShader() { return GLOW_BLUR_FRAGMENT_SHADER; } -void GlowBlurFilter::onPrepareProgram(const tgfx::GLInterface* gl, unsigned int program) { - textureOffsetHHandle = gl->functions->getUniformLocation(program, "textureOffsetH"); - textureOffsetVHandle = gl->functions->getUniformLocation(program, "textureOffsetV"); +void GlowBlurFilter::onPrepareProgram(tgfx::Context* context, unsigned int program) { + auto gl = tgfx::GLFunctions::Get(context); + textureOffsetHHandle = gl->getUniformLocation(program, "textureOffsetH"); + textureOffsetVHandle = gl->getUniformLocation(program, "textureOffsetV"); } void GlowBlurFilter::updateOffset(float offset) { blurOffset = offset; } -void GlowBlurFilter::onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect&, - const tgfx::Point&) { +void GlowBlurFilter::onUpdateParams(tgfx::Context* context, const tgfx::Rect&, const tgfx::Point&) { auto textureOffsetH = blurDirection == BlurDirection::Horizontal ? blurOffset : 0; auto textureOffsetV = blurDirection == BlurDirection::Vertical ? blurOffset : 0; - gl->functions->uniform1f(textureOffsetHHandle, textureOffsetH); - gl->functions->uniform1f(textureOffsetVHandle, textureOffsetV); + auto gl = tgfx::GLFunctions::Get(context); + gl->uniform1f(textureOffsetHHandle, textureOffsetH); + gl->uniform1f(textureOffsetVHandle, textureOffsetV); } } // namespace pag diff --git a/src/rendering/filters/glow/GlowBlurFilter.h b/src/rendering/filters/glow/GlowBlurFilter.h index b4f1edd412..ea400e4c3a 100644 --- a/src/rendering/filters/glow/GlowBlurFilter.h +++ b/src/rendering/filters/glow/GlowBlurFilter.h @@ -34,9 +34,9 @@ class GlowBlurFilter : public LayerFilter { std::string onBuildFragmentShader() override; - void onPrepareProgram(const tgfx::GLInterface* gl, unsigned program) override; + void onPrepareProgram(tgfx::Context* context, unsigned program) override; - void onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, + void onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) override; private: diff --git a/src/rendering/filters/glow/GlowFilter.cpp b/src/rendering/filters/glow/GlowFilter.cpp index 53b9f95025..4c5ee367ff 100644 --- a/src/rendering/filters/glow/GlowFilter.cpp +++ b/src/rendering/filters/glow/GlowFilter.cpp @@ -93,9 +93,8 @@ void GlowFilter::draw(tgfx::Context* context, const FilterSource* source, if (!checkBuffer(context, blurWidth, blurHeight)) { return; } - auto gl = tgfx::GLInterface::Get(context); - blurFilterBufferH->clearColor(gl); - blurFilterBufferV->clearColor(gl); + blurFilterBufferH->clearColor(); + blurFilterBufferV->clearColor(); auto targetH = blurFilterBufferH->toFilterTarget(tgfx::Matrix::I()); blurFilterH->updateOffset(1.0f / blurWidth); @@ -106,7 +105,7 @@ void GlowFilter::draw(tgfx::Context* context, const FilterSource* source, blurFilterV->updateOffset(1.0f / blurHeight); blurFilterV->draw(context, sourceV.get(), targetV.get()); - targetFilter->updateTexture(blurFilterBufferV->getTexture().id); + targetFilter->updateTexture(blurFilterBufferV->getTexture()); targetFilter->draw(context, source, target); } } // namespace pag diff --git a/src/rendering/filters/glow/GlowMergeFilter.cpp b/src/rendering/filters/glow/GlowMergeFilter.cpp index 1e322ff043..366f72894a 100644 --- a/src/rendering/filters/glow/GlowMergeFilter.cpp +++ b/src/rendering/filters/glow/GlowMergeFilter.cpp @@ -49,25 +49,27 @@ std::string GlowMergeFilter::onBuildFragmentShader() { return GLOW_TARGET_FRAGMENT_SHADER; } -void GlowMergeFilter::onPrepareProgram(const tgfx::GLInterface* gl, unsigned int program) { - inputTextureHandle = gl->functions->getUniformLocation(program, "inputImageTexture"); - blurTextureHandle = gl->functions->getUniformLocation(program, "blurImageTexture"); - progressHandle = gl->functions->getUniformLocation(program, "progress"); +void GlowMergeFilter::onPrepareProgram(tgfx::Context* context, unsigned int program) { + auto gl = tgfx::GLFunctions::Get(context); + inputTextureHandle = gl->getUniformLocation(program, "inputImageTexture"); + blurTextureHandle = gl->getUniformLocation(program, "blurImageTexture"); + progressHandle = gl->getUniformLocation(program, "progress"); } -void GlowMergeFilter::updateTexture(unsigned blurTexture) { - blurTextureID = blurTexture; +void GlowMergeFilter::updateTexture(const tgfx::GLSampler& sampler) { + blurTexture = sampler; } -void GlowMergeFilter::onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect&, +void GlowMergeFilter::onUpdateParams(tgfx::Context* context, const tgfx::Rect&, const tgfx::Point&) { auto glowEffect = static_cast(effect); auto glowThreshold = glowEffect->glowThreshold->getValueAt(layerFrame); - gl->functions->uniform1f(progressHandle, glowThreshold); - gl->functions->uniform1i(inputTextureHandle, 0); - // TODO(domrjchen): 下面这行之前写成了 gl->functions->uniform1i(progressHandle, 1), 会导致 glError, + auto gl = tgfx::GLFunctions::Get(context); + gl->uniform1f(progressHandle, glowThreshold); + gl->uniform1i(inputTextureHandle, 0); + // TODO(domrjchen): 下面这行之前写成了 gl->uniform1i(progressHandle, 1), 会导致 glError, // 暂时注释掉。目前的发光效果跟 AE 也没有对齐,后面重写发光效果时时再修复。 - // gl->functions->uniform1i(blurTextureHandle, 1); - ActiveGLTexture(gl, GL_TEXTURE1, GL_TEXTURE_2D, blurTextureID); + // gl->uniform1i(blurTextureHandle, 1); + tgfx::GLContext::Unwrap(context)->bindTexture(1, &blurTexture); } } // namespace pag diff --git a/src/rendering/filters/glow/GlowMergeFilter.h b/src/rendering/filters/glow/GlowMergeFilter.h index 5b5873c26e..1537826135 100644 --- a/src/rendering/filters/glow/GlowMergeFilter.h +++ b/src/rendering/filters/glow/GlowMergeFilter.h @@ -26,14 +26,14 @@ class GlowMergeFilter : public LayerFilter { explicit GlowMergeFilter(Effect* effect); ~GlowMergeFilter() override = default; - void updateTexture(unsigned blurTexture); + void updateTexture(const tgfx::GLSampler& sampler); protected: std::string onBuildFragmentShader() override; - void onPrepareProgram(const tgfx::GLInterface* gl, unsigned program) override; + void onPrepareProgram(tgfx::Context* context, unsigned program) override; - void onUpdateParams(const tgfx::GLInterface* gl, const tgfx::Rect& contentBounds, + void onUpdateParams(tgfx::Context* context, const tgfx::Rect& contentBounds, const tgfx::Point& filterScale) override; private: @@ -42,6 +42,6 @@ class GlowMergeFilter : public LayerFilter { int inputTextureHandle = -1; int blurTextureHandle = -1; int progressHandle = -1; - unsigned blurTextureID = 0; + tgfx::GLSampler blurTexture = {}; }; } // namespace pag diff --git a/src/rendering/filters/utils/FilterBuffer.cpp b/src/rendering/filters/utils/FilterBuffer.cpp index a4131ad924..ae261543eb 100644 --- a/src/rendering/filters/utils/FilterBuffer.cpp +++ b/src/rendering/filters/utils/FilterBuffer.cpp @@ -41,13 +41,13 @@ tgfx::GLSampler FilterBuffer::getTexture() const { return texture->glSampler(); } -void FilterBuffer::clearColor(const tgfx::GLInterface*) const { +void FilterBuffer::clearColor() const { surface->getCanvas()->clear(); } std::unique_ptr FilterBuffer::toFilterSource(const tgfx::Point& scale) const { auto filterSource = new FilterSource(); - filterSource->textureID = getTexture().id; + filterSource->sampler = getTexture(); filterSource->width = surface->width(); filterSource->height = surface->height(); filterSource->scale = scale; @@ -60,7 +60,7 @@ std::unique_ptr FilterBuffer::toFilterSource(const tgfx::Point& sc std::unique_ptr FilterBuffer::toFilterTarget( const tgfx::Matrix& drawingMatrix) const { auto filterTarget = new FilterTarget(); - filterTarget->frameBufferID = getFramebuffer().id; + filterTarget->frameBuffer = getFramebuffer(); filterTarget->width = surface->width(); filterTarget->height = surface->height(); filterTarget->vertexMatrix = tgfx::ToGLVertexMatrix( diff --git a/src/rendering/filters/utils/FilterBuffer.h b/src/rendering/filters/utils/FilterBuffer.h index 682973b48b..f353608f3e 100644 --- a/src/rendering/filters/utils/FilterBuffer.h +++ b/src/rendering/filters/utils/FilterBuffer.h @@ -31,7 +31,7 @@ class FilterBuffer { static std::shared_ptr Make(tgfx::Context* context, int width, int height, bool usesMSAA = false); - void clearColor(const tgfx::GLInterface* gl) const; + void clearColor() const; std::unique_ptr toFilterSource(const tgfx::Point& scale) const; diff --git a/src/rendering/filters/utils/FilterHelper.cpp b/src/rendering/filters/utils/FilterHelper.cpp index c66c093a42..88813f58cf 100644 --- a/src/rendering/filters/utils/FilterHelper.cpp +++ b/src/rendering/filters/utils/FilterHelper.cpp @@ -49,7 +49,7 @@ std::unique_ptr ToFilterSource(const tgfx::Texture* texture, return nullptr; } auto filterSource = new FilterSource(); - filterSource->textureID = GetTextureID(texture); + filterSource->sampler = *static_cast(texture->getSampler()); filterSource->width = texture->width(); filterSource->height = texture->height(); filterSource->scale = scale; @@ -65,7 +65,7 @@ std::unique_ptr ToFilterTarget(const tgfx::Surface* surface, } auto renderTarget = std::static_pointer_cast(surface->getRenderTarget()); auto filterTarget = new FilterTarget(); - filterTarget->frameBufferID = renderTarget->glFrameBuffer().id; + filterTarget->frameBuffer = renderTarget->glFrameBuffer(); filterTarget->width = surface->width(); filterTarget->height = surface->height(); filterTarget->vertexMatrix = @@ -93,11 +93,4 @@ void PreConcatMatrix(FilterTarget* target, const tgfx::Matrix& matrix) { target->vertexMatrix = tgfx::ToGLVertexMatrix(vertexMatrix, target->width, target->height, tgfx::ImageOrigin::BottomLeft); } - -unsigned GetTextureID(const tgfx::Texture* texture) { - if (texture == nullptr || texture->isYUV()) { - return 0; - } - return static_cast(texture)->glSampler().id; -} } // namespace pag diff --git a/src/rendering/filters/utils/FilterHelper.h b/src/rendering/filters/utils/FilterHelper.h index b64905dcd4..6dbf4aee6a 100644 --- a/src/rendering/filters/utils/FilterHelper.h +++ b/src/rendering/filters/utils/FilterHelper.h @@ -40,6 +40,4 @@ tgfx::Point ToGLVertexPoint(const FilterTarget* target, const FilterSource* sour const tgfx::Rect& contentBounds, const tgfx::Point& contentPoint); void PreConcatMatrix(FilterTarget* target, const tgfx::Matrix& matrix); - -unsigned GetTextureID(const tgfx::Texture* texture); } // namespace pag diff --git a/src/rendering/renderers/FilterRenderer.cpp b/src/rendering/renderers/FilterRenderer.cpp index 2d55a71e26..7bfa190ec2 100644 --- a/src/rendering/renderers/FilterRenderer.cpp +++ b/src/rendering/renderers/FilterRenderer.cpp @@ -308,7 +308,6 @@ std::vector FilterRenderer::MakeFilterNodes(const FilterList* filter void ApplyFilters(tgfx::Context* context, std::vector filterNodes, const tgfx::Rect& contentBounds, FilterSource* filterSource, FilterTarget* filterTarget) { - auto gl = tgfx::GLInterface::Get(context); auto scale = filterSource->scale; std::shared_ptr freeBuffer = nullptr; std::shared_ptr lastBuffer = nullptr; @@ -335,7 +334,7 @@ void ApplyFilters(tgfx::Context* context, std::vector filterNodes, if (currentBuffer == nullptr) { return; } - currentBuffer->clearColor(gl); + currentBuffer->clearColor(); auto offsetMatrix = tgfx::Matrix::MakeTrans((lastBounds.left - node.bounds.left) * scale.x, (lastBounds.top - node.bounds.top) * scale.y); auto currentTarget = currentBuffer->toFilterTarget(offsetMatrix); @@ -485,6 +484,8 @@ void FilterRenderer::DrawWithFilter(tgfx::Canvas* parentCanvas, RenderCache* cac parentCanvas->flush(); auto context = parentCanvas->getContext(); ApplyFilters(context, filterNodes, contentBounds, filterSource.get(), filterTarget.get()); + // Reset the GL states stored in the context, they may be modified during the filter being applied. + context->resetState(); if (targetSurface) { tgfx::Matrix drawingMatrix = {}; diff --git a/test/PAGBlendTest.cpp b/test/PAGBlendTest.cpp index ab7f2d6023..6a209b01f3 100644 --- a/test/PAGBlendTest.cpp +++ b/test/PAGBlendTest.cpp @@ -53,9 +53,8 @@ PAG_TEST_F(PAGBlendTest, Blend) { tgfx::GLSampler GetBottomLeftImage(std::shared_ptr device, int width, int height) { auto context = device->lockContext(); - auto gl = GLInterface::Get(context); tgfx::GLSampler textureInfo; - CreateGLTexture(gl, width, height, &textureInfo); + CreateGLTexture(context, width, height, &textureInfo); auto backendTexture = ToBackendTexture(textureInfo, width, height); auto surface = PAGSurface::MakeFrom(backendTexture, ImageOrigin::BottomLeft); device->unlock(); @@ -79,9 +78,8 @@ PAG_TEST_F(PAGBlendTest, CopyDstTexture) { auto device = GLDevice::Make(); auto context = device->lockContext(); ASSERT_TRUE(context != nullptr); - auto gl = GLInterface::Get(context); tgfx::GLSampler textureInfo; - CreateGLTexture(gl, width, height, &textureInfo); + CreateGLTexture(context, width, height, &textureInfo); auto backendTexture = ToBackendTexture(textureInfo, width, height); auto pagSurface = PAGSurface::MakeFrom(backendTexture, ImageOrigin::BottomLeft); device->unlock(); @@ -95,8 +93,8 @@ PAG_TEST_F(PAGBlendTest, CopyDstTexture) { EXPECT_TRUE(Baseline::Compare(pagSurface, "PAGBlendTest/CopyDstTexture")); context = device->lockContext(); - gl = GLInterface::Get(context); - gl->functions->deleteTextures(1, &textureInfo.id); + auto gl = GLFunctions::Get(context); + gl->deleteTextures(1, &textureInfo.id); device->unlock(); } @@ -110,11 +108,10 @@ PAG_TEST_F(PAGBlendTest, TextureBottomLeft) { auto replaceTextureInfo = GetBottomLeftImage(device, width, height); auto context = device->lockContext(); ASSERT_TRUE(context != nullptr); - auto gl = GLInterface::Get(context); auto backendTexture = ToBackendTexture(replaceTextureInfo, width, height); auto replaceImage = PAGImage::FromTexture(backendTexture, ImageOrigin::BottomLeft); tgfx::GLSampler textureInfo; - CreateGLTexture(gl, width, height, &textureInfo); + CreateGLTexture(context, width, height, &textureInfo); backendTexture = ToBackendTexture(textureInfo, width, height); auto pagSurface = PAGSurface::MakeFrom(backendTexture, ImageOrigin::TopLeft); device->unlock(); @@ -130,9 +127,9 @@ PAG_TEST_F(PAGBlendTest, TextureBottomLeft) { EXPECT_TRUE(Baseline::Compare(pagSurface, "PAGBlendTest/TextureBottomLeft")); context = device->lockContext(); - gl = GLInterface::Get(context); - gl->functions->deleteTextures(1, &replaceTextureInfo.id); - gl->functions->deleteTextures(1, &textureInfo.id); + auto gl = GLFunctions::Get(context); + gl->deleteTextures(1, &replaceTextureInfo.id); + gl->deleteTextures(1, &textureInfo.id); device->unlock(); } @@ -150,9 +147,8 @@ PAG_TEST_F(PAGBlendTest, BothBottomLeft) { auto replaceImage = PAGImage::FromTexture(backendTexture, ImageOrigin::BottomLeft); replaceImage->setMatrix( Matrix::MakeTrans(static_cast(width) * 0.1, static_cast(height) * 0.2)); - auto gl = GLInterface::Get(context); tgfx::GLSampler textureInfo = {}; - CreateGLTexture(gl, width, height, &textureInfo); + CreateGLTexture(context, width, height, &textureInfo); backendTexture = ToBackendTexture(textureInfo, width, height); auto pagSurface = PAGSurface::MakeFrom(backendTexture, ImageOrigin::BottomLeft); device->unlock(); @@ -172,9 +168,9 @@ PAG_TEST_F(PAGBlendTest, BothBottomLeft) { context = device->lockContext(); ASSERT_TRUE(context != nullptr); - gl = GLInterface::Get(context); - gl->functions->deleteTextures(1, &replaceTextureInfo.id); - gl->functions->deleteTextures(1, &textureInfo.id); + auto gl = GLFunctions::Get(context); + gl->deleteTextures(1, &replaceTextureInfo.id); + gl->deleteTextures(1, &textureInfo.id); device->unlock(); } } // namespace pag diff --git a/test/PAGReadPixelsTest.cpp b/test/PAGReadPixelsTest.cpp index fff12228f6..4aa0e6cd85 100644 --- a/test/PAGReadPixelsTest.cpp +++ b/test/PAGReadPixelsTest.cpp @@ -224,13 +224,12 @@ PAG_TEST(PAGReadPixelsTest, TestSurfaceReadPixels) { ASSERT_TRUE(result); CHECK_PIXELS(AlphaRectInfo, pixels, "Surface_alpha_to_alpha_100_-100"); - auto gl = GLInterface::Get(context); tgfx::GLSampler textureInfo = {}; - result = CreateGLTexture(gl, width, height, &textureInfo); + result = CreateGLTexture(context, width, height, &textureInfo); ASSERT_TRUE(result); auto glTexture = GLTexture::MakeFrom(context, textureInfo, width, height, tgfx::ImageOrigin::BottomLeft); - surface = Surface::MakeFrom(context, glTexture); + surface = Surface::MakeFrom(glTexture); ASSERT_TRUE(surface != nullptr); canvas = surface->getCanvas(); canvas->clear(); @@ -254,8 +253,8 @@ PAG_TEST(PAGReadPixelsTest, TestSurfaceReadPixels) { result = surface->readPixels(RGBARectInfo, pixels, 100, -100); ASSERT_TRUE(result); CHECK_PIXELS(RGBARectInfo, pixels, "Surface_BL_rgbA_to_rgbA_100_-100"); - - gl->functions->deleteTextures(1, &textureInfo.id); + auto gl = GLFunctions::Get(context); + gl->deleteTextures(1, &textureInfo.id); device->unlock(); } diff --git a/test/PAGSurfaceTest.cpp b/test/PAGSurfaceTest.cpp index 6e44112cbf..e6d4b2c84c 100644 --- a/test/PAGSurfaceTest.cpp +++ b/test/PAGSurfaceTest.cpp @@ -38,10 +38,10 @@ PAG_TEST(PAGSurfaceTest, FromTexture) { auto device = GLDevice::Make(); auto context = device->lockContext(); ASSERT_TRUE(context != nullptr); - auto gl = GLInterface::Get(context); - auto glVersion = gl->caps->version; + + auto glVersion = GLCaps::Get(context)->version; tgfx::GLSampler textureInfo; - CreateGLTexture(gl, width, height, &textureInfo); + CreateGLTexture(context, width, height, &textureInfo); auto backendTexture = ToBackendTexture(textureInfo, width, height); auto pagSurface = PAGSurface::MakeFrom(backendTexture, ImageOrigin::TopLeft); auto nativeHandle = GLDevice::CurrentNativeHandle(); @@ -91,9 +91,8 @@ PAG_TEST(PAGSurfaceTest, Mask) { auto device = GLDevice::Make(); auto context = device->lockContext(); ASSERT_TRUE(context != nullptr); - auto gl = GLInterface::Get(context); tgfx::GLSampler textureInfo; - CreateGLTexture(gl, width, height, &textureInfo); + CreateGLTexture(context, width, height, &textureInfo); auto backendTexture = ToBackendTexture(textureInfo, width, height); auto pagSurface = PAGSurface::MakeFrom(backendTexture, ImageOrigin::BottomLeft); device->unlock(); @@ -108,8 +107,8 @@ PAG_TEST(PAGSurfaceTest, Mask) { context = device->lockContext(); ASSERT_TRUE(context != nullptr); - gl = GLInterface::Get(context); - gl->functions->deleteTextures(1, &textureInfo.id); + auto gl = GLFunctions::Get(context); + gl->deleteTextures(1, &textureInfo.id); device->unlock(); } } // namespace pag diff --git a/tgfx/include/gpu/Context.h b/tgfx/include/gpu/Context.h index 43955e66c1..39f73b7eae 100644 --- a/tgfx/include/gpu/Context.h +++ b/tgfx/include/gpu/Context.h @@ -79,6 +79,13 @@ class Context { */ virtual const Caps* caps() const = 0; + /** + * The Context normally assumes that no outsider is setting state within the underlying GPU API's + * context/device/whatever. This call informs the context that the state was modified and it + * should resend. Shouldn't be called frequently for good performance. + */ + virtual void resetState() = 0; + protected: explicit Context(Device* device); diff --git a/tgfx/include/gpu/Resource.h b/tgfx/include/gpu/Resource.h index bffe9d49fa..e4f0db31fe 100644 --- a/tgfx/include/gpu/Resource.h +++ b/tgfx/include/gpu/Resource.h @@ -22,7 +22,7 @@ namespace tgfx { /** - * The base class for GPU resource. Overrides the onRelease() method to to free all GPU resources. + * The base class for GPU resource. Overrides the onReleaseGPU() method to to free all GPU resources. * No backend API calls should be made during destructuring since there may be no GPU context which * is current on the calling thread. * Note: Resource is not thread safe, do not access any properties of a Resource unless its @@ -47,24 +47,25 @@ class Resource { } protected: + Context* context = nullptr; + /** * Overridden to compute a recycleKey to make this Resource reusable. */ virtual void computeRecycleKey(BytesKey*) const { } - /** - * Overridden to free GPU resources in the backend API. - */ - virtual void onRelease(Context* context) = 0; - private: - Context* context = nullptr; std::weak_ptr weakThis; BytesKey recycleKey = {}; size_t cacheArrayIndex = 0; int64_t lastUsedTime = 0; + /** + * Overridden to free GPU resources in the backend API. + */ + virtual void onReleaseGPU() = 0; + friend class ResourceCache; }; } // namespace tgfx diff --git a/tgfx/include/gpu/Surface.h b/tgfx/include/gpu/Surface.h index bc4563a0b0..a364760361 100644 --- a/tgfx/include/gpu/Surface.h +++ b/tgfx/include/gpu/Surface.h @@ -59,15 +59,13 @@ class Surface { /** * Wraps a render target into Surface. Returns nullptr if renderTarget is nullptr. */ - static std::shared_ptr MakeFrom(Context* context, - std::shared_ptr renderTarget); + static std::shared_ptr MakeFrom(std::shared_ptr renderTarget); /** * Wraps a texture into Surface. A Surface with MSAA enabled is returned if the sampleCount is * greater than 1. Returns nullptr if the specified texture is not renderable. */ - static std::shared_ptr MakeFrom(Context* context, std::shared_ptr texture, - int sampleCount = 1); + static std::shared_ptr MakeFrom(std::shared_ptr texture, int sampleCount = 1); explicit Surface(Context* context); @@ -168,11 +166,12 @@ class Surface { bool hitTest(float x, float y) const; protected: + Context* context = nullptr; + virtual bool onReadPixels(const ImageInfo& dstInfo, void* dstPixels, int srcX, int srcY) const = 0; private: - Context* context = nullptr; std::unique_ptr surfaceOptions = nullptr; }; } // namespace tgfx \ No newline at end of file diff --git a/tgfx/include/gpu/opengl/GLRenderTarget.h b/tgfx/include/gpu/opengl/GLRenderTarget.h index afd14c31cc..6d8dc147c3 100644 --- a/tgfx/include/gpu/opengl/GLRenderTarget.h +++ b/tgfx/include/gpu/opengl/GLRenderTarget.h @@ -58,9 +58,6 @@ class GLRenderTarget : public RenderTarget { return renderTargetFBInfo; } - protected: - void onRelease(Context* context) override; - private: GLFrameBuffer textureFBInfo = {}; GLFrameBuffer renderTargetFBInfo = {}; @@ -72,23 +69,23 @@ class GLRenderTarget : public RenderTarget { * Creates a new render target which uses specified texture as pixel storage. Caller must ensure * texture is valid for the lifetime of returned render target. */ - static std::shared_ptr MakeFrom(Context* context, const GLTexture* texture, - int sampleCount = 1); + static std::shared_ptr MakeFrom(const GLTexture* texture, int sampleCount = 1); GLRenderTarget(int width, int height, ImageOrigin origin, int sampleCount, GLFrameBuffer frameBuffer, unsigned textureTarget = 0); - void clear(const GLInterface* gl) const; + void onReleaseGPU() override; + + void clear() const; - void resolve(Context* context) const; + void resolve() const; /** * Copies a rect of pixels to dstPixels with specified color type, alpha type and row bytes. Copy * starts at (srcX, srcY), and does not exceed Surface (width(), height()). Pixels are copied * only if pixel conversion is possible. Returns true if pixels are copied to dstPixels. */ - bool readPixels(Context* context, const ImageInfo& dstInfo, void* dstPixels, int srcX = 0, - int srcY = 0) const; + bool readPixels(const ImageInfo& dstInfo, void* dstPixels, int srcX = 0, int srcY = 0) const; friend class GLSurface; diff --git a/tgfx/include/gpu/opengl/GLYUVTexture.h b/tgfx/include/gpu/opengl/GLYUVTexture.h index c2f7936516..b0669abbe5 100644 --- a/tgfx/include/gpu/opengl/GLYUVTexture.h +++ b/tgfx/include/gpu/opengl/GLYUVTexture.h @@ -40,7 +40,8 @@ class GLYUVTexture : public YUVTexture { GLYUVTexture(YUVColorSpace colorSpace, YUVColorRange colorRange, int width, int height); - void onRelease(Context*) override; + private: + void onReleaseGPU() override; friend class YUVTexture; }; diff --git a/tgfx/src/core/vectors/web/WebMask.cpp b/tgfx/src/core/vectors/web/WebMask.cpp index b62d389abf..b48ed606ac 100644 --- a/tgfx/src/core/vectors/web/WebMask.cpp +++ b/tgfx/src/core/vectors/web/WebMask.cpp @@ -43,8 +43,8 @@ std::shared_ptr WebMask::makeTexture(Context* context) const { return nullptr; } auto& glInfo = std::static_pointer_cast(texture)->glSampler(); - auto gl = GLInterface::Get(context); - gl->functions->bindTexture(glInfo.target, glInfo.id); + auto gl = GLFunctions::Get(context); + gl->bindTexture(glInfo.target, glInfo.id); webMask.call("update", val::module_property("GL")); return texture; } diff --git a/tgfx/src/gpu/Program.h b/tgfx/src/gpu/Program.h index 656529d254..2796a79d8e 100644 --- a/tgfx/src/gpu/Program.h +++ b/tgfx/src/gpu/Program.h @@ -23,23 +23,35 @@ namespace tgfx { /** - * The base class for GPU program. Overrides the onRelease() method to to free all GPU resources. + * The base class for GPU program. Overrides the onReleaseGPU() method to to free all GPU resources. * No backend API calls should be made during destructuring since there may be no GPU context which * is current on the calling thread. */ class Program { public: + explicit Program(Context* context) : context(context) { + } + virtual ~Program() = default; - protected: /** - * Overridden to free GPU resources in the backend API. + * Retrieves the context associated with this Program. */ - virtual void onRelease(Context* context) = 0; + Context* getContext() const { + return context; + } + + protected: + Context* context = nullptr; private: BytesKey uniqueKey = {}; + /** + * Overridden to free GPU resources in the backend API. + */ + virtual void onReleaseGPU() = 0; + friend class ProgramCache; }; diff --git a/tgfx/src/gpu/ProgramBuilder.cpp b/tgfx/src/gpu/ProgramBuilder.cpp index 20f254047e..c7c0db7a48 100644 --- a/tgfx/src/gpu/ProgramBuilder.cpp +++ b/tgfx/src/gpu/ProgramBuilder.cpp @@ -22,8 +22,9 @@ #include "GLXferProcessor.h" namespace tgfx { -ProgramBuilder::ProgramBuilder(const GeometryProcessor* geometryProcessor, const Pipeline* pipeline) - : geometryProcessor(geometryProcessor), pipeline(pipeline) { +ProgramBuilder::ProgramBuilder(Context* context, const GeometryProcessor* geometryProcessor, + const Pipeline* pipeline) + : context(context), geometryProcessor(geometryProcessor), pipeline(pipeline) { } bool ProgramBuilder::emitAndInstallProcessors() { @@ -57,9 +58,9 @@ void ProgramBuilder::emitAndInstallGeoProc(std::string* outputColor, std::string glGeometryProcessor = geometryProcessor->createGLInstance(); GLGeometryProcessor::FPCoordTransformHandler transformHandler(*pipeline, &transformedCoordVars); - GLGeometryProcessor::EmitArgs args(vertexShaderBuilder(), fragmentShaderBuilder(), - varyingHandler(), uniformHandler(), caps(), geometryProcessor, - *outputColor, *outputCoverage, &transformHandler); + GLGeometryProcessor::EmitArgs args( + vertexShaderBuilder(), fragmentShaderBuilder(), varyingHandler(), uniformHandler(), + getContext()->caps(), geometryProcessor, *outputColor, *outputCoverage, &transformHandler); glGeometryProcessor->emitCode(args); fragmentShaderBuilder()->codeAppend("}"); diff --git a/tgfx/src/gpu/ProgramBuilder.h b/tgfx/src/gpu/ProgramBuilder.h index f83604f012..bba3180a49 100644 --- a/tgfx/src/gpu/ProgramBuilder.h +++ b/tgfx/src/gpu/ProgramBuilder.h @@ -30,7 +30,9 @@ class ProgramBuilder { public: virtual ~ProgramBuilder() = default; - virtual const Caps* caps() const = 0; + Context* getContext() const { + return context; + } virtual std::string versionDeclString() = 0; @@ -66,7 +68,10 @@ class ProgramBuilder { virtual FragmentShaderBuilder* fragmentShaderBuilder() = 0; protected: - ProgramBuilder(const GeometryProcessor* geometryProcessor, const Pipeline* pipeline); + Context* context = nullptr; + + ProgramBuilder(Context* context, const GeometryProcessor* geometryProcessor, + const Pipeline* pipeline); bool emitAndInstallProcessors(); diff --git a/tgfx/src/gpu/ProgramCache.cpp b/tgfx/src/gpu/ProgramCache.cpp index 2bc2845d4b..715130076e 100644 --- a/tgfx/src/gpu/ProgramCache.cpp +++ b/tgfx/src/gpu/ProgramCache.cpp @@ -56,7 +56,7 @@ void ProgramCache::removeOldestProgram(bool releaseGPU) { programLRU.pop_back(); programMap.erase(program->uniqueKey); if (releaseGPU) { - program->onRelease(context); + program->onReleaseGPU(); } delete program; } diff --git a/tgfx/src/gpu/ResourceCache.cpp b/tgfx/src/gpu/ResourceCache.cpp index 3416eae87d..fa664f9e97 100644 --- a/tgfx/src/gpu/ResourceCache.cpp +++ b/tgfx/src/gpu/ResourceCache.cpp @@ -79,7 +79,7 @@ void ResourceCache::releaseAll(bool releaseGPU) { PurgeGuard guard(this); for (auto& resource : nonpurgeableResources) { if (releaseGPU) { - resource->onRelease(context); + resource->onReleaseGPU(); } // 标记 Resource 已经被释放,等外部指针计数为 0 时可以直接 delete。 resource->context = nullptr; @@ -88,7 +88,7 @@ void ResourceCache::releaseAll(bool releaseGPU) { for (auto& item : recycledResources) { for (auto& resource : item.second) { if (releaseGPU) { - resource->onRelease(context); + resource->onReleaseGPU(); } delete resource; } @@ -106,7 +106,7 @@ void ResourceCache::purgeNotUsedIn(int64_t usNotUsed) { if (currentTime - resource->lastUsedTime < usNotUsed) { needToRecycle.push_back(resource); } else { - resource->onRelease(context); + resource->onReleaseGPU(); delete resource; } } @@ -182,7 +182,7 @@ void ResourceCache::removeResource(Resource* resource) { recycledResources[resource->recycleKey].push_back(resource); } else { purgingResource = true; - resource->onRelease(context); + resource->onReleaseGPU(); purgingResource = false; delete resource; } diff --git a/tgfx/src/gpu/opengl/GLBuffer.cpp b/tgfx/src/gpu/opengl/GLBuffer.cpp index 506a50f5f5..232c96e887 100644 --- a/tgfx/src/gpu/opengl/GLBuffer.cpp +++ b/tgfx/src/gpu/opengl/GLBuffer.cpp @@ -39,15 +39,14 @@ std::shared_ptr GLBuffer::Make(Context* context, const uint16_t* buffe if (glBuffer != nullptr) { return glBuffer; } - auto gl = GLInterface::Get(context); + auto gl = GLFunctions::Get(context); glBuffer = Resource::Wrap(context, new GLBuffer(buffer, length)); - gl->functions->genBuffers(1, &glBuffer->_bufferID); + gl->genBuffers(1, &glBuffer->_bufferID); if (buffer) { - gl->functions->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, glBuffer->_bufferID); - gl->functions->bufferData(GL_ELEMENT_ARRAY_BUFFER, - static_cast(sizeof(uint16_t) * length), buffer, - GL_STATIC_DRAW); - gl->functions->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + gl->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, glBuffer->_bufferID); + gl->bufferData(GL_ELEMENT_ARRAY_BUFFER, static_cast(sizeof(uint16_t) * length), + buffer, GL_STATIC_DRAW); + gl->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } return glBuffer; } @@ -56,10 +55,10 @@ void GLBuffer::computeRecycleKey(BytesKey* bytesKey) const { ComputeRecycleKey(bytesKey, uniqueKey, _length); } -void GLBuffer::onRelease(Context* context) { +void GLBuffer::onReleaseGPU() { if (_bufferID > 0) { - auto gl = GLInterface::Get(context); - gl->functions->deleteBuffers(1, &_bufferID); + auto gl = GLFunctions::Get(context); + gl->deleteBuffers(1, &_bufferID); _bufferID = 0; } } diff --git a/tgfx/src/gpu/opengl/GLBuffer.h b/tgfx/src/gpu/opengl/GLBuffer.h index 14268c82eb..aafb9bc146 100644 --- a/tgfx/src/gpu/opengl/GLBuffer.h +++ b/tgfx/src/gpu/opengl/GLBuffer.h @@ -40,7 +40,7 @@ class GLBuffer : public Resource { GLBuffer(const void* uniqueKey, size_t length) : uniqueKey(uniqueKey), _length(length) { } - void onRelease(Context* context) override; + void onReleaseGPU() override; const void* uniqueKey = nullptr; size_t _length = 0; diff --git a/tgfx/src/gpu/opengl/GLCanvas.cpp b/tgfx/src/gpu/opengl/GLCanvas.cpp index 26fb695f8a..9c5f348429 100644 --- a/tgfx/src/gpu/opengl/GLCanvas.cpp +++ b/tgfx/src/gpu/opengl/GLCanvas.cpp @@ -35,7 +35,7 @@ GLCanvas::GLCanvas(Surface* surface) : Canvas(surface) { void GLCanvas::clear() { auto renderTarget = std::static_pointer_cast(surface->getRenderTarget()); - renderTarget->clear(GLInterface::Get(getContext())); + renderTarget->clear(); } void GLCanvas::drawTexture(const Texture* texture, const Texture* mask, bool inverted) { diff --git a/tgfx/src/gpu/opengl/GLCaps.cpp b/tgfx/src/gpu/opengl/GLCaps.cpp index d64ed36369..c9289892f3 100644 --- a/tgfx/src/gpu/opengl/GLCaps.cpp +++ b/tgfx/src/gpu/opengl/GLCaps.cpp @@ -159,6 +159,10 @@ static bool IsMediumFloatFp32(const GLInfo& ctxInfo) { return true; } +const GLCaps* GLCaps::Get(Context* context) { + return context ? static_cast(context->caps()) : nullptr; +} + GLCaps::GLCaps(const GLInfo& info) { standard = info.standard; version = info.version; diff --git a/tgfx/src/gpu/opengl/GLCaps.h b/tgfx/src/gpu/opengl/GLCaps.h index aeb156f9e1..0eb4870288 100644 --- a/tgfx/src/gpu/opengl/GLCaps.h +++ b/tgfx/src/gpu/opengl/GLCaps.h @@ -128,6 +128,8 @@ class GLCaps : public Caps { bool textureSwizzleSupport = false; bool semaphoreSupport = false; + static const GLCaps* Get(Context* context); + explicit GLCaps(const GLInfo& info); const TextureFormat& getTextureFormat(PixelFormat pixelFormat) const; diff --git a/tgfx/src/gpu/opengl/GLContext.cpp b/tgfx/src/gpu/opengl/GLContext.cpp index 57b5aa67bf..7c6d8f16b3 100644 --- a/tgfx/src/gpu/opengl/GLContext.cpp +++ b/tgfx/src/gpu/opengl/GLContext.cpp @@ -18,9 +18,68 @@ #include "gpu/opengl/GLContext.h" #include "gpu/opengl/GLDevice.h" +#include "gpu/opengl/GLUtil.h" namespace tgfx { GLContext::GLContext(Device* device, const GLInterface* glInterface) : Context(device), interface(glInterface) { } + +void GLContext::resetState() { +} + +static std::array GetGLSwizzleValues(const Swizzle& swizzle) { + unsigned glValues[4]; + for (int i = 0; i < 4; ++i) { + switch (swizzle[i]) { + case 'r': + glValues[i] = GL_RED; + break; + case 'g': + glValues[i] = GL_GREEN; + break; + case 'b': + glValues[i] = GL_BLUE; + break; + case 'a': + glValues[i] = GL_ALPHA; + break; + case '1': + glValues[i] = GL_ONE; + break; + default: + LOGE("Unsupported component"); + } + } + return {glValues[0], glValues[1], glValues[2], glValues[3]}; +} + +void GLContext::bindTexture(int unitIndex, const TextureSampler* sampler) { + if (sampler == nullptr) { + return; + } + auto glSampler = static_cast(sampler); + auto gl = interface->functions.get(); + auto caps = interface->caps.get(); + gl->activeTexture(GL_TEXTURE0 + unitIndex); + gl->bindTexture(glSampler->target, glSampler->id); + gl->texParameteri(glSampler->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl->texParameteri(glSampler->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl->texParameteri(glSampler->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl->texParameteri(glSampler->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (caps->textureSwizzleSupport) { + const auto& swizzle = caps->getSwizzle(sampler->format); + auto glValues = GetGLSwizzleValues(swizzle); + if (caps->standard == GLStandard::GL) { + gl->texParameteriv(glSampler->target, GL_TEXTURE_SWIZZLE_RGBA, + reinterpret_cast(&glValues[0])); + } else if (caps->standard == GLStandard::GLES) { + // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. + gl->texParameteri(glSampler->target, GL_TEXTURE_SWIZZLE_R, static_cast(glValues[0])); + gl->texParameteri(glSampler->target, GL_TEXTURE_SWIZZLE_G, static_cast(glValues[1])); + gl->texParameteri(glSampler->target, GL_TEXTURE_SWIZZLE_B, static_cast(glValues[2])); + gl->texParameteri(glSampler->target, GL_TEXTURE_SWIZZLE_A, static_cast(glValues[3])); + } + } +} } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/GLContext.h b/tgfx/src/gpu/opengl/GLContext.h index 5830dff84b..f8994849a5 100644 --- a/tgfx/src/gpu/opengl/GLContext.h +++ b/tgfx/src/gpu/opengl/GLContext.h @@ -20,12 +20,17 @@ #include "GLInterface.h" #include "gpu/Context.h" +#include "gpu/opengl/GLSampler.h" namespace tgfx { class GLCaps; class GLContext : public Context { public: + static GLContext* Unwrap(Context* context) { + return static_cast(context); + } + GLContext(Device* device, const GLInterface* glInterface); Backend backend() const override { @@ -40,6 +45,10 @@ class GLContext : public Context { return interface->caps.get(); } + void resetState() override; + + void bindTexture(int unitIndex, const TextureSampler* sampler); + private: const GLInterface* interface = nullptr; diff --git a/tgfx/src/gpu/opengl/GLDrawer.cpp b/tgfx/src/gpu/opengl/GLDrawer.cpp index 2a203f6aa5..0328e447fa 100644 --- a/tgfx/src/gpu/opengl/GLDrawer.cpp +++ b/tgfx/src/gpu/opengl/GLDrawer.cpp @@ -76,31 +76,33 @@ std::shared_ptr GLDrawer::Make(Context* context) { } bool GLDrawer::init(Context* context) { - auto gl = GLInterface::Get(context); - CheckGLError(gl); - if (gl->caps->vertexArrayObjectSupport) { + CheckGLError(context); + auto gl = GLFunctions::Get(context); + auto caps = GLCaps::Get(context); + if (caps->vertexArrayObjectSupport) { // Using VAO is required in the core profile. - gl->functions->genVertexArrays(1, &vertexArray); + gl->genVertexArrays(1, &vertexArray); } - gl->functions->genBuffers(1, &vertexBuffer); - return CheckGLError(gl); + gl->genBuffers(1, &vertexBuffer); + return CheckGLError(context); } -void GLDrawer::onRelease(Context* context) { - auto gl = GLInterface::Get(context); +void GLDrawer::onReleaseGPU() { + auto gl = GLFunctions::Get(context); if (vertexArray > 0) { - gl->functions->deleteVertexArrays(1, &vertexArray); + gl->deleteVertexArrays(1, &vertexArray); vertexArray = 0; } if (vertexBuffer > 0) { - gl->functions->deleteBuffers(1, &vertexBuffer); + gl->deleteBuffers(1, &vertexBuffer); vertexBuffer = 0; } } static std::shared_ptr CreateDstTexture(const DrawArgs& args, Point* dstOffset) { - auto gl = GLInterface::Get(args.context); - if (gl->caps->textureBarrierSupport && args.renderTargetTexture) { + auto gl = GLFunctions::Get(args.context); + auto caps = GLCaps::Get(args.context); + if (caps->textureBarrierSupport && args.renderTargetTexture) { *dstOffset = {0, 0}; return args.renderTargetTexture; } @@ -121,15 +123,15 @@ static std::shared_ptr CreateDstTexture(const DrawArgs& args, Point* ds return nullptr; } auto renderTarget = static_cast(args.renderTarget); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, renderTarget->glFrameBuffer().id); + gl->bindFramebuffer(GL_FRAMEBUFFER, renderTarget->glFrameBuffer().id); auto glSampler = std::static_pointer_cast(dstTexture)->glSampler(); - gl->functions->bindTexture(glSampler.target, glSampler.id); + gl->bindTexture(glSampler.target, glSampler.id); // format != BGRA && !srcHasMSAARenderBuffer && !dstHasMSAARenderBuffer && dstIsTextureable && // dstOrigin == srcOrigin && canConfigBeFBOColorAttachment(srcConfig) && (!srcIsTextureable || // srcIsGLTexture2D) - gl->functions->copyTexSubImage2D(glSampler.target, 0, 0, 0, static_cast(dstRect.x()), - static_cast(dstRect.y()), static_cast(dstRect.width()), - static_cast(dstRect.height())); + gl->copyTexSubImage2D(glSampler.target, 0, 0, 0, static_cast(dstRect.x()), + static_cast(dstRect.y()), static_cast(dstRect.width()), + static_cast(dstRect.height())); return dstTexture; } @@ -140,26 +142,29 @@ static PixelFormat GetOutputPixelFormat(const DrawArgs& args) { return PixelFormat::RGBA_8888; } -static void UpdateScissor(const GLInterface* gl, const DrawArgs& args) { +static void UpdateScissor(Context* context, const DrawArgs& args) { + auto gl = GLFunctions::Get(context); if (args.scissorRect.isEmpty()) { - gl->functions->disable(GL_SCISSOR_TEST); + gl->disable(GL_SCISSOR_TEST); } else { - gl->functions->enable(GL_SCISSOR_TEST); - gl->functions->scissor( - static_cast(args.scissorRect.x()), static_cast(args.scissorRect.y()), - static_cast(args.scissorRect.width()), static_cast(args.scissorRect.height())); + gl->enable(GL_SCISSOR_TEST); + gl->scissor(static_cast(args.scissorRect.x()), static_cast(args.scissorRect.y()), + static_cast(args.scissorRect.width()), + static_cast(args.scissorRect.height())); } } -static void UpdateBlend(const GLInterface* gl, bool blendAsCoeff, unsigned first, unsigned second) { +static void UpdateBlend(Context* context, bool blendAsCoeff, unsigned first, unsigned second) { + auto gl = GLFunctions::Get(context); if (blendAsCoeff) { - gl->functions->enable(GL_BLEND); - gl->functions->blendFunc(first, second); - gl->functions->blendEquation(GL_FUNC_ADD); + gl->enable(GL_BLEND); + gl->blendFunc(first, second); + gl->blendEquation(GL_FUNC_ADD); } else { - gl->functions->disable(GL_BLEND); - if (gl->caps->frameBufferFetchSupport && gl->caps->frameBufferFetchRequiresEnablePerSample) { - gl->functions->enable(GL_FETCH_PER_SAMPLE_ARM); + gl->disable(GL_BLEND); + auto caps = GLCaps::Get(context); + if (caps->frameBufferFetchSupport && caps->frameBufferFetchRequiresEnablePerSample) { + gl->enable(GL_FETCH_PER_SAMPLE_ARM); } } } @@ -174,7 +179,8 @@ void GLDrawer::draw(DrawArgs args, std::unique_ptr op) const { std::move(args.colors.begin(), args.colors.end(), fragmentProcessors.begin()); std::move(args.masks.begin(), args.masks.end(), fragmentProcessors.begin() + static_cast(numColorProcessors)); - auto gl = GLInterface::Get(args.context); + auto gl = GLFunctions::Get(args.context); + auto caps = GLCaps::Get(args.context); std::unique_ptr xferProcessor; std::shared_ptr dstTexture; Point dstTextureOffset = Point::Zero(); @@ -183,12 +189,12 @@ void GLDrawer::draw(DrawArgs args, std::unique_ptr op) const { auto blendAsCoeff = BlendAsCoeff(args.blendMode, &first, &second); if (!blendAsCoeff) { xferProcessor = PorterDuffXferProcessor::Make(args.blendMode); - if (!gl->caps->frameBufferFetchSupport) { + if (!caps->frameBufferFetchSupport) { dstTexture = CreateDstTexture(args, &dstTextureOffset); } } auto config = GetOutputPixelFormat(args); - const auto& swizzle = gl->caps->getOutputSwizzle(config); + const auto& swizzle = caps->getOutputSwizzle(config); Pipeline pipeline(std::move(fragmentProcessors), numColorProcessors, std::move(xferProcessor), dstTexture, dstTextureOffset, &swizzle); auto geometryProcessor = op->getGeometryProcessor(args); @@ -197,45 +203,43 @@ void GLDrawer::draw(DrawArgs args, std::unique_ptr op) const { if (program == nullptr) { return; } - CheckGLError(gl); + CheckGLError(args.context); auto renderTarget = static_cast(args.renderTarget); - gl->functions->useProgram(program->programID()); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, renderTarget->glFrameBuffer().id); - gl->functions->viewport(0, 0, renderTarget->width(), renderTarget->height()); - UpdateScissor(gl, args); - UpdateBlend(gl, blendAsCoeff, first, second); + gl->useProgram(program->programID()); + gl->bindFramebuffer(GL_FRAMEBUFFER, renderTarget->glFrameBuffer().id); + gl->viewport(0, 0, renderTarget->width(), renderTarget->height()); + UpdateScissor(args.context, args); + UpdateBlend(args.context, blendAsCoeff, first, second); if (pipeline.needsBarrierTexture(args.renderTargetTexture.get())) { - gl->functions->textureBarrier(); + gl->textureBarrier(); } - program->updateUniformsAndTextureBindings(gl, *geometryProcessor, pipeline); + program->updateUniformsAndTextureBindings(*geometryProcessor, pipeline); if (vertexArray > 0) { - gl->functions->bindVertexArray(vertexArray); + gl->bindVertexArray(vertexArray); } - gl->functions->bindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + gl->bindBuffer(GL_ARRAY_BUFFER, vertexBuffer); auto vertices = op->vertices(args); - gl->functions->bufferData(GL_ARRAY_BUFFER, - static_cast(vertices.size()) * sizeof(float), &vertices[0], - GL_STATIC_DRAW); + gl->bufferData(GL_ARRAY_BUFFER, static_cast(vertices.size()) * sizeof(float), + &vertices[0], GL_STATIC_DRAW); for (const auto& attribute : program->vertexAttributes()) { const AttribLayout& layout = GetAttribLayout(attribute.gpuType); - gl->functions->vertexAttribPointer(static_cast(attribute.location), layout.count, - layout.type, layout.normalized, program->vertexStride(), - reinterpret_cast(attribute.offset)); - gl->functions->enableVertexAttribArray(static_cast(attribute.location)); + gl->vertexAttribPointer(static_cast(attribute.location), layout.count, layout.type, + layout.normalized, program->vertexStride(), + reinterpret_cast(attribute.offset)); + gl->enableVertexAttribArray(static_cast(attribute.location)); } - gl->functions->bindBuffer(GL_ARRAY_BUFFER, 0); + gl->bindBuffer(GL_ARRAY_BUFFER, 0); auto indexBuffer = op->getIndexBuffer(args); if (indexBuffer) { - gl->functions->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer->bufferID()); - gl->functions->drawElements(GL_TRIANGLES, static_cast(indexBuffer->length()), - GL_UNSIGNED_SHORT, 0); - gl->functions->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + gl->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer->bufferID()); + gl->drawElements(GL_TRIANGLES, static_cast(indexBuffer->length()), GL_UNSIGNED_SHORT, 0); + gl->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } else { - gl->functions->drawArrays(GL_TRIANGLE_STRIP, 0, 4); + gl->drawArrays(GL_TRIANGLE_STRIP, 0, 4); } if (vertexArray > 0) { - gl->functions->bindVertexArray(0); + gl->bindVertexArray(0); } - CheckGLError(gl); + CheckGLError(args.context); } } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/GLDrawer.h b/tgfx/src/gpu/opengl/GLDrawer.h index 3a36e43e35..2f373dfe24 100644 --- a/tgfx/src/gpu/opengl/GLDrawer.h +++ b/tgfx/src/gpu/opengl/GLDrawer.h @@ -63,7 +63,7 @@ class GLDrawer : public Resource { private: bool init(Context* context); - void onRelease(Context* context) override; + void onReleaseGPU() override; unsigned vertexArray = 0; unsigned vertexBuffer = 0; diff --git a/tgfx/src/gpu/opengl/GLFragmentShaderBuilder.cpp b/tgfx/src/gpu/opengl/GLFragmentShaderBuilder.cpp index 2a5673886b..c8dc2fa2f1 100644 --- a/tgfx/src/gpu/opengl/GLFragmentShaderBuilder.cpp +++ b/tgfx/src/gpu/opengl/GLFragmentShaderBuilder.cpp @@ -29,10 +29,10 @@ GLFragmentShaderBuilder::GLFragmentShaderBuilder(ProgramBuilder* program) } std::string GLFragmentShaderBuilder::dstColor() { - auto gl = static_cast(programBuilder)->gl(); - if (gl->caps->frameBufferFetchSupport) { - addFeature(PrivateFeature::FramebufferFetch, gl->caps->frameBufferFetchExtensionString); - return gl->caps->frameBufferFetchColorName; + auto caps = GLCaps::Get(programBuilder->getContext()); + if (caps->frameBufferFetchSupport) { + addFeature(PrivateFeature::FramebufferFetch, caps->frameBufferFetchExtensionString); + return caps->frameBufferFetchColorName; } return kDstColorName; } diff --git a/tgfx/src/gpu/opengl/GLProgram.cpp b/tgfx/src/gpu/opengl/GLProgram.cpp index c1dc0961dc..3137bdcf9f 100644 --- a/tgfx/src/gpu/opengl/GLProgram.cpp +++ b/tgfx/src/gpu/opengl/GLProgram.cpp @@ -23,12 +23,13 @@ #include "gpu/opengl/GLTexture.h" namespace tgfx { -GLProgram::GLProgram(unsigned programID, const std::vector& uniforms, +GLProgram::GLProgram(Context* context, unsigned programID, const std::vector& uniforms, std::unique_ptr geometryProcessor, std::unique_ptr xferProcessor, std::vector> fragmentProcessors, std::vector attributes, int vertexStride) - : programId(programID), + : Program(context), + programId(programID), glGeometryProcessor(std::move(geometryProcessor)), glXferProcessor(std::move(xferProcessor)), glFragmentProcessors(std::move(fragmentProcessors)), @@ -39,64 +40,59 @@ GLProgram::GLProgram(unsigned programID, const std::vector& uniforms, } } -void GLProgram::setupSamplerUniforms(const GLInterface* gl, - const std::vector& textureSamplers) const { - gl->functions->useProgram(programId); +void GLProgram::setupSamplerUniforms(const std::vector& textureSamplers) const { + auto gl = GLFunctions::Get(context); + gl->useProgram(programId); // Assign texture units to sampler uniforms one time up front. auto count = static_cast(textureSamplers.size()); for (int i = 0; i < count; ++i) { const auto& sampler = textureSamplers[i]; if (kUnusedUniform != sampler.location) { - gl->functions->uniform1i(sampler.location, i); + gl->uniform1i(sampler.location, i); } } } -void GLProgram::onRelease(Context* context) { +void GLProgram::onReleaseGPU() { if (programId) { - auto gl = GLInterface::Get(context); - gl->functions->deleteProgram(programId); + auto gl = GLFunctions::Get(context); + gl->deleteProgram(programId); } } -static void BindGLTexture(const GLInterface* gl, int position, const TextureSampler* sampler) { - auto glSampler = static_cast(sampler); - ActiveGLTexture(gl, GL_TEXTURE0 + position, glSampler->target, glSampler->id, glSampler->format); -} - -void GLProgram::updateUniformsAndTextureBindings(const GLInterface* gl, - const GeometryProcessor& geometryProcessor, +void GLProgram::updateUniformsAndTextureBindings(const GeometryProcessor& geometryProcessor, const Pipeline& pipeline) { // we set the textures, and uniforms for installed processors in a generic way. // We must bind to texture units in the same order in which we set the uniforms in // GLProgramDataManager. That is, we bind textures for processors in this order: // geometryProcessor, fragmentProcessors, XferProcessor. - GLProgramDataManager programDataManager(gl, &uniformLocations); + GLProgramDataManager programDataManager(context, &uniformLocations); FragmentProcessor::CoordTransformIter coordTransformIter(pipeline); glGeometryProcessor->setData(programDataManager, geometryProcessor, &coordTransformIter); int nextTexSamplerIdx = 0; - setFragmentData(gl, programDataManager, pipeline, &nextTexSamplerIdx); + setFragmentData(programDataManager, pipeline, &nextTexSamplerIdx); auto offset = Point::Zero(); const auto* dstTexture = pipeline.getDstTexture(&offset); + auto glContext = GLContext::Unwrap(context); if (dstTexture) { glXferProcessor->setData(programDataManager, *pipeline.getXferProcessor(), dstTexture, offset); - BindGLTexture(gl, nextTexSamplerIdx++, dstTexture->getSampler()); + glContext->bindTexture(nextTexSamplerIdx++, dstTexture->getSampler()); } } -void GLProgram::setFragmentData(const GLInterface* gl, - const GLProgramDataManager& programDataManager, +void GLProgram::setFragmentData(const GLProgramDataManager& programDataManager, const Pipeline& pipeline, int* nextTexSamplerIdx) { FragmentProcessor::Iter iter(pipeline); GLFragmentProcessor::Iter glslIter(glFragmentProcessors); const FragmentProcessor* fp = iter.next(); GLFragmentProcessor* glslFP = glslIter.next(); + auto glContext = GLContext::Unwrap(context); while (fp && glslFP) { glslFP->setData(programDataManager, *fp); for (size_t i = 0; i < fp->numTextureSamplers(); ++i) { - BindGLTexture(gl, (*nextTexSamplerIdx)++, fp->textureSampler(i)); + glContext->bindTexture((*nextTexSamplerIdx)++, fp->textureSampler(i)); } fp = iter.next(); glslFP = glslIter.next(); diff --git a/tgfx/src/gpu/opengl/GLProgram.h b/tgfx/src/gpu/opengl/GLProgram.h index d9bafec1f8..45916af9c6 100644 --- a/tgfx/src/gpu/opengl/GLProgram.h +++ b/tgfx/src/gpu/opengl/GLProgram.h @@ -18,6 +18,7 @@ #pragma once +#include "GLContext.h" #include "GLProgramDataManager.h" #include "GLUniformHandler.h" #include "gpu/GLFragmentProcessor.h" @@ -34,16 +35,13 @@ class GLProgram : public Program { int location = 0; }; - GLProgram(unsigned programID, const std::vector& uniforms, + GLProgram(Context* context, unsigned programID, const std::vector& uniforms, std::unique_ptr geometryProcessor, std::unique_ptr xferProcessor, std::vector> fragmentProcessors, std::vector attributes, int vertexStride); - void setupSamplerUniforms(const GLInterface* gl, - const std::vector& textureSamplers) const; - - void onRelease(Context* context) override; + void setupSamplerUniforms(const std::vector& textureSamplers) const; /** * Gets the GL program ID for this program. @@ -58,8 +56,7 @@ class GLProgram : public Program { * * It is the caller's responsibility to ensure the program is bound before calling. */ - void updateUniformsAndTextureBindings(const GLInterface* gl, - const GeometryProcessor& geometryProcessor, + void updateUniformsAndTextureBindings(const GeometryProcessor& geometryProcessor, const Pipeline& pipeline); int vertexStride() const { @@ -72,8 +69,10 @@ class GLProgram : public Program { private: // A helper to loop over effects, set the transforms (via subclass) and bind textures - void setFragmentData(const GLInterface* gl, const GLProgramDataManager& programDataManager, - const Pipeline& pipeline, int* nextTexSamplerIdx); + void setFragmentData(const GLProgramDataManager& programDataManager, const Pipeline& pipeline, + int* nextTexSamplerIdx); + + void onReleaseGPU() override; unsigned programId = 0; diff --git a/tgfx/src/gpu/opengl/GLProgramBuilder.cpp b/tgfx/src/gpu/opengl/GLProgramBuilder.cpp index dc05e8d5b2..b7d0213247 100644 --- a/tgfx/src/gpu/opengl/GLProgramBuilder.cpp +++ b/tgfx/src/gpu/opengl/GLProgramBuilder.cpp @@ -59,19 +59,17 @@ static std::string SLTypeString(ShaderVar::Type t) { } std::unique_ptr GLProgramBuilder::CreateProgram( - const GLInterface* gl, const GeometryProcessor* geometryProcessor, const Pipeline* pipeline) { - GLProgramBuilder builder(gl, geometryProcessor, pipeline); + Context* context, const GeometryProcessor* geometryProcessor, const Pipeline* pipeline) { + GLProgramBuilder builder(context, geometryProcessor, pipeline); if (!builder.emitAndInstallProcessors()) { return nullptr; } return builder.finalize(); } -GLProgramBuilder::GLProgramBuilder(const GLInterface* gl, - const GeometryProcessor* geometryProcessor, +GLProgramBuilder::GLProgramBuilder(Context* context, const GeometryProcessor* geometryProcessor, const Pipeline* pipeline) - : ProgramBuilder(geometryProcessor, pipeline), - _gl(gl), + : ProgramBuilder(context, geometryProcessor, pipeline), _varyingHandler(this), _uniformHandler(this), _vertexBuilder(this), @@ -112,7 +110,7 @@ std::unique_ptr GLProgramBuilder::finalize() { auto vertex = vertexShaderBuilder()->shaderString(); auto fragment = fragmentShaderBuilder()->shaderString(); - auto programID = CreateGLProgram(_gl, vertex, fragment); + auto programID = CreateGLProgram(context, vertex, fragment); if (programID == 0) { return nullptr; } @@ -123,13 +121,14 @@ std::unique_ptr GLProgramBuilder::finalize() { } void GLProgramBuilder::computeCountsAndStrides(unsigned int programID) { + auto gl = GLFunctions::Get(context); vertexStride = 0; for (const auto* attr : geometryProcessor->vertexAttributes()) { GLProgram::Attribute attribute; attribute.gpuType = attr->gpuType(); attribute.offset = vertexStride; vertexStride += static_cast(attr->sizeAlign4()); - attribute.location = _gl->functions->getAttribLocation(programID, attr->name().c_str()); + attribute.location = gl->getAttribLocation(programID, attr->name().c_str()); if (attribute.location >= 0) { attributes.push_back(attribute); } @@ -141,7 +140,8 @@ void GLProgramBuilder::resolveProgramResourceLocations(unsigned programID) { } bool GLProgramBuilder::checkSamplerCounts() { - if (numFragmentSamplers > _gl->caps->maxFragmentSamplers) { + auto caps = GLCaps::Get(context); + if (numFragmentSamplers > caps->maxFragmentSamplers) { LOGE("Program would use too many fragment samplers."); return false; } @@ -149,14 +149,15 @@ bool GLProgramBuilder::checkSamplerCounts() { } std::unique_ptr GLProgramBuilder::createProgram(unsigned programID) { - auto program = new GLProgram(programID, _uniformHandler.uniforms, std::move(glGeometryProcessor), - std::move(xferProcessor), std::move(fragmentProcessors), attributes, - vertexStride); - program->setupSamplerUniforms(_gl, _uniformHandler.samplers); + auto program = new GLProgram(context, programID, _uniformHandler.uniforms, + std::move(glGeometryProcessor), std::move(xferProcessor), + std::move(fragmentProcessors), attributes, vertexStride); + program->setupSamplerUniforms(_uniformHandler.samplers); return std::unique_ptr(program); } bool GLProgramBuilder::isDesktopGL() const { - return gl()->caps->standard == GLStandard::GL; + auto caps = GLCaps::Get(context); + return caps->standard == GLStandard::GL; } } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/GLProgramBuilder.h b/tgfx/src/gpu/opengl/GLProgramBuilder.h index 47e80dbce8..425c4402bd 100644 --- a/tgfx/src/gpu/opengl/GLProgramBuilder.h +++ b/tgfx/src/gpu/opengl/GLProgramBuilder.h @@ -18,8 +18,8 @@ #pragma once +#include "GLContext.h" #include "GLFragmentShaderBuilder.h" -#include "GLInterface.h" #include "GLProgram.h" #include "GLUniformHandler.h" #include "GLVertexShaderBuilder.h" @@ -35,17 +35,9 @@ class GLProgramBuilder : public ProgramBuilder { * After successful generation, the builder result objects are available * to be used. */ - static std::unique_ptr CreateProgram(const GLInterface* gl, + static std::unique_ptr CreateProgram(Context* context, const GeometryProcessor* geometryProcessor, const Pipeline* pipeline); - const GLInterface* gl() const { - return _gl; - } - - const Caps* caps() const override { - return _gl->caps.get(); - } - std::string versionDeclString() override; std::string textureFuncName() const override; @@ -55,7 +47,7 @@ class GLProgramBuilder : public ProgramBuilder { bool isDesktopGL() const; private: - GLProgramBuilder(const GLInterface* gl, const GeometryProcessor* geometryProcessor, + GLProgramBuilder(Context* context, const GeometryProcessor* geometryProcessor, const Pipeline* pipeline); void computeCountsAndStrides(unsigned programID); @@ -88,7 +80,6 @@ class GLProgramBuilder : public ProgramBuilder { bool checkSamplerCounts() override; - const GLInterface* _gl; VaryingHandler _varyingHandler; GLUniformHandler _uniformHandler; GLVertexShaderBuilder _vertexBuilder; diff --git a/tgfx/src/gpu/opengl/GLProgramCreator.cpp b/tgfx/src/gpu/opengl/GLProgramCreator.cpp index 5513929e0b..c4dbda25b9 100644 --- a/tgfx/src/gpu/opengl/GLProgramCreator.cpp +++ b/tgfx/src/gpu/opengl/GLProgramCreator.cpp @@ -32,7 +32,6 @@ void GLProgramCreator::computeUniqueKey(Context* context, BytesKey* bytesKey) co } std::unique_ptr GLProgramCreator::createProgram(Context* context) const { - auto gl = GLInterface::Get(context); - return GLProgramBuilder::CreateProgram(gl, geometryProcessor, pipeline); + return GLProgramBuilder::CreateProgram(context, geometryProcessor, pipeline); } } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/GLProgramDataManager.cpp b/tgfx/src/gpu/opengl/GLProgramDataManager.cpp index b037caf237..0856b4912c 100644 --- a/tgfx/src/gpu/opengl/GLProgramDataManager.cpp +++ b/tgfx/src/gpu/opengl/GLProgramDataManager.cpp @@ -17,41 +17,39 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "GLProgramDataManager.h" -#include "GLContext.h" -#include "GLInterface.h" #include "GLUniformHandler.h" #include "GLUtil.h" namespace tgfx { -GLProgramDataManager::GLProgramDataManager(const GLInterface* gl, const std::vector* uniforms) - : gl(gl), uniforms(uniforms) { +GLProgramDataManager::GLProgramDataManager(Context* context, const std::vector* uniforms) + : gl(GLFunctions::Get(context)), uniforms(uniforms) { } void GLProgramDataManager::set1f(UniformHandle handle, float v0) const { auto location = uniforms->at(handle.toIndex()); if (kUnusedUniform != location) { - gl->functions->uniform1f(location, v0); + gl->uniform1f(location, v0); } } void GLProgramDataManager::set2f(UniformHandle handle, float v0, float v1) const { auto location = uniforms->at(handle.toIndex()); if (kUnusedUniform != location) { - gl->functions->uniform2f(location, v0, v1); + gl->uniform2f(location, v0, v1); } } void GLProgramDataManager::set4fv(UniformHandle handle, int arrayCount, const float* v) const { auto location = uniforms->at(handle.toIndex()); if (kUnusedUniform != location) { - gl->functions->uniform4fv(location, arrayCount, v); + gl->uniform4fv(location, arrayCount, v); } } void GLProgramDataManager::setMatrix3f(UniformHandle handle, const float matrix[]) const { auto location = uniforms->at(handle.toIndex()); if (kUnusedUniform != location) { - gl->functions->uniformMatrix3fv(location, 1, GL_FALSE, matrix); + gl->uniformMatrix3fv(location, 1, GL_FALSE, matrix); } } diff --git a/tgfx/src/gpu/opengl/GLProgramDataManager.h b/tgfx/src/gpu/opengl/GLProgramDataManager.h index d66599f82e..69d8755a46 100644 --- a/tgfx/src/gpu/opengl/GLProgramDataManager.h +++ b/tgfx/src/gpu/opengl/GLProgramDataManager.h @@ -18,13 +18,13 @@ #pragma once -#include "GLInterface.h" +#include "GLContext.h" #include "gpu/ProgramDataManager.h" namespace tgfx { class GLProgramDataManager : public ProgramDataManager { public: - GLProgramDataManager(const GLInterface* gl, const std::vector* uniforms); + GLProgramDataManager(Context* context, const std::vector* uniforms); void set1f(UniformHandle handle, float v0) const override; @@ -37,7 +37,7 @@ class GLProgramDataManager : public ProgramDataManager { void setMatrix(UniformHandle u, const Matrix& matrix) const override; private: - const GLInterface* gl; + const GLFunctions* gl; const std::vector* uniforms; }; } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/GLRenderTarget.cpp b/tgfx/src/gpu/opengl/GLRenderTarget.cpp index aabc05e1b5..50b9e791e1 100644 --- a/tgfx/src/gpu/opengl/GLRenderTarget.cpp +++ b/tgfx/src/gpu/opengl/GLRenderTarget.cpp @@ -47,122 +47,126 @@ std::shared_ptr GLRenderTarget::MakeAdopted(Context* context, return Resource::Wrap(context, target); } -static bool RenderbufferStorageMSAA(const GLInterface* gl, int sampleCount, PixelFormat pixelFormat, +static bool RenderbufferStorageMSAA(Context* context, int sampleCount, PixelFormat pixelFormat, int width, int height) { - CheckGLError(gl); - auto format = gl->caps->getTextureFormat(pixelFormat).sizedFormat; - switch (gl->caps->msFBOType) { + CheckGLError(context); + auto gl = GLFunctions::Get(context); + auto caps = GLCaps::Get(context); + auto format = caps->getTextureFormat(pixelFormat).sizedFormat; + switch (caps->msFBOType) { case MSFBOType::Standard: - gl->functions->renderbufferStorageMultisample(GL_RENDERBUFFER, sampleCount, format, width, - height); + gl->renderbufferStorageMultisample(GL_RENDERBUFFER, sampleCount, format, width, height); break; case MSFBOType::ES_Apple: - gl->functions->renderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, sampleCount, format, - width, height); + gl->renderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, sampleCount, format, width, height); break; case MSFBOType::ES_EXT_MsToTexture: case MSFBOType::ES_IMG_MsToTexture: - gl->functions->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, sampleCount, format, width, - height); + gl->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, sampleCount, format, width, height); break; case MSFBOType::None: LOGE("Shouldn't be here if we don't support multisampled renderbuffers."); break; } - return CheckGLError(gl); + return CheckGLError(context); } -static void FrameBufferTexture2D(const GLInterface* gl, unsigned textureTarget, unsigned textureID, +static void FrameBufferTexture2D(Context* context, unsigned textureTarget, unsigned textureID, int sampleCount) { + auto gl = GLFunctions::Get(context); + auto caps = GLCaps::Get(context); // 解绑的时候framebufferTexture2DMultisample在华为手机上会出现crash,统一走framebufferTexture2D解绑 - if (textureID != 0 && sampleCount > 1 && gl->caps->usesImplicitMSAAResolve()) { - gl->functions->framebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - textureTarget, textureID, 0, sampleCount); + if (textureID != 0 && sampleCount > 1 && caps->usesImplicitMSAAResolve()) { + gl->framebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureTarget, + textureID, 0, sampleCount); } else { - gl->functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureTarget, - textureID, 0); + gl->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureTarget, textureID, 0); } } static void ReleaseResource(Context* context, GLFrameBuffer* textureFBInfo, GLFrameBuffer* renderTargetFBInfo = nullptr, unsigned* msRenderBufferID = nullptr) { - auto gl = GLInterface::Get(context); + auto gl = GLFunctions::Get(context); if (textureFBInfo && textureFBInfo->id) { - gl->functions->deleteFramebuffers(1, &(textureFBInfo->id)); + gl->deleteFramebuffers(1, &(textureFBInfo->id)); if (renderTargetFBInfo && renderTargetFBInfo->id == textureFBInfo->id) { renderTargetFBInfo->id = 0; } textureFBInfo->id = 0; } if (renderTargetFBInfo && renderTargetFBInfo->id > 0) { - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, renderTargetFBInfo->id); - gl->functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, - 0); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, 0); - gl->functions->deleteFramebuffers(1, &(renderTargetFBInfo->id)); + gl->bindFramebuffer(GL_FRAMEBUFFER, renderTargetFBInfo->id); + gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0); + gl->bindFramebuffer(GL_FRAMEBUFFER, 0); + gl->deleteFramebuffers(1, &(renderTargetFBInfo->id)); renderTargetFBInfo->id = 0; } if (msRenderBufferID && *msRenderBufferID > 0) { - gl->functions->deleteRenderbuffers(1, msRenderBufferID); + gl->deleteRenderbuffers(1, msRenderBufferID); *msRenderBufferID = 0; } } -static bool CreateRenderBuffer(const GLInterface* gl, const GLTexture* texture, - GLFrameBuffer* renderTargetFBInfo, unsigned* msRenderBufferID, - int sampleCount) { - gl->functions->genFramebuffers(1, &(renderTargetFBInfo->id)); +static bool CreateRenderBuffer(const GLTexture* texture, GLFrameBuffer* renderTargetFBInfo, + unsigned* msRenderBufferID, int sampleCount) { + if (texture == nullptr) { + return false; + } + auto gl = GLFunctions::Get(texture->getContext()); + gl->genFramebuffers(1, &(renderTargetFBInfo->id)); if (renderTargetFBInfo->id == 0) { return false; } - gl->functions->genRenderbuffers(1, msRenderBufferID); + gl->genRenderbuffers(1, msRenderBufferID); if (*msRenderBufferID == 0) { return false; } - gl->functions->bindRenderbuffer(GL_RENDERBUFFER, *msRenderBufferID); - if (!RenderbufferStorageMSAA(gl, sampleCount, renderTargetFBInfo->format, texture->width(), - texture->height())) { + gl->bindRenderbuffer(GL_RENDERBUFFER, *msRenderBufferID); + if (!RenderbufferStorageMSAA(texture->getContext(), sampleCount, renderTargetFBInfo->format, + texture->width(), texture->height())) { return false; } - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, renderTargetFBInfo->id); - gl->functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, - *msRenderBufferID); + gl->bindFramebuffer(GL_FRAMEBUFFER, renderTargetFBInfo->id); + gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + *msRenderBufferID); #ifdef TGFX_BUILD_FOR_WEB return true; #else - return gl->functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; + return gl->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; #endif } -std::shared_ptr GLRenderTarget::MakeFrom(Context* context, const GLTexture* texture, +std::shared_ptr GLRenderTarget::MakeFrom(const GLTexture* texture, int sampleCount) { - if (texture == nullptr || context == nullptr) { + if (texture == nullptr) { return nullptr; } - auto gl = GLInterface::Get(context); + auto context = texture->getContext(); + auto gl = GLFunctions::Get(context); + auto caps = GLCaps::Get(context); GLFrameBuffer textureFBInfo = {}; textureFBInfo.format = texture->glSampler().format; - gl->functions->genFramebuffers(1, &textureFBInfo.id); + gl->genFramebuffers(1, &textureFBInfo.id); if (textureFBInfo.id == 0) { return nullptr; } GLFrameBuffer renderTargetFBInfo = {}; renderTargetFBInfo.format = texture->glSampler().format; unsigned msRenderBufferID = 0; - if (sampleCount > 1 && gl->caps->usesMSAARenderBuffers()) { - if (!CreateRenderBuffer(gl, texture, &renderTargetFBInfo, &msRenderBufferID, sampleCount)) { + if (sampleCount > 1 && caps->usesMSAARenderBuffers()) { + if (!CreateRenderBuffer(texture, &renderTargetFBInfo, &msRenderBufferID, sampleCount)) { ReleaseResource(context, &textureFBInfo, &renderTargetFBInfo, &msRenderBufferID); return nullptr; } } else { renderTargetFBInfo = textureFBInfo; } - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, textureFBInfo.id); + gl->bindFramebuffer(GL_FRAMEBUFFER, textureFBInfo.id); auto textureInfo = texture->glSampler(); - FrameBufferTexture2D(gl, textureInfo.target, textureInfo.id, sampleCount); + FrameBufferTexture2D(context, textureInfo.target, textureInfo.id, sampleCount); #ifndef TGFX_BUILD_FOR_WEB - if (gl->functions->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + if (gl->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { ReleaseResource(context, &textureFBInfo, &renderTargetFBInfo, &msRenderBufferID); return nullptr; } @@ -182,24 +186,26 @@ GLRenderTarget::GLRenderTarget(int width, int height, ImageOrigin origin, int sa textureTarget(textureTarget) { } -void GLRenderTarget::clear(const GLInterface* gl) const { +void GLRenderTarget::clear() const { int oldFb = 0; - gl->functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFb); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, renderTargetFBInfo.id); - gl->functions->viewport(0, 0, width(), height()); - gl->functions->scissor(0, 0, width(), height()); - gl->functions->clearColor(0.0f, 0.0f, 0.0f, 0.0f); - gl->functions->clear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, oldFb); + auto gl = GLFunctions::Get(context); + gl->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFb); + gl->bindFramebuffer(GL_FRAMEBUFFER, renderTargetFBInfo.id); + gl->viewport(0, 0, width(), height()); + gl->scissor(0, 0, width(), height()); + gl->clearColor(0.0f, 0.0f, 0.0f, 0.0f); + gl->clear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + gl->bindFramebuffer(GL_FRAMEBUFFER, oldFb); } -static bool CanReadDirectly(const GLInterface* gl, ImageOrigin origin, const ImageInfo& srcInfo, +static bool CanReadDirectly(Context* context, ImageOrigin origin, const ImageInfo& srcInfo, const ImageInfo& dstInfo) { if (origin != ImageOrigin::TopLeft || dstInfo.alphaType() != srcInfo.alphaType() || dstInfo.colorType() != srcInfo.colorType()) { return false; } - if (dstInfo.rowBytes() != dstInfo.minRowBytes() && !gl->caps->packRowLengthSupport) { + auto caps = GLCaps::Get(context); + if (dstInfo.rowBytes() != dstInfo.minRowBytes() && !caps->packRowLengthSupport) { return false; } return true; @@ -226,28 +232,29 @@ static void CopyPixels(const ImageInfo& srcInfo, const void* srcPixels, const Im delete[] tempPixels; } -bool GLRenderTarget::readPixels(Context* context, const ImageInfo& dstInfo, void* dstPixels, - int srcX, int srcY) const { +bool GLRenderTarget::readPixels(const ImageInfo& dstInfo, void* dstPixels, int srcX, + int srcY) const { dstPixels = dstInfo.computeOffset(dstPixels, -srcX, -srcY); auto outInfo = dstInfo.makeIntersect(-srcX, -srcY, width(), height()); if (outInfo.isEmpty()) { return false; } auto pixelFormat = renderTargetFBInfo.format; - auto gl = GLInterface::Get(context); - const auto& format = gl->caps->getTextureFormat(pixelFormat); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, renderTargetFBInfo.id); + auto gl = GLFunctions::Get(context); + auto caps = GLCaps::Get(context); + const auto& format = caps->getTextureFormat(pixelFormat); + gl->bindFramebuffer(GL_FRAMEBUFFER, renderTargetFBInfo.id); auto colorType = pixelFormat == PixelFormat::ALPHA_8 ? ColorType::ALPHA_8 : ColorType::RGBA_8888; auto srcInfo = ImageInfo::Make(outInfo.width(), outInfo.height(), colorType, AlphaType::Premultiplied); void* pixels = nullptr; uint8_t* tempPixels = nullptr; auto restoreGLRowLength = false; - if (CanReadDirectly(gl, origin(), srcInfo, outInfo)) { + if (CanReadDirectly(context, origin(), srcInfo, outInfo)) { pixels = dstPixels; if (outInfo.rowBytes() != outInfo.minRowBytes()) { - gl->functions->pixelStorei(GL_PACK_ROW_LENGTH, - static_cast(outInfo.rowBytes() / outInfo.bytesPerPixel())); + gl->pixelStorei(GL_PACK_ROW_LENGTH, + static_cast(outInfo.rowBytes() / outInfo.bytesPerPixel())); restoreGLRowLength = true; } } else { @@ -255,17 +262,17 @@ bool GLRenderTarget::readPixels(Context* context, const ImageInfo& dstInfo, void pixels = tempPixels; } auto alignment = pixelFormat == PixelFormat::ALPHA_8 ? 1 : 4; - gl->functions->pixelStorei(GL_PACK_ALIGNMENT, alignment); + gl->pixelStorei(GL_PACK_ALIGNMENT, alignment); auto flipY = origin() == ImageOrigin::BottomLeft; auto readX = std::max(0, srcX); auto readY = std::max(0, srcY); if (flipY) { readY = height() - readY - outInfo.height(); } - gl->functions->readPixels(readX, readY, outInfo.width(), outInfo.height(), format.externalFormat, - GL_UNSIGNED_BYTE, pixels); + gl->readPixels(readX, readY, outInfo.width(), outInfo.height(), format.externalFormat, + GL_UNSIGNED_BYTE, pixels); if (restoreGLRowLength) { - gl->functions->pixelStorei(GL_PACK_ROW_LENGTH, 0); + gl->pixelStorei(GL_PACK_ROW_LENGTH, 0); } if (tempPixels != nullptr) { CopyPixels(srcInfo, tempPixels, outInfo, dstPixels, flipY); @@ -274,39 +281,40 @@ bool GLRenderTarget::readPixels(Context* context, const ImageInfo& dstInfo, void return true; } -void GLRenderTarget::resolve(Context* context) const { +void GLRenderTarget::resolve() const { if (sampleCount() <= 1) { return; } - auto gl = GLInterface::Get(context); - if (!gl->caps->usesMSAARenderBuffers()) { + auto gl = GLFunctions::Get(context); + auto caps = GLCaps::Get(context); + if (!caps->usesMSAARenderBuffers()) { return; } - gl->functions->bindFramebuffer(GL_READ_FRAMEBUFFER, renderTargetFBInfo.id); - gl->functions->bindFramebuffer(GL_DRAW_FRAMEBUFFER, textureFBInfo.id); - if (gl->caps->msFBOType == MSFBOType::ES_Apple) { + gl->bindFramebuffer(GL_READ_FRAMEBUFFER, renderTargetFBInfo.id); + gl->bindFramebuffer(GL_DRAW_FRAMEBUFFER, textureFBInfo.id); + if (caps->msFBOType == MSFBOType::ES_Apple) { // Apple's extension uses the scissor as the blit bounds. - gl->functions->enable(GL_SCISSOR_TEST); - gl->functions->scissor(0, 0, width(), height()); - gl->functions->resolveMultisampleFramebuffer(); - gl->functions->disable(GL_SCISSOR_TEST); + gl->enable(GL_SCISSOR_TEST); + gl->scissor(0, 0, width(), height()); + gl->resolveMultisampleFramebuffer(); + gl->disable(GL_SCISSOR_TEST); } else { // BlitFrameBuffer respects the scissor, so disable it. - gl->functions->disable(GL_SCISSOR_TEST); - gl->functions->blitFramebuffer(0, 0, width(), height(), 0, 0, width(), height(), - GL_COLOR_BUFFER_BIT, GL_NEAREST); + gl->disable(GL_SCISSOR_TEST); + gl->blitFramebuffer(0, 0, width(), height(), 0, 0, width(), height(), GL_COLOR_BUFFER_BIT, + GL_NEAREST); } } -void GLRenderTarget::onRelease(Context* context) { +void GLRenderTarget::onReleaseGPU() { if (externalTexture) { return; } if (textureTarget != 0) { - auto gl = GLInterface::Get(context); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, textureFBInfo.id); - FrameBufferTexture2D(gl, textureTarget, 0, sampleCount()); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, 0); + auto gl = GLFunctions::Get(context); + gl->bindFramebuffer(GL_FRAMEBUFFER, textureFBInfo.id); + FrameBufferTexture2D(context, textureTarget, 0, sampleCount()); + gl->bindFramebuffer(GL_FRAMEBUFFER, 0); } ReleaseResource(context, &textureFBInfo, &renderTargetFBInfo, &msRenderBufferID); } diff --git a/tgfx/src/gpu/opengl/GLSampler.cpp b/tgfx/src/gpu/opengl/GLSampler.cpp index beae3122d4..2a4a4fdd70 100644 --- a/tgfx/src/gpu/opengl/GLSampler.cpp +++ b/tgfx/src/gpu/opengl/GLSampler.cpp @@ -21,8 +21,8 @@ namespace tgfx { void GLSampler::computeKey(Context* context, BytesKey* bytesKey) const { - auto gl = GLInterface::Get(context); - bytesKey->write(static_cast(gl->caps->getTextureSwizzle(format).asKey())); + auto caps = GLCaps::Get(context); + bytesKey->write(static_cast(caps->getTextureSwizzle(format).asKey())); bytesKey->write(target); } } // namespace tgfx \ No newline at end of file diff --git a/tgfx/src/gpu/opengl/GLSurface.cpp b/tgfx/src/gpu/opengl/GLSurface.cpp index bf34f37b5c..a0d120d33c 100644 --- a/tgfx/src/gpu/opengl/GLSurface.cpp +++ b/tgfx/src/gpu/opengl/GLSurface.cpp @@ -22,26 +22,24 @@ #include "gpu/opengl/GLSemaphore.h" namespace tgfx { -std::shared_ptr Surface::MakeFrom(Context* context, - std::shared_ptr renderTarget) { - if (renderTarget == nullptr || context == nullptr) { +std::shared_ptr Surface::MakeFrom(std::shared_ptr renderTarget) { + if (renderTarget == nullptr) { return nullptr; } auto glRT = std::static_pointer_cast(renderTarget); - return std::shared_ptr(new GLSurface(context, std::move(glRT))); + return std::shared_ptr(new GLSurface(std::move(glRT))); } -std::shared_ptr Surface::MakeFrom(Context* context, std::shared_ptr texture, - int sampleCount) { +std::shared_ptr Surface::MakeFrom(std::shared_ptr texture, int sampleCount) { if (texture == nullptr || texture->isYUV()) { return nullptr; } auto glTexture = std::static_pointer_cast(texture); - auto renderTarget = GLRenderTarget::MakeFrom(context, glTexture.get(), sampleCount); + auto renderTarget = GLRenderTarget::MakeFrom(glTexture.get(), sampleCount); if (renderTarget == nullptr) { return nullptr; } - auto surface = new GLSurface(context, renderTarget, glTexture); + auto surface = new GLSurface(renderTarget, glTexture); return std::shared_ptr(surface); } @@ -50,7 +48,7 @@ std::shared_ptr Surface::Make(Context* context, int width, int height, auto pixelFormat = alphaOnly ? PixelFormat::ALPHA_8 : PixelFormat::RGBA_8888; std::shared_ptr texture; if (alphaOnly) { - if (GLInterface::Get(context)->caps->textureRedSupport) { + if (GLCaps::Get(context)->textureRedSupport) { texture = std::static_pointer_cast(Texture::MakeAlpha(context, width, height)); } } else { @@ -59,21 +57,23 @@ std::shared_ptr Surface::Make(Context* context, int width, int height, if (texture == nullptr) { return nullptr; } - auto gl = GLInterface::Get(context); - sampleCount = gl->caps->getSampleCount(sampleCount, pixelFormat); - auto renderTarget = GLRenderTarget::MakeFrom(context, texture.get(), sampleCount); + auto caps = GLCaps::Get(context); + sampleCount = caps->getSampleCount(sampleCount, pixelFormat); + auto renderTarget = GLRenderTarget::MakeFrom(texture.get(), sampleCount); if (renderTarget == nullptr) { return nullptr; } - auto surface = new GLSurface(context, renderTarget, texture); + auto surface = new GLSurface(renderTarget, texture); // 对于内部创建的 RenderTarget 默认清屏。 surface->getCanvas()->clear(); return std::shared_ptr(surface); } -GLSurface::GLSurface(Context* context, std::shared_ptr renderTarget, +GLSurface::GLSurface(std::shared_ptr renderTarget, std::shared_ptr texture) - : Surface(context), renderTarget(std::move(renderTarget)), texture(std::move(texture)) { + : Surface(renderTarget->getContext()), + renderTarget(std::move(renderTarget)), + texture(std::move(texture)) { } GLSurface::~GLSurface() { @@ -92,12 +92,13 @@ bool GLSurface::wait(const Semaphore* semaphore) { if (glSync == nullptr) { return false; } - auto gl = GLInterface::Get(getContext()); - if (!gl->caps->semaphoreSupport) { + auto caps = GLCaps::Get(context); + if (!caps->semaphoreSupport) { return false; } - gl->functions->waitSync(glSync, 0, GL_TIMEOUT_IGNORED); - gl->functions->deleteSync(glSync); + auto gl = GLFunctions::Get(context); + gl->waitSync(glSync, 0, GL_TIMEOUT_IGNORED); + gl->deleteSync(glSync); return true; } @@ -108,15 +109,16 @@ bool GLSurface::flush(Semaphore* semaphore) { } return false; } - auto gl = GLInterface::Get(getContext()); - if (!gl->caps->semaphoreSupport) { + auto caps = GLCaps::Get(context); + if (!caps->semaphoreSupport) { return false; } - auto* sync = gl->functions->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + auto gl = GLFunctions::Get(context); + auto* sync = gl->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); if (sync) { static_cast(semaphore)->glSync = sync; // If we inserted semaphores during the flush, we need to call glFlush. - gl->functions->flush(); + gl->flush(); return true; } return false; @@ -126,7 +128,7 @@ std::shared_ptr GLSurface::getTexture() const { if (canvas) { canvas->flush(); } - renderTarget->resolve(getContext()); + renderTarget->resolve(); return texture; } @@ -134,8 +136,7 @@ bool GLSurface::onReadPixels(const ImageInfo& dstInfo, void* dstPixels, int srcX if (canvas) { canvas->flush(); } - auto context = getContext(); - renderTarget->resolve(context); - return renderTarget->readPixels(context, dstInfo, dstPixels, srcX, srcY); + renderTarget->resolve(); + return renderTarget->readPixels(dstInfo, dstPixels, srcX, srcY); } } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/GLSurface.h b/tgfx/src/gpu/opengl/GLSurface.h index ce0453c252..95eca756f9 100644 --- a/tgfx/src/gpu/opengl/GLSurface.h +++ b/tgfx/src/gpu/opengl/GLSurface.h @@ -60,7 +60,7 @@ class GLSurface : public Surface { std::shared_ptr texture = nullptr; GLCanvas* canvas = nullptr; - explicit GLSurface(Context* context, std::shared_ptr renderTarget, + explicit GLSurface(std::shared_ptr renderTarget, std::shared_ptr texture = nullptr); friend class Surface; diff --git a/tgfx/src/gpu/opengl/GLTexture.cpp b/tgfx/src/gpu/opengl/GLTexture.cpp index a569c6a55f..25fd0dcd0c 100644 --- a/tgfx/src/gpu/opengl/GLTexture.cpp +++ b/tgfx/src/gpu/opengl/GLTexture.cpp @@ -29,16 +29,15 @@ class GLBackendTexture : public GLTexture { sampler = std::move(textureSampler); } - protected: - void onRelease(Context* context) override { + private: + bool adopted = false; + + void onReleaseGPU() override { if (adopted) { - auto gl = GLInterface::Get(context); - gl->functions->deleteTextures(1, &sampler.id); + auto gl = GLFunctions::Get(context); + gl->deleteTextures(1, &sampler.id); } } - - private: - bool adopted = false; }; std::shared_ptr GLTexture::MakeFrom(Context* context, const GLSampler& sampler, @@ -78,9 +77,10 @@ class GLAlphaTexture : public GLTexture { ComputeRecycleKey(recycleKey, width(), height()); } - void onRelease(Context* context) override { - auto gl = GLInterface::Get(context); - gl->functions->deleteTextures(1, &sampler.id); + private: + void onReleaseGPU() override { + auto gl = GLFunctions::Get(context); + gl->deleteTextures(1, &sampler.id); } }; @@ -104,29 +104,29 @@ class GLRGBATexture : public GLTexture { ComputeRecycleKey(recycleKey, width(), height()); } - void onRelease(Context* context) override { - auto gl = GLInterface::Get(context); - gl->functions->deleteTextures(1, &sampler.id); + private: + void onReleaseGPU() override { + auto gl = GLFunctions::Get(context); + gl->deleteTextures(1, &sampler.id); } }; -static bool CheckMaxTextureSize(const GLInterface* gl, int width, int height) { - auto maxTextureSize = gl->caps->maxTextureSize; +static bool CheckMaxTextureSize(const GLCaps* caps, int width, int height) { + auto maxTextureSize = caps->maxTextureSize; return width <= maxTextureSize && height <= maxTextureSize; } std::shared_ptr Texture::Make(Context* context, int width, int height, void* pixels, size_t rowBytes, ImageOrigin origin, bool alphaOnly) { - auto gl = GLInterface::Get(context); // Clear the previously generated GLError, causing the subsequent CheckGLError to return an // incorrect result. - CheckGLError(gl); - - if (!CheckMaxTextureSize(gl, width, height)) { + CheckGLError(context); + auto caps = GLCaps::Get(context); + if (!CheckMaxTextureSize(caps, width, height)) { return nullptr; } PixelFormat pixelFormat = alphaOnly ? PixelFormat::ALPHA_8 : PixelFormat::RGBA_8888; - const auto& format = gl->caps->getTextureFormat(pixelFormat); + const auto& format = caps->getTextureFormat(pixelFormat); BytesKey recycleKey = {}; if (alphaOnly) { GLAlphaTexture::ComputeRecycleKey(&recycleKey, width, height); @@ -143,21 +143,22 @@ std::shared_ptr Texture::Make(Context* context, int width, int height, } else { sampler.target = GL_TEXTURE_2D; sampler.format = pixelFormat; - gl->functions->genTextures(1, &(sampler.id)); + auto gl = GLFunctions::Get(context); + gl->genTextures(1, &(sampler.id)); if (sampler.id == 0) { return nullptr; } - gl->functions->bindTexture(sampler.target, sampler.id); - gl->functions->texParameteri(sampler.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl->functions->texParameteri(sampler.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gl->functions->texParameteri(sampler.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gl->functions->texParameteri(sampler.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl->bindTexture(sampler.target, sampler.id); + gl->texParameteri(sampler.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + 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); if (pixels == nullptr) { - gl->functions->texImage2D(sampler.target, 0, static_cast(format.internalFormatTexImage), - width, height, 0, format.externalFormat, GL_UNSIGNED_BYTE, nullptr); + gl->texImage2D(sampler.target, 0, static_cast(format.internalFormatTexImage), width, + height, 0, format.externalFormat, GL_UNSIGNED_BYTE, nullptr); } - if (!CheckGLError(gl)) { - gl->functions->deleteTextures(1, &sampler.id); + if (!CheckGLError(context)) { + gl->deleteTextures(1, &sampler.id); return nullptr; } if (alphaOnly) { @@ -168,7 +169,7 @@ std::shared_ptr Texture::Make(Context* context, int width, int height, } if (pixels != nullptr) { int bytesPerPixel = alphaOnly ? 1 : 4; - SubmitGLTexture(gl, sampler, width, height, rowBytes, bytesPerPixel, pixels); + SubmitGLTexture(context, sampler, width, height, rowBytes, bytesPerPixel, pixels); } return texture; } diff --git a/tgfx/src/gpu/opengl/GLUniformHandler.cpp b/tgfx/src/gpu/opengl/GLUniformHandler.cpp index 1cdbed9b44..d407e01889 100644 --- a/tgfx/src/gpu/opengl/GLUniformHandler.cpp +++ b/tgfx/src/gpu/opengl/GLUniformHandler.cpp @@ -45,8 +45,8 @@ UniformHandle GLUniformHandler::internalAddUniform(ShaderFlags visibility, Shade SamplerHandle GLUniformHandler::addSampler(const TextureSampler* sampler, const std::string& name) { auto mangleName = programBuilder->nameVariable('u', name); - auto gl = static_cast(programBuilder)->gl(); - const auto& swizzle = gl->caps->getTextureSwizzle(sampler->format); + auto caps = GLCaps::Get(programBuilder->getContext()); + const auto& swizzle = caps->getTextureSwizzle(sampler->format); ShaderVar::Type type; switch (static_cast(sampler)->target) { @@ -90,14 +90,12 @@ std::string GLUniformHandler::getUniformDeclarations(ShaderFlags visibility) con } void GLUniformHandler::resolveUniformLocations(unsigned programID) { - auto gl = static_cast(programBuilder)->gl(); + auto gl = GLFunctions::Get(programBuilder->getContext()); for (auto& uniform : uniforms) { - uniform.location = - gl->functions->getUniformLocation(programID, uniform.variable.name().c_str()); + uniform.location = gl->getUniformLocation(programID, uniform.variable.name().c_str()); } for (auto& sampler : samplers) { - sampler.location = - gl->functions->getUniformLocation(programID, sampler.variable.name().c_str()); + sampler.location = gl->getUniformLocation(programID, sampler.variable.name().c_str()); } } } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/GLUtil.cpp b/tgfx/src/gpu/opengl/GLUtil.cpp index 0824c41b13..e50296043e 100644 --- a/tgfx/src/gpu/opengl/GLUtil.cpp +++ b/tgfx/src/gpu/opengl/GLUtil.cpp @@ -51,155 +51,109 @@ GLVersion GetGLVersion(const char* versionString) { return {}; } -bool CreateGLTexture(const GLInterface* gl, int width, int height, GLSampler* texture) { +bool CreateGLTexture(Context* context, int width, int height, GLSampler* texture) { texture->target = GL_TEXTURE_2D; texture->format = PixelFormat::RGBA_8888; - gl->functions->genTextures(1, &texture->id); + auto gl = GLFunctions::Get(context); + gl->genTextures(1, &texture->id); if (texture->id <= 0) { return false; } - gl->functions->bindTexture(texture->target, texture->id); - gl->functions->texParameteri(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl->functions->texParameteri(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gl->functions->texParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gl->functions->texParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gl->functions->texImage2D(texture->target, 0, GL_RGBA, width, height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, nullptr); - gl->functions->bindTexture(texture->target, 0); + gl->bindTexture(texture->target, texture->id); + gl->texParameteri(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl->texParameteri(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl->texParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl->texParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl->texImage2D(texture->target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + gl->bindTexture(texture->target, 0); return true; } -static std::array GetGLSwizzleValues(const Swizzle& swizzle) { - unsigned glValues[4]; - for (int i = 0; i < 4; ++i) { - switch (swizzle[i]) { - case 'r': - glValues[i] = GL_RED; - break; - case 'g': - glValues[i] = GL_GREEN; - break; - case 'b': - glValues[i] = GL_BLUE; - break; - case 'a': - glValues[i] = GL_ALPHA; - break; - case '1': - glValues[i] = GL_ONE; - break; - default: - LOGE("Unsupported component"); - } - } - return {glValues[0], glValues[1], glValues[2], glValues[3]}; -} - -void ActiveGLTexture(const GLInterface* gl, unsigned textureUnit, unsigned target, - unsigned textureID, PixelFormat pixelFormat) { - gl->functions->activeTexture(textureUnit); - gl->functions->bindTexture(target, textureID); - gl->functions->texParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl->functions->texParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gl->functions->texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gl->functions->texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - if (gl->caps->textureSwizzleSupport) { - const auto& swizzle = gl->caps->getSwizzle(pixelFormat); - auto glValues = GetGLSwizzleValues(swizzle); - if (gl->caps->standard == GLStandard::GL) { - gl->functions->texParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, - reinterpret_cast(&glValues[0])); - } else if (gl->caps->standard == GLStandard::GLES) { - // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. - gl->functions->texParameteri(target, GL_TEXTURE_SWIZZLE_R, static_cast(glValues[0])); - gl->functions->texParameteri(target, GL_TEXTURE_SWIZZLE_G, static_cast(glValues[1])); - gl->functions->texParameteri(target, GL_TEXTURE_SWIZZLE_B, static_cast(glValues[2])); - gl->functions->texParameteri(target, GL_TEXTURE_SWIZZLE_A, static_cast(glValues[3])); - } - } -} - -void SubmitGLTexture(const GLInterface* gl, const GLSampler& sampler, int width, int height, +void SubmitGLTexture(Context* context, const GLSampler& sampler, int width, int height, size_t rowBytes, int bytesPerPixel, void* pixels) { if (pixels == nullptr || rowBytes == 0) { return; } - const auto& format = gl->caps->getTextureFormat(sampler.format); - gl->functions->bindTexture(sampler.target, sampler.id); - gl->functions->pixelStorei(GL_UNPACK_ALIGNMENT, bytesPerPixel); - if (gl->caps->unpackRowLengthSupport) { + auto gl = GLFunctions::Get(context); + auto caps = GLCaps::Get(context); + const auto& format = caps->getTextureFormat(sampler.format); + gl->bindTexture(sampler.target, sampler.id); + gl->pixelStorei(GL_UNPACK_ALIGNMENT, bytesPerPixel); + if (caps->unpackRowLengthSupport) { // the number of pixels, not bytes - gl->functions->pixelStorei(GL_UNPACK_ROW_LENGTH, static_cast(rowBytes / bytesPerPixel)); - gl->functions->texImage2D(sampler.target, 0, static_cast(format.internalFormatTexImage), - width, height, 0, format.externalFormat, GL_UNSIGNED_BYTE, pixels); - gl->functions->pixelStorei(GL_UNPACK_ROW_LENGTH, 0); + gl->pixelStorei(GL_UNPACK_ROW_LENGTH, static_cast(rowBytes / bytesPerPixel)); + gl->texImage2D(sampler.target, 0, static_cast(format.internalFormatTexImage), width, + height, 0, format.externalFormat, GL_UNSIGNED_BYTE, pixels); + gl->pixelStorei(GL_UNPACK_ROW_LENGTH, 0); } else { if (static_cast(width) * bytesPerPixel == rowBytes) { - gl->functions->texImage2D(sampler.target, 0, static_cast(format.internalFormatTexImage), - width, height, 0, format.externalFormat, GL_UNSIGNED_BYTE, pixels); + gl->texImage2D(sampler.target, 0, static_cast(format.internalFormatTexImage), width, + height, 0, format.externalFormat, GL_UNSIGNED_BYTE, pixels); } else { - gl->functions->texImage2D(sampler.target, 0, static_cast(format.internalFormatTexImage), - width, height, 0, format.externalFormat, GL_UNSIGNED_BYTE, nullptr); + gl->texImage2D(sampler.target, 0, static_cast(format.internalFormatTexImage), width, + height, 0, format.externalFormat, GL_UNSIGNED_BYTE, nullptr); auto data = reinterpret_cast(pixels); for (int row = 0; row < height; ++row) { - gl->functions->texSubImage2D(sampler.target, 0, 0, row, width, 1, format.externalFormat, - GL_UNSIGNED_BYTE, data + (row * rowBytes)); + gl->texSubImage2D(sampler.target, 0, 0, row, width, 1, format.externalFormat, + GL_UNSIGNED_BYTE, data + (row * rowBytes)); } } } } -unsigned CreateGLProgram(const GLInterface* gl, const std::string& vertex, - const std::string& fragment) { - auto vertexShader = LoadGLShader(gl, GL_VERTEX_SHADER, vertex); +unsigned CreateGLProgram(Context* context, const std::string& vertex, const std::string& fragment) { + auto vertexShader = LoadGLShader(context, GL_VERTEX_SHADER, vertex); if (vertexShader == 0) { return 0; } - auto fragmentShader = LoadGLShader(gl, GL_FRAGMENT_SHADER, fragment); + auto fragmentShader = LoadGLShader(context, GL_FRAGMENT_SHADER, fragment); if (fragmentShader == 0) { return 0; } - auto programHandle = gl->functions->createProgram(); - gl->functions->attachShader(programHandle, vertexShader); - gl->functions->attachShader(programHandle, fragmentShader); - gl->functions->linkProgram(programHandle); + auto gl = GLFunctions::Get(context); + auto programHandle = gl->createProgram(); + gl->attachShader(programHandle, vertexShader); + gl->attachShader(programHandle, fragmentShader); + gl->linkProgram(programHandle); int success; - gl->functions->getProgramiv(programHandle, GL_LINK_STATUS, &success); + gl->getProgramiv(programHandle, GL_LINK_STATUS, &success); if (!success) { char infoLog[512]; - gl->functions->getProgramInfoLog(programHandle, 512, nullptr, infoLog); - gl->functions->deleteProgram(programHandle); + gl->getProgramInfoLog(programHandle, 512, nullptr, infoLog); + gl->deleteProgram(programHandle); } - gl->functions->deleteShader(vertexShader); - gl->functions->deleteShader(fragmentShader); + gl->deleteShader(vertexShader); + gl->deleteShader(fragmentShader); return programHandle; } -unsigned LoadGLShader(const GLInterface* gl, unsigned shaderType, const std::string& source) { - auto shader = gl->functions->createShader(shaderType); +unsigned LoadGLShader(Context* context, unsigned shaderType, const std::string& source) { + auto gl = GLFunctions::Get(context); + auto shader = gl->createShader(shaderType); const char* files[] = {source.c_str()}; - gl->functions->shaderSource(shader, 1, files, nullptr); - gl->functions->compileShader(shader); + gl->shaderSource(shader, 1, files, nullptr); + gl->compileShader(shader); int success; - gl->functions->getShaderiv(shader, GL_COMPILE_STATUS, &success); + gl->getShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { char infoLog[512]; - gl->functions->getShaderInfoLog(shader, 512, nullptr, infoLog); + gl->getShaderInfoLog(shader, 512, nullptr, infoLog); LOGE("Could not compile shader: %d %s", shaderType, infoLog); - gl->functions->deleteShader(shader); + gl->deleteShader(shader); shader = 0; } return shader; } -bool CheckGLError(const GLInterface* gl) { +bool CheckGLError(Context* context) { #ifdef TGFX_BUILD_FOR_WEB - USE(gl); + USE(context); return true; #else + auto gl = GLFunctions::Get(context); bool success = true; unsigned errorCode; - while ((errorCode = gl->functions->getError()) != GL_NO_ERROR) { + while ((errorCode = gl->getError()) != GL_NO_ERROR) { success = false; LOGE("glCheckError: %d", errorCode); } diff --git a/tgfx/src/gpu/opengl/GLUtil.h b/tgfx/src/gpu/opengl/GLUtil.h index c389aedbd3..6d63506ec3 100644 --- a/tgfx/src/gpu/opengl/GLUtil.h +++ b/tgfx/src/gpu/opengl/GLUtil.h @@ -20,7 +20,6 @@ #include #include -#include "GLInterface.h" #include "core/ImageOrigin.h" #include "core/Matrix.h" #include "gpu/opengl/GLContext.h" @@ -39,19 +38,15 @@ struct GLVersion { GLVersion GetGLVersion(const char* versionString); -unsigned CreateGLProgram(const GLInterface* gl, const std::string& vertex, - const std::string& fragment); +unsigned CreateGLProgram(Context* context, const std::string& vertex, const std::string& fragment); -unsigned LoadGLShader(const GLInterface* gl, unsigned shaderType, const std::string& source); +unsigned LoadGLShader(Context* context, unsigned shaderType, const std::string& source); -bool CheckGLError(const GLInterface* gl); +bool CheckGLError(Context* context); -bool CreateGLTexture(const GLInterface* gl, int width, int height, GLSampler* texture); +bool CreateGLTexture(Context* context, int width, int height, GLSampler* texture); -void ActiveGLTexture(const GLInterface* gl, unsigned textureUnit, unsigned target, - unsigned textureID, PixelFormat pixelFormat = PixelFormat::RGBA_8888); - -void SubmitGLTexture(const GLInterface* gl, const GLSampler& sampler, int width, int height, +void SubmitGLTexture(Context* context, const GLSampler& sampler, int width, int height, size_t rowBytes, int bytesPerPixel, void* pixels); std::array ToGLMatrix(const Matrix& matrix); diff --git a/tgfx/src/gpu/opengl/GLYUVTexture.cpp b/tgfx/src/gpu/opengl/GLYUVTexture.cpp index 43e9600904..291cdfe27f 100644 --- a/tgfx/src/gpu/opengl/GLYUVTexture.cpp +++ b/tgfx/src/gpu/opengl/GLYUVTexture.cpp @@ -89,10 +89,11 @@ class GLNV12Texture : public GLYUVTexture { } }; -static std::vector MakeTexturePlanes(const GLInterface* gl, const YUVConfig& yuvConfig) { +static std::vector MakeTexturePlanes(Context* context, const YUVConfig& yuvConfig) { std::vector texturePlanes{}; unsigned yuvTextureIDs[] = {0, 0, 0}; - gl->functions->genTextures(yuvConfig.planeCount, yuvTextureIDs); + auto gl = GLFunctions::Get(context); + gl->genTextures(yuvConfig.planeCount, yuvTextureIDs); if (yuvTextureIDs[0] == 0) { return texturePlanes; } @@ -106,7 +107,7 @@ static std::vector MakeTexturePlanes(const GLInterface* gl, const YUV return texturePlanes; } -static void SubmitYUVTexture(const GLInterface* gl, const YUVConfig& yuvConfig, +static void SubmitYUVTexture(Context* context, const YUVConfig& yuvConfig, const GLSampler yuvTextures[]) { static constexpr int factor[] = {0, 1, 1}; for (int index = 0; index < yuvConfig.planeCount; index++) { @@ -116,14 +117,13 @@ static void SubmitYUVTexture(const GLInterface* gl, const YUVConfig& yuvConfig, auto rowBytes = yuvConfig.rowBytes[index]; auto bytesPerPixel = yuvConfig.bytesPerPixel[index]; auto pixels = yuvConfig.pixelsPlane[index]; - SubmitGLTexture(gl, sampler, w, h, rowBytes, bytesPerPixel, pixels); + SubmitGLTexture(context, sampler, w, h, rowBytes, bytesPerPixel, pixels); } } std::shared_ptr YUVTexture::MakeI420(Context* context, YUVColorSpace colorSpace, YUVColorRange colorRange, int width, int height, uint8_t* pixelsPlane[3], const int lineSize[3]) { - auto gl = GLInterface::Get(context); YUVConfig yuvConfig = YUVConfig(colorSpace, colorRange, width, height, I420_PLANE_COUNT); for (int i = 0; i < 3; i++) { yuvConfig.pixelsPlane[i] = pixelsPlane[i]; @@ -137,7 +137,7 @@ std::shared_ptr YUVTexture::MakeI420(Context* context, YUVColorSpace auto texture = std::static_pointer_cast(context->resourceCache()->getRecycled(recycleKey)); if (texture == nullptr) { - auto texturePlanes = MakeTexturePlanes(gl, yuvConfig); + auto texturePlanes = MakeTexturePlanes(context, yuvConfig); if (texturePlanes.empty()) { return nullptr; } @@ -146,14 +146,13 @@ std::shared_ptr YUVTexture::MakeI420(Context* context, YUVColorSpace yuvConfig.width, yuvConfig.height))); texture->samplers = texturePlanes; } - SubmitYUVTexture(gl, yuvConfig, &texture->samplers[0]); + SubmitYUVTexture(context, yuvConfig, &texture->samplers[0]); return texture; } std::shared_ptr YUVTexture::MakeNV12(Context* context, YUVColorSpace colorSpace, YUVColorRange colorRange, int width, int height, uint8_t* pixelsPlane[2], const int lineSize[2]) { - auto gl = GLInterface::Get(context); YUVConfig yuvConfig = YUVConfig(colorSpace, colorRange, width, height, NV12_PLANE_COUNT); for (int i = 0; i < 2; i++) { yuvConfig.pixelsPlane[i] = pixelsPlane[i]; @@ -169,7 +168,7 @@ std::shared_ptr YUVTexture::MakeNV12(Context* context, YUVColorSpace auto texture = std::static_pointer_cast(context->resourceCache()->getRecycled(recycleKey)); if (texture == nullptr) { - auto texturePlanes = MakeTexturePlanes(gl, yuvConfig); + auto texturePlanes = MakeTexturePlanes(context, yuvConfig); if (texturePlanes.empty()) { return nullptr; } @@ -178,7 +177,7 @@ std::shared_ptr YUVTexture::MakeNV12(Context* context, YUVColorSpace yuvConfig.width, yuvConfig.height))); texture->samplers = texturePlanes; } - SubmitYUVTexture(gl, yuvConfig, &texture->samplers[0]); + SubmitYUVTexture(context, yuvConfig, &texture->samplers[0]); return texture; } @@ -198,10 +197,10 @@ const TextureSampler* GLYUVTexture::getSamplerAt(size_t index) const { return &samplers[index]; } -void GLYUVTexture::onRelease(Context* context) { - auto gl = GLInterface::Get(context); +void GLYUVTexture::onReleaseGPU() { + auto gl = GLFunctions::Get(context); for (const auto& sampler : samplers) { - gl->functions->deleteTextures(1, &sampler.id); + gl->deleteTextures(1, &sampler.id); } } } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.h b/tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.h index 0765c87415..04232ca3ca 100644 --- a/tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.h +++ b/tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.h @@ -34,12 +34,13 @@ class CGLHardwareTexture : public GLTexture { protected: void computeRecycleKey(BytesKey* recycleKey) const override; - void onRelease(Context*) override; private: CVPixelBufferRef pixelBuffer = nullptr; CVOpenGLTextureRef texture = nil; static void ComputeRecycleKey(BytesKey* recycleKey, CVPixelBufferRef pixelBuffer); + + void onReleaseGPU() override; }; } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.mm b/tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.mm index 834c896ec5..4a4c1d3373 100644 --- a/tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.mm +++ b/tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.mm @@ -92,7 +92,7 @@ ComputeRecycleKey(recycleKey, pixelBuffer); } -void CGLHardwareTexture::onRelease(Context* context) { +void CGLHardwareTexture::onReleaseGPU() { if (texture == nil) { return; } diff --git a/tgfx/src/gpu/opengl/cgl/CGLWindow.mm b/tgfx/src/gpu/opengl/cgl/CGLWindow.mm index 4093f24f00..afff47fa1c 100644 --- a/tgfx/src/gpu/opengl/cgl/CGLWindow.mm +++ b/tgfx/src/gpu/opengl/cgl/CGLWindow.mm @@ -110,11 +110,12 @@ GLFrameBuffer frameBuffer = {}; frameBuffer.id = 0; frameBuffer.format = PixelFormat::RGBA_8888; - auto renderTarget = GLRenderTarget::MakeFrom(context, frameBuffer, size.width, size.height, ImageOrigin::BottomLeft); - return Surface::MakeFrom(context, renderTarget); + auto renderTarget = GLRenderTarget::MakeFrom(context, frameBuffer, size.width, size.height, + ImageOrigin::BottomLeft); + return Surface::MakeFrom(renderTarget); } auto texture = CGLHardwareTexture::MakeFrom(context, pixelBuffer); - return Surface::MakeFrom(context, texture); + return Surface::MakeFrom(texture); } void CGLWindow::onPresent(Context*, int64_t) { diff --git a/tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.h b/tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.h index 4b64205f32..a7ed6da053 100644 --- a/tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.h +++ b/tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.h @@ -33,12 +33,12 @@ class EAGLHardwareTexture : public GLTexture { protected: void computeRecycleKey(BytesKey* recycleKey) const override; - void onRelease(Context*) override; private: CVPixelBufferRef pixelBuffer = nullptr; CVOpenGLESTextureRef texture = nil; static void ComputeRecycleKey(BytesKey* recycleKey, CVPixelBufferRef pixelBuffer); + void onReleaseGPU() override; }; } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.mm b/tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.mm index 50c36d4c48..1c3bab1031 100644 --- a/tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.mm +++ b/tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.mm @@ -17,9 +17,9 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "EAGLHardwareTexture.h" -#include "gpu/opengl/eagl/EAGLDevice.h" #include "core/utils/UniqueID.h" #include "gpu/opengl/GLContext.h" +#include "gpu/opengl/eagl/EAGLDevice.h" namespace tgfx { static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pixelBuffer, @@ -32,20 +32,20 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix CVOpenGLESTextureRef texture = nil; CVReturn result; if (CVPixelBufferGetPixelFormatType(pixelBuffer) == kCVPixelFormatType_OneComponent8) { - auto gl = GLInterface::Get(context); - const auto& format = gl->caps->getTextureFormat(PixelFormat::ALPHA_8); + auto caps = GLCaps::Get(context); + const auto& format = caps->getTextureFormat(PixelFormat::ALPHA_8); // 返回的 texture 对象是一个强引用计数为 1 的对象。 result = CVOpenGLESTextureCacheCreateTextureFromImage( kCFAllocatorDefault, textureCache, pixelBuffer, NULL, /* texture attributes */ - GL_TEXTURE_2D, format.internalFormatTexImage, /* opengl format */ - width, height, GL_RED, /* native iOS format */ + GL_TEXTURE_2D, format.internalFormatTexImage, /* opengl format */ + width, height, GL_RED, /* native iOS format */ GL_UNSIGNED_BYTE, 0, &texture); } else { // 返回的 texture 对象是一个强引用计数为 1 的对象。 result = CVOpenGLESTextureCacheCreateTextureFromImage( kCFAllocatorDefault, textureCache, pixelBuffer, NULL, /* texture attributes */ - GL_TEXTURE_2D, GL_RGBA, /* opengl format */ - width, height, GL_BGRA, /* native iOS format */ + GL_TEXTURE_2D, GL_RGBA, /* opengl format */ + width, height, GL_BGRA, /* native iOS format */ GL_UNSIGNED_BYTE, 0, &texture); } if (result != kCVReturnSuccess && texture != nil) { @@ -60,8 +60,8 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix std::shared_ptr glTexture = nullptr; BytesKey recycleKey = {}; ComputeRecycleKey(&recycleKey, pixelBuffer); - glTexture = - std::static_pointer_cast(context->resourceCache()->getRecycled(recycleKey)); + glTexture = std::static_pointer_cast( + context->resourceCache()->getRecycled(recycleKey)); if (glTexture) { return glTexture; } @@ -69,14 +69,14 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix if (eaglDevice == nullptr) { return nullptr; } - + auto texture = GetTextureRef(context, pixelBuffer, eaglDevice->getTextureCache()); if (texture == nil) { return nullptr; } GLSampler glInfo = {}; auto oneComponent8 = - CVPixelBufferGetPixelFormatType(pixelBuffer) == kCVPixelFormatType_OneComponent8; + CVPixelBufferGetPixelFormatType(pixelBuffer) == kCVPixelFormatType_OneComponent8; glInfo.format = oneComponent8 ? PixelFormat::ALPHA_8 : PixelFormat::RGBA_8888; glInfo.target = CVOpenGLESTextureGetTarget(texture); glInfo.id = CVOpenGLESTextureGetName(texture); @@ -113,7 +113,7 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix ComputeRecycleKey(recycleKey, pixelBuffer); } -void EAGLHardwareTexture::onRelease(Context* context) { +void EAGLHardwareTexture::onReleaseGPU() { if (texture == nil) { return; } diff --git a/tgfx/src/gpu/opengl/eagl/EAGLNV12Texture.h b/tgfx/src/gpu/opengl/eagl/EAGLNV12Texture.h index e88acd86be..ace720ff34 100644 --- a/tgfx/src/gpu/opengl/eagl/EAGLNV12Texture.h +++ b/tgfx/src/gpu/opengl/eagl/EAGLNV12Texture.h @@ -36,12 +36,11 @@ class EAGLNV12Texture : public GLYUVTexture { return YUVPixelFormat::NV12; } - protected: - void onRelease(Context* context) override; - private: CVPixelBufferRef pixelBuffer = nullptr; CVOpenGLESTextureRef lumaTexture = nullptr; CVOpenGLESTextureRef chromaTexture = nullptr; + + void onReleaseGPU() override; }; } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/eagl/EAGLNV12Texture.mm b/tgfx/src/gpu/opengl/eagl/EAGLNV12Texture.mm index f1059a9763..ba53cc7a0f 100644 --- a/tgfx/src/gpu/opengl/eagl/EAGLNV12Texture.mm +++ b/tgfx/src/gpu/opengl/eagl/EAGLNV12Texture.mm @@ -45,16 +45,16 @@ static GLSampler ToGLSampler(CVOpenGLESTextureRef texture, PixelFormat format) { auto height = static_cast(CVPixelBufferGetHeight(pixelBuffer)); CVOpenGLESTextureRef outputTextureLuma = nil; CVOpenGLESTextureRef outputTextureChroma = nil; - auto gl = GLInterface::Get(context); + auto caps = GLCaps::Get(context); auto lumaComponentFormat = PixelFormat::GRAY_8; - const auto& oneComponentFormat = gl->caps->getTextureFormat(lumaComponentFormat); + const auto& oneComponentFormat = caps->getTextureFormat(lumaComponentFormat); // 返回的 texture 对象是一个强引用计数为 1 的对象。 CVOpenGLESTextureCacheCreateTextureFromImage( kCFAllocatorDefault, textureCache, pixelBuffer, NULL, GL_TEXTURE_2D, oneComponentFormat.internalFormatTexImage, width, height, oneComponentFormat.externalFormat, GL_UNSIGNED_BYTE, 0, &outputTextureLuma); auto chromaComponentFormat = PixelFormat::RG_88; - const auto& twoComponentFormat = gl->caps->getTextureFormat(chromaComponentFormat); + const auto& twoComponentFormat = caps->getTextureFormat(chromaComponentFormat); // 返回的 texture 对象是一个强引用计数为 1 的对象。 CVOpenGLESTextureCacheCreateTextureFromImage( kCFAllocatorDefault, textureCache, pixelBuffer, NULL, GL_TEXTURE_2D, @@ -89,7 +89,7 @@ static GLSampler ToGLSampler(CVOpenGLESTextureRef texture, PixelFormat format) { } } -void EAGLNV12Texture::onRelease(Context*) { +void EAGLNV12Texture::onReleaseGPU() { if (lumaTexture == nil || chromaTexture == nil) { return; } diff --git a/tgfx/src/gpu/opengl/eagl/EAGLWindow.mm b/tgfx/src/gpu/opengl/eagl/EAGLWindow.mm index 5d16078d78..00b5f70e06 100644 --- a/tgfx/src/gpu/opengl/eagl/EAGLWindow.mm +++ b/tgfx/src/gpu/opengl/eagl/EAGLWindow.mm @@ -86,13 +86,13 @@ EAGLWindow::~EAGLWindow() { auto context = device->lockContext(); if (context) { - auto gl = GLInterface::Get(context); + auto gl = GLFunctions::Get(context); if (frameBufferID > 0) { - gl->functions->deleteFramebuffers(1, &frameBufferID); + gl->deleteFramebuffers(1, &frameBufferID); frameBufferID = 0; } if (colorBuffer) { - gl->functions->deleteRenderbuffers(1, &colorBuffer); + gl->deleteRenderbuffers(1, &colorBuffer); colorBuffer = 0; } device->unlock(); @@ -106,15 +106,15 @@ std::shared_ptr EAGLWindow::onCreateSurface(Context* context) { if (pixelBuffer != nil) { auto texture = EAGLHardwareTexture::MakeFrom(context, pixelBuffer); - return GLSurface::MakeFrom(context, texture); + return GLSurface::MakeFrom(texture); } - auto gl = GLInterface::Get(context); + auto gl = GLFunctions::Get(context); if (frameBufferID > 0) { - gl->functions->deleteFramebuffers(1, &frameBufferID); + gl->deleteFramebuffers(1, &frameBufferID); frameBufferID = 0; } if (colorBuffer) { - gl->functions->deleteRenderbuffers(1, &colorBuffer); + gl->deleteRenderbuffers(1, &colorBuffer); colorBuffer = 0; } auto width = layer.bounds.size.width * layer.contentsScale; @@ -122,17 +122,16 @@ if (width <= 0 || height <= 0) { return nullptr; } - gl->functions->genFramebuffers(1, &frameBufferID); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, frameBufferID); - gl->functions->genRenderbuffers(1, &colorBuffer); - gl->functions->bindRenderbuffer(GL_RENDERBUFFER, colorBuffer); - gl->functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, - colorBuffer); + gl->genFramebuffers(1, &frameBufferID); + gl->bindFramebuffer(GL_FRAMEBUFFER, frameBufferID); + gl->genRenderbuffers(1, &colorBuffer); + gl->bindRenderbuffer(GL_RENDERBUFFER, colorBuffer); + gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer); auto eaglContext = static_cast(context->device())->eaglContext(); [eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; - auto frameBufferStatus = gl->functions->checkFramebufferStatus(GL_FRAMEBUFFER); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, 0); - gl->functions->bindRenderbuffer(GL_RENDERBUFFER, 0); + auto frameBufferStatus = gl->checkFramebufferStatus(GL_FRAMEBUFFER); + gl->bindFramebuffer(GL_FRAMEBUFFER, 0); + gl->bindRenderbuffer(GL_RENDERBUFFER, 0); if (frameBufferStatus != GL_FRAMEBUFFER_COMPLETE) { LOGE("EAGLWindow::onCreateSurface() Framebuffer is not complete!"); return nullptr; @@ -140,19 +139,20 @@ GLFrameBuffer glInfo = {}; glInfo.id = frameBufferID; glInfo.format = PixelFormat::RGBA_8888; - auto renderTarget = GLRenderTarget::MakeFrom(context, glInfo, static_cast(width), static_cast(height), ImageOrigin::BottomLeft); - return Surface::MakeFrom(context, renderTarget); + auto renderTarget = GLRenderTarget::MakeFrom(context, glInfo, static_cast(width), + static_cast(height), ImageOrigin::BottomLeft); + return Surface::MakeFrom(renderTarget); } void EAGLWindow::onPresent(Context* context, int64_t) { - auto gl = GLInterface::Get(context); + auto gl = GLFunctions::Get(context); if (layer) { - gl->functions->bindRenderbuffer(GL_RENDERBUFFER, colorBuffer); + gl->bindRenderbuffer(GL_RENDERBUFFER, colorBuffer); auto eaglContext = static_cast(context->device())->eaglContext(); [eaglContext presentRenderbuffer:GL_RENDERBUFFER]; - gl->functions->bindRenderbuffer(GL_RENDERBUFFER, 0); + gl->bindRenderbuffer(GL_RENDERBUFFER, 0); } else { - gl->functions->flush(); + gl->flush(); } } } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/egl/EGLHardwareTexture.cpp b/tgfx/src/gpu/opengl/egl/EGLHardwareTexture.cpp index c7ba74cf07..87a562dee8 100644 --- a/tgfx/src/gpu/opengl/egl/EGLHardwareTexture.cpp +++ b/tgfx/src/gpu/opengl/egl/EGLHardwareTexture.cpp @@ -110,7 +110,7 @@ void EGLHardwareTexture::ComputeRecycleKey(BytesKey* recycleKey, void* hardwareB recycleKey->write(hardwareBuffer); } -void EGLHardwareTexture::onRelease(Context* context) { +void EGLHardwareTexture::onReleaseGPU() { glDeleteTextures(1, &sampler.id); auto display = static_cast(context->device())->getDisplay(); eglext::eglDestroyImageKHR(display, eglImage); diff --git a/tgfx/src/gpu/opengl/egl/EGLHardwareTexture.h b/tgfx/src/gpu/opengl/egl/EGLHardwareTexture.h index e721c9f8ab..fe92217c18 100644 --- a/tgfx/src/gpu/opengl/egl/EGLHardwareTexture.h +++ b/tgfx/src/gpu/opengl/egl/EGLHardwareTexture.h @@ -41,7 +41,7 @@ class EGLHardwareTexture : public GLTexture { ~EGLHardwareTexture() override; - void onRelease(Context* context) override; + void onReleaseGPU() override; }; } // namespace tgfx diff --git a/tgfx/src/gpu/opengl/egl/EGLWindow.cpp b/tgfx/src/gpu/opengl/egl/EGLWindow.cpp index 6727c36d94..8542d7ee4f 100644 --- a/tgfx/src/gpu/opengl/egl/EGLWindow.cpp +++ b/tgfx/src/gpu/opengl/egl/EGLWindow.cpp @@ -59,7 +59,7 @@ std::shared_ptr EGLWindow::onCreateSurface(Context* context) { frameBuffer.format = PixelFormat::RGBA_8888; auto renderTarget = GLRenderTarget::MakeFrom(context, frameBuffer, width, height, ImageOrigin::BottomLeft); - return Surface::MakeFrom(context, renderTarget); + return Surface::MakeFrom(renderTarget); } void EGLWindow::onPresent(Context*, int64_t presentationTime) { diff --git a/tgfx/src/gpu/opengl/qt/QGLWindow.cpp b/tgfx/src/gpu/opengl/qt/QGLWindow.cpp index e0617582bd..81c2dd2e02 100644 --- a/tgfx/src/gpu/opengl/qt/QGLWindow.cpp +++ b/tgfx/src/gpu/opengl/qt/QGLWindow.cpp @@ -99,7 +99,7 @@ std::shared_ptr QGLWindow::onCreateSurface(Context* context) { } frontTexture = std::static_pointer_cast(Texture::MakeRGBA(context, width, height)); backTexture = std::static_pointer_cast(Texture::MakeRGBA(context, width, height)); - auto surface = Surface::MakeFrom(context, backTexture); + auto surface = Surface::MakeFrom(backTexture); renderTarget = std::static_pointer_cast(surface->getRenderTarget()); return surface; } @@ -108,13 +108,13 @@ void QGLWindow::onPresent(Context* context, int64_t) { if (renderTarget == nullptr) { return; } - auto gl = GLInterface::Get(context); + auto gl = GLFunctions::Get(context); std::swap(frontTexture, backTexture); - gl->functions->flush(); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, renderTarget->glFrameBuffer().id); - gl->functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - backTexture->glSampler().id, 0); - gl->functions->bindFramebuffer(GL_FRAMEBUFFER, 0); + gl->flush(); + gl->bindFramebuffer(GL_FRAMEBUFFER, renderTarget->glFrameBuffer().id); + gl->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + backTexture->glSampler().id, 0); + gl->bindFramebuffer(GL_FRAMEBUFFER, 0); invalidateTexture(); } } // namespace tgfx \ No newline at end of file diff --git a/tgfx/src/gpu/opengl/webgl/WebGLWindow.cpp b/tgfx/src/gpu/opengl/webgl/WebGLWindow.cpp index ecfd686ccd..81ea327ed1 100644 --- a/tgfx/src/gpu/opengl/webgl/WebGLWindow.cpp +++ b/tgfx/src/gpu/opengl/webgl/WebGLWindow.cpp @@ -51,6 +51,6 @@ std::shared_ptr WebGLWindow::onCreateSurface(Context* context) { glInfo.format = PixelFormat::RGBA_8888; auto renderTarget = GLRenderTarget::MakeFrom(context, glInfo, width, height, ImageOrigin::BottomLeft); - return Surface::MakeFrom(context, renderTarget); + return Surface::MakeFrom(renderTarget); } } // namespace tgfx diff --git a/tgfx/src/platform/web/NativeTextureBuffer.cpp b/tgfx/src/platform/web/NativeTextureBuffer.cpp index 821838b6b8..3c28f1d7cc 100644 --- a/tgfx/src/platform/web/NativeTextureBuffer.cpp +++ b/tgfx/src/platform/web/NativeTextureBuffer.cpp @@ -37,8 +37,8 @@ std::shared_ptr NativeTextureBuffer::makeTexture(Context* context) cons return nullptr; } auto& glInfo = std::static_pointer_cast(texture)->glSampler(); - auto gl = GLInterface::Get(context); - gl->functions->bindTexture(glInfo.target, glInfo.id); + auto gl = GLFunctions::Get(context); + gl->bindTexture(glInfo.target, glInfo.id); source.call("upload", val::module_property("GL")); return texture; }