gl_engine: gradient implementation 25/243225/3
authorPranay Kumar Samanta <pranay.ks@samsung.com>
Fri, 4 Sep 2020 04:56:28 +0000 (10:26 +0530)
committerHermet Park <chuneon.park@samsung.com>
Tue, 8 Sep 2020 05:42:18 +0000 (14:42 +0900)
Change-Id: If2413328437847d52ba1badc3b5c510fdd47ccd3

16 files changed:
src/lib/gl_engine/meson.build [changed mode: 0644->0755]
src/lib/gl_engine/tvgGlCommon.h [changed mode: 0644->0755]
src/lib/gl_engine/tvgGlGeometry.cpp [changed mode: 0644->0755]
src/lib/gl_engine/tvgGlGeometry.h [changed mode: 0644->0755]
src/lib/gl_engine/tvgGlProgram.cpp [changed mode: 0644->0755]
src/lib/gl_engine/tvgGlProgram.h [changed mode: 0644->0755]
src/lib/gl_engine/tvgGlPropertyInterface.cpp [new file with mode: 0755]
src/lib/gl_engine/tvgGlPropertyInterface.h [new file with mode: 0755]
src/lib/gl_engine/tvgGlRenderTask.cpp [new file with mode: 0755]
src/lib/gl_engine/tvgGlRenderTask.h [new file with mode: 0755]
src/lib/gl_engine/tvgGlRenderer.cpp [changed mode: 0644->0755]
src/lib/gl_engine/tvgGlRenderer.h [changed mode: 0644->0755]
src/lib/gl_engine/tvgGlRendererProperties.h [new file with mode: 0755]
src/lib/gl_engine/tvgGlShaderSrc.cpp [changed mode: 0644->0755]
src/lib/gl_engine/tvgGlShaderSrc.h [changed mode: 0644->0755]
src/lib/tvgGlCanvas.cpp [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 63c7ee8..5efb7b1
@@ -3,13 +3,18 @@ source_file = [
    'tvgGlGeometry.h',
    'tvgGlGpuBuffer.h',
    'tvgGlProgram.h',
+   'tvgGlPropertyInterface.h',
    'tvgGlRenderer.h',
+   'tvgGlRendererProperties.h',
+   'tvgGlRenderTask.h',
    'tvgGlShader.h',
    'tvgGlShaderSrc.h',
    'tvgGlGeometry.cpp',
    'tvgGlGpuBuffer.cpp',
    'tvgGlProgram.cpp',
+   'tvgGlPropertyInterface.cpp',
    'tvgGlRenderer.cpp',
+   'tvgGlRenderTask.cpp',
    'tvgGlShader.cpp',
    'tvgGlShaderSrc.cpp',
 ]
old mode 100644 (file)
new mode 100755 (executable)
index db137f2..11a7181
@@ -24,6 +24,7 @@
 #define _TVG_GL_COMMON_H_\r
 \r
 #include "tvgCommon.h"\r
+#include <assert.h>\r
 \r
 \r
 #define GL_CHECK(x) \\r
old mode 100644 (file)
new mode 100755 (executable)
index e89077d..0d6245c
@@ -33,6 +33,17 @@ uint32_t GlGeometry::getPrimitiveCount()
 }
 
 
+const GlSize GlGeometry::getPrimitiveSize(const uint32_t primitiveIndex) const
+{
+    if (primitiveIndex >= mPrimitives.size())
+    {
+        return GlSize();
+    }
+    GlSize size = mPrimitives[primitiveIndex].mBottomRight - mPrimitives[primitiveIndex].mTopLeft;
+    return size;
+}
+
+
 bool GlGeometry::decomposeOutline(const Shape &shape)
 {
     const PathCommand *cmds = nullptr;
@@ -46,43 +57,63 @@ bool GlGeometry::decomposeOutline(const Shape &shape)
         return false;
 
     GlPrimitive* curPrimitive = nullptr;
+    GlPoint min = { FLT_MAX, FLT_MAX };
+    GlPoint max = { 0.0f, 0.0f };
+
     for (size_t i = 0; i < cmdCnt; ++i)
     {
-        switch (*(cmds + i))
-        {
-            case PathCommand::Close:
-            {
-                if (curPrimitive && curPrimitive->mAAPoints.size() > 0 &&
-                (curPrimitive->mAAPoints[0].orgPt != curPrimitive->mAAPoints.back().orgPt) )
+        switch (*(cmds + i)) {
+            case PathCommand::Close: {
+                if (curPrimitive)
                 {
-                    curPrimitive->mAAPoints.push_back(curPrimitive->mAAPoints[0].orgPt);
+                    if (curPrimitive->mAAPoints.size() > 0 &&
+                        (curPrimitive->mAAPoints[0].orgPt != curPrimitive->mAAPoints.back().orgPt))
+                    {
+                        curPrimitive->mAAPoints.push_back(curPrimitive->mAAPoints[0].orgPt);
+                    }
+                    curPrimitive->mIsClosed = true;
                 }
                 break;
             }
-            case PathCommand::MoveTo:
+            case PathCommand::MoveTo: {
+                if (curPrimitive)
+                {
+                    curPrimitive->mTopLeft = min;
+                    curPrimitive->mBottomRight = max;
+                    if (curPrimitive->mAAPoints.size() > 2 &&
+                        (curPrimitive->mAAPoints[0].orgPt == curPrimitive->mAAPoints.back().orgPt))
+                    {
+                        curPrimitive->mIsClosed = true;
+                    }
+                }
                 mPrimitives.push_back(GlPrimitive());
                 curPrimitive = &mPrimitives.back();
-                __attribute__ ((fallthrough));
-            case PathCommand::LineTo:
-            {
+            }
+            __attribute__ ((fallthrough));
+            case PathCommand::LineTo: {
                 if (curPrimitive)
                 {
-                    addPoint(*curPrimitive, pts[0]);
+                    addPoint(*curPrimitive, pts[0], min, max);
                 }
                 pts++;
                 break;
             }
-            case PathCommand::CubicTo:
-            {
+            case PathCommand::CubicTo: {
                 if (curPrimitive)
                 {
-                    decomposeCubicCurve(*curPrimitive, curPrimitive->mAAPoints.back().orgPt, pts[0], pts[1], pts[2]);
+                    decomposeCubicCurve(*curPrimitive, curPrimitive->mAAPoints.back().orgPt, pts[0], pts[1], pts[2], min, max);
                 }
                 pts += 3;
                 break;
             }
         }
     }
+    if (curPrimitive)
+    {
+        curPrimitive->mTopLeft = min;
+        curPrimitive->mBottomRight = max;
+    }
+
     return true;
 }
 
@@ -107,20 +138,30 @@ bool GlGeometry::generateAAPoints(TVG_UNUSED const Shape &shape, float strokeWd,
 
         size_t fPoint = 0;
         size_t sPoint = 1;
-        for (size_t i = 0; i < nPoints; ++i)
+        for (size_t i = 0; i < nPoints - 1; ++i)
         {
             fPoint = i;
             sPoint = i + 1;
-            if (fPoint == nPoints - 1)
+            if (shapeGeometry.mIsClosed && sPoint == nPoints - 1)
+            {
                 sPoint = 0;
+            }
 
             GlPoint normal = getNormal(aaPts[fPoint].orgPt, aaPts[sPoint].orgPt);
 
             normalInfo[fPoint].normal1 = normal;
             normalInfo[sPoint].normal2 = normal;
         }
-        normalInfo[0].normal2 = normalInfo[0].normal1;
-        normalInfo[nPoints - 1].normal1 = normalInfo[nPoints - 1].normal2;
+        if (shapeGeometry.mIsClosed)
+        {
+            normalInfo[nPoints - 1].normal1 = normalInfo[0].normal1;
+            normalInfo[nPoints - 1].normal2 = normalInfo[0].normal2;
+        }
+        else
+        {
+            normalInfo[nPoints - 1].normal1 = normalInfo[nPoints - 1].normal2;
+            normalInfo[0].normal2 = normalInfo[0].normal1;
+        }
 
         for (uint32_t i = 0; i < nPoints; ++i)
         {
@@ -133,7 +174,7 @@ bool GlGeometry::generateAAPoints(TVG_UNUSED const Shape &shape, float strokeWd,
             else
                 normalInfo[i].normalF = GlPoint(0, 0);
 
-            if (flag & RenderUpdateFlag::Color)
+            if (flag & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient))
             {
                 aaPts[i].fillOuterBlur = extendEdge(aaPts[i].orgPt, normalInfo[i].normalF, blurDir * stroke);
                 aaPts[i].fillOuter = extendEdge(aaPts[i].fillOuterBlur, normalInfo[i].normalF, blurDir*antiAliasWidth);
@@ -161,7 +202,7 @@ bool GlGeometry::tesselate(TVG_UNUSED const Shape &shape, float viewWd, float vi
         VertexDataArray& fill = shapeGeometry.mFill;
         VertexDataArray& stroke = shapeGeometry.mStroke;
 
-        if (flag & RenderUpdateFlag::Color)
+        if (flag & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient) )
         {
             uint32_t i = 0;
             for (size_t pt = 0; pt < aaPts.size(); ++pt)
@@ -229,7 +270,7 @@ void GlGeometry::draw(const uint32_t location, const uint32_t primitiveIndex, Re
     {
         return;
     }
-    VertexDataArray& geometry = (flag == RenderUpdateFlag::Color) ? mPrimitives[primitiveIndex].mFill : mPrimitives[primitiveIndex].mStroke;
+    VertexDataArray& geometry = (flag == RenderUpdateFlag::Stroke) ? mPrimitives[primitiveIndex].mStroke : mPrimitives[primitiveIndex].mFill;
 
     updateBuffer(location, geometry);
     GL_CHECK(glDrawElements(GL_TRIANGLES, geometry.indices.size(), GL_UNSIGNED_INT, geometry.indices.data()));
@@ -280,8 +321,12 @@ GlPoint GlGeometry::extendEdge(const GlPoint &pt, const GlPoint &normal, float s
     return (pt + tmp);
 }
 
-void GlGeometry::addPoint(GlPrimitive& primitve, const GlPoint &pt)
+void GlGeometry::addPoint(GlPrimitive& primitve, const GlPoint &pt, GlPoint &min, GlPoint &max)
 {
+    if (pt.x < min.x) min.x = pt.x;
+    if (pt.y < min.y) min.y = pt.y;
+    if (pt.x > max.x) max.x = pt.x;
+    if (pt.y > max.y) max.y = pt.y;
     primitve.mAAPoints.push_back(GlPoint(pt.x, pt.y));
 }
 
@@ -320,11 +365,11 @@ bool GlGeometry::isBezierFlat(const GlPoint &p1, const GlPoint &c1, const GlPoin
     return false;
 }
 
-void GlGeometry::decomposeCubicCurve(GlPrimitive& primitve, const GlPoint &pt1, const GlPoint &cpt1, const GlPoint &cpt2, const GlPoint &pt2)
+void GlGeometry::decomposeCubicCurve(GlPrimitive& primitve, const GlPoint &pt1, const GlPoint &cpt1, const GlPoint &cpt2, const GlPoint &pt2, GlPoint &min, GlPoint &max)
 {
     if (isBezierFlat(pt1, cpt1, cpt2, pt2))
     {
-        addPoint(primitve, pt2);
+        addPoint(primitve, pt2, min, max);
         return;
     }
     GlPoint p12 = (pt1 + cpt1) * 0.5f;
@@ -336,7 +381,7 @@ void GlGeometry::decomposeCubicCurve(GlPrimitive& primitve, const GlPoint &pt1,
 
     GlPoint p1234 = (p123 + p234) * 0.5f;
 
-    decomposeCubicCurve(primitve, pt1, p12, p123, p1234);
-    decomposeCubicCurve(primitve, p1234, p234, p34, pt2);
+    decomposeCubicCurve(primitve, pt1, p12, p123, p1234, min, max);
+    decomposeCubicCurve(primitve, p1234, p234, p34, pt2, min, max);
 }
 
old mode 100644 (file)
new mode 100755 (executable)
index e5f1b03..68dc99d
@@ -128,6 +128,8 @@ public:
     }
 };
 
+typedef GlPoint GlSize;
+
 struct SmoothPoint
 {
     GlPoint orgPt;
@@ -174,6 +176,9 @@ struct GlPrimitive
     vector<SmoothPoint> mAAPoints;
     VertexDataArray mFill;
     VertexDataArray mStroke;
+    GlPoint mTopLeft;
+    GlPoint mBottomRight;
+    bool mIsClosed = false;
 };
 
 class GlGpuBuffer;
@@ -183,9 +188,10 @@ class GlGeometry
 public:
 
     uint32_t getPrimitiveCount();
+    const GlSize getPrimitiveSize(const uint32_t primitiveIndex) const;
     bool decomposeOutline(const Shape& shape);
-    bool generateAAPoints(const Shape& shape, float strokeWd, RenderUpdateFlag flag);
-    bool tesselate(const Shape &shape, float viewWd, float viewHt, RenderUpdateFlag flag);
+    bool generateAAPoints(TVG_UNUSED const Shape& shape, float strokeWd, RenderUpdateFlag flag);
+    bool tesselate(TVG_UNUSED const Shape &shape, float viewWd, float viewHt, RenderUpdateFlag flag);
     void disableVertex(uint32_t location);
     void draw(const uint32_t location, const uint32_t primitiveIndex, RenderUpdateFlag flag);
 
@@ -196,11 +202,11 @@ private:
     float dotProduct(const GlPoint &p1, const GlPoint &p2);
     GlPoint extendEdge(const GlPoint &pt, const GlPoint &normal, float scalar);
 
-    void addPoint(GlPrimitive& primitve, const GlPoint &pt);
+    void addPoint(GlPrimitive& primitve, const GlPoint &pt, GlPoint &min, GlPoint &max);
     void addTriangleFanIndices(uint32_t &curPt, vector<uint32_t> &indices);
     void addQuadIndices(uint32_t &curPt, vector<uint32_t> &indices);
     bool isBezierFlat(const GlPoint &p1, const GlPoint &c1, const GlPoint &c2, const GlPoint &p2);
-    void decomposeCubicCurve(GlPrimitive& primitve, const GlPoint &pt1, const GlPoint &cpt1, const GlPoint &cpt2, const GlPoint &pt2);
+    void decomposeCubicCurve(GlPrimitive& primitve, const GlPoint &pt1, const GlPoint &cpt1, const GlPoint &cpt2, const GlPoint &pt2, GlPoint &min, GlPoint &max);
     void updateBuffer(const uint32_t location, const VertexDataArray& vertexArray);
 
     unique_ptr<GlGpuBuffer> mGpuBuffer;
old mode 100644 (file)
new mode 100755 (executable)
index 9d03849..38ed3e1
 #include <GLES2/gl2.h>
 
 
-static std::vector<string> gStdAttributes = {
-    "aLocation"
-};
-
-static std::vector<string> gStdUniforms = {
-    "uColor"
-};
-
 uint32_t GlProgram::mCurrentProgram = 0;
-map<string, int32_t> GlProgram::mAttributeBuffer;
-map<string, int32_t> GlProgram::mUniformBuffer;
 
 
 unique_ptr<GlProgram> GlProgram::gen(std::shared_ptr<GlShader> shader)
@@ -48,17 +38,6 @@ unique_ptr<GlProgram> GlProgram::gen(std::shared_ptr<GlShader> shader)
 GlProgram::GlProgram(std::shared_ptr<GlShader> shader)
 {
     linkProgram(shader);
-    load();
-
-    for (auto name : gStdAttributes)
-    {
-        getAttributeLocation(name.c_str());
-    }
-    for (auto name : gStdUniforms)
-    {
-        getUniformLocation(name.c_str());
-    }
-
 }
 
 
@@ -93,38 +72,63 @@ void GlProgram::unload()
 
 int32_t GlProgram::getAttributeLocation(const char* name)
 {
-    if (mAttributeBuffer.find(name) != mAttributeBuffer.end())
-    {
-        return mAttributeBuffer[name];
-    }
     GL_CHECK(int32_t location = glGetAttribLocation(mCurrentProgram, name));
-    if (location != -1)
-    {
-        mAttributeBuffer[name] = location;
-    }
     return location;
 }
 
 
 int32_t GlProgram::getUniformLocation(const char* name)
 {
-    if (mUniformBuffer.find(name) != mUniformBuffer.end())
-    {
-        return mUniformBuffer[name];
-    }
     GL_CHECK(int32_t location = glGetUniformLocation(mCurrentProgram, name));
-    if (location != -1)
-    {
-        mUniformBuffer[name] = location;
-    }
     return location;
+}
+
+
+void GlProgram::setUniform1Value(int32_t location, int count, const int* values)
+{
+    GL_CHECK(glUniform1iv(location, count, values));
+}
+
 
+void GlProgram::setUniform2Value(int32_t location, int count, const int* values)
+{
+    GL_CHECK(glUniform2iv(location, count, values));
+}
+
+
+void GlProgram::setUniform3Value(int32_t location, int count, const int* values)
+{
+    GL_CHECK(glUniform3iv(location, count, values));
+}
+
+
+void GlProgram::setUniform4Value(int32_t location, int count, const int* values)
+{
+    GL_CHECK(glUniform4iv(location, count, values));
+}
+
+
+void GlProgram::setUniform1Value(int32_t location, int count, const float* values)
+{
+    GL_CHECK(glUniform1fv(location, count, values));
+}
+
+
+void GlProgram::setUniform2Value(int32_t location, int count, const float* values)
+{
+    GL_CHECK(glUniform2fv(location, count, values));
+}
+
+
+void GlProgram::setUniform3Value(int32_t location, int count, const float* values)
+{
+    GL_CHECK(glUniform3fv(location, count, values));
 }
 
 
-void GlProgram::setUniformValue(int32_t location, float r, float g, float b, float a)
+void GlProgram::setUniform4Value(int32_t location, int count, const float* values)
 {
-    glUniform4f(location, r, g, b, a);
+    GL_CHECK(glUniform4fv(location, count, values));
 }
 
 
old mode 100644 (file)
new mode 100755 (executable)
index ccdb258..730274f
@@ -36,10 +36,17 @@ public:
     ~GlProgram();
 
     void load();
-    void unload();
+    static void unload();
     int32_t getAttributeLocation(const char* name);
     int32_t getUniformLocation(const char* name);
-    void setUniformValue(int32_t location, float r, float g, float b, float a);
+    void setUniform1Value(int32_t location, int count, const int* values);
+    void setUniform2Value(int32_t location, int count, const int* values);
+    void setUniform3Value(int32_t location, int count, const int* values);
+    void setUniform4Value(int32_t location, int count, const int* values);
+    void setUniform1Value(int32_t location, int count, const float* values);
+    void setUniform2Value(int32_t location, int count, const float* values);
+    void setUniform3Value(int32_t location, int count, const float* values);
+    void setUniform4Value(int32_t location, int count, const float* values);
 
 private:
 
@@ -47,8 +54,6 @@ private:
     uint32_t mProgramObj;
     static uint32_t mCurrentProgram;
 
-    static std::map<string, int32_t> mAttributeBuffer;
-    static std::map<string, int32_t> mUniformBuffer;
 };
 
 #endif /* _TVG_GL_PROGRAM_H_ */
diff --git a/src/lib/gl_engine/tvgGlPropertyInterface.cpp b/src/lib/gl_engine/tvgGlPropertyInterface.cpp
new file mode 100755 (executable)
index 0000000..ebb1c57
--- /dev/null
@@ -0,0 +1,83 @@
+#include "tvgGlPropertyInterface.h"
+#include "tvgGlRenderTask.h"
+
+VertexProperty  PropertyInterface::mEmptyProperty;
+
+VertexProperty& PropertyInterface::addProperty(GlRenderTask* rTask, std::shared_ptr<GlProgram> prog, std::string name, uint32_t propFormatSize, VertexProperty::PropertyType propType)
+{
+    std::map<int32_t, VertexProperty>* vertexProperty = nullptr;
+    int32_t id;
+    switch (propType) {
+    case VertexProperty::PropertyType::ATTRIBUTE: {
+        id = prog->getAttributeLocation(name.c_str());
+        vertexProperty = &rTask->getAttributeVertexProperty();
+        break;
+    }
+    case VertexProperty::PropertyType::UNIFORM: {
+        id = prog->getUniformLocation(name.c_str());
+        vertexProperty = &rTask->getUniformVertexProperty();
+        break;
+    }
+    default: break;
+    }
+    if (id != -1)
+    {
+        VertexProperty property = { id, name, propType, VertexProperty::DataType::FLOAT };
+        property.propertyValues.setStride(propFormatSize);
+        if (vertexProperty)
+        {
+            (*vertexProperty)[id] = property;
+            return (*vertexProperty)[id];
+        }
+    }
+    return mEmptyProperty;
+}
+
+
+int32_t PropertyInterface::getPropertyId(GlRenderTask* rTask, std::string name)
+{
+    std::map<int32_t, VertexProperty>& vertexProperty = rTask->getUniformVertexProperty();
+    for (auto& property : vertexProperty)
+    {
+        if (property.second.propertyName == name)
+        {
+            return property.second.propertyId;
+        }
+    }
+    return -1;
+}
+
+
+VertexProperty& PropertyInterface::getProperty(GlRenderTask* rTask, std::string name)
+{
+    std::map<int32_t, VertexProperty>& vertexProperty = rTask->getUniformVertexProperty();
+    for (auto& property : vertexProperty)
+    {
+        if (property.second.propertyName == name)
+        {
+            return property.second;
+        }
+    }
+    return mEmptyProperty;
+}
+
+
+VertexProperty& PropertyInterface::getProperty(GlRenderTask* rTask, int32_t propId)
+{
+    std::map<int32_t, VertexProperty>& vertexProperty = rTask->getUniformVertexProperty();
+    if (vertexProperty.find(propId) != vertexProperty.end())
+    {
+        return vertexProperty[propId];
+    }
+    return mEmptyProperty;
+}
+
+
+void PropertyInterface::clearData(GlRenderTask* rTask)
+{
+    std::map<int32_t, VertexProperty>& vertexProperty = rTask->getUniformVertexProperty();
+    for (auto& prop : vertexProperty)
+    {
+        prop.second.propertyValues.clear();
+    }
+}
diff --git a/src/lib/gl_engine/tvgGlPropertyInterface.h b/src/lib/gl_engine/tvgGlPropertyInterface.h
new file mode 100755 (executable)
index 0000000..c8f309c
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef _TVG_GL_PROPERTY_INTERFACE_H_
+#define _TVG_GL_PROPERTY_INTERFACE_H_
+
+#include "tvgGlRendererProperties.h"
+#include "tvgGlRenderTask.h"
+
+#include <string>
+#include <memory>
+#include <map>
+
+#define ADD_ATTRIBUTE_PROPERTY(var, rtask, prog, varName, formatSize, location) \
+    var = &PropertyInterface::addProperty(rtask, prog, varName, formatSize, VertexProperty::PropertyType::ATTRIBUTE); \
+    if (var->propertyId != -1) \
+        location = var->propertyId
+
+#define ADD_UNIFORM_PROPERTY(var, rtask, prog, varName, formatSize, location) \
+    var = &PropertyInterface::addProperty(rtask, prog, varName, formatSize, VertexProperty::PropertyType::UNIFORM); \
+    if (var->propertyId != -1) \
+        location = var->propertyId
+
+#define FORMAT_SIZE_FLOAT   1
+#define FORMAT_SIZE_VEC_2   2
+#define FORMAT_SIZE_VEC_3   3
+#define FORMAT_SIZE_VEC_4   4
+
+class PropertyInterface
+{
+public:
+    static VertexProperty& addProperty(GlRenderTask* rTask, std::shared_ptr<GlProgram> prog, std::string name, uint32_t propFormatSize, VertexProperty::PropertyType propType);
+    template<typename... Args>
+    static void setProperty(GlRenderTask* rTask, std::string name, float first, Args... args)
+    {
+        VertexProperty& prop = getProperty(rTask, name);
+        if (prop.propertyId == -1)
+        {
+            return;
+        }
+        setProperty(prop.propertyId, first, args...);
+    }
+    template<typename... Args>
+    static void setProperty(GlRenderTask* rTask, int32_t propId, float first, Args... args)
+    {
+        std::map<int32_t, VertexProperty>::iterator itr = rTask->getUniformVertexProperty().find(propId);
+        if (itr->second.propertyId == -1)
+        {
+            return;
+        }
+        VertexProperty& prop = itr->second;
+
+        prop.dataType = VertexProperty::DataType::FLOAT;
+        prop.propertyValues.set(first, args...);
+    }
+    static int32_t getPropertyId(GlRenderTask* rTask, std::string name);
+    static VertexProperty& getProperty(GlRenderTask* rTask, std::string name);
+    static VertexProperty& getProperty(GlRenderTask* rTask, int32_t propId);
+    static void clearData(GlRenderTask* rTask);
+
+private:
+    PropertyInterface() {}
+    static VertexProperty  mEmptyProperty;
+};
+
+
+#endif /* _TVG_GL_PROPERTY_INTERFACE_H_ */
diff --git a/src/lib/gl_engine/tvgGlRenderTask.cpp b/src/lib/gl_engine/tvgGlRenderTask.cpp
new file mode 100755 (executable)
index 0000000..accb957
--- /dev/null
@@ -0,0 +1,267 @@
+#include "tvgGlCommon.h"
+#include "tvgGlShaderSrc.h"
+#include "tvgGlRenderTask.h"
+#include "tvgGlPropertyInterface.h"
+
+#include <memory>
+#include <string>
+#include <GLES2/gl2.h>
+
+
+GlRenderTask::GlRenderTask(RenderTypes renderType, shared_ptr<GlShader> shader)
+{
+    mRenderType = renderType;
+    mProgram = GlProgram::gen(shader);
+    load();
+
+    VertexProperty* prop = nullptr;
+    ADD_ATTRIBUTE_PROPERTY(prop, this, mProgram, "aLocation", FORMAT_SIZE_VEC_4, mLocVertexAttribute);
+}
+
+
+GlRenderTask::RenderTypes GlRenderTask::getRenderType()
+{
+    return mRenderType;
+}
+
+
+void GlRenderTask::load()
+{
+    mProgram->load();
+}
+
+
+void GlRenderTask::unload()
+{
+    GlProgram::unload();
+}
+
+
+std::shared_ptr<GlProgram> GlRenderTask::getProgram()
+{
+    return mProgram;
+}
+
+
+std::map<int32_t, VertexProperty>& GlRenderTask::getAttributeVertexProperty()
+{
+    return mAttributePropertyBuffer;
+}
+
+
+std::map<int32_t, VertexProperty>& GlRenderTask::getUniformVertexProperty()
+{
+    return mUniformPropertyBuffer;
+}
+
+
+int32_t GlRenderTask::getLocationPropertyId() const
+{
+    return mLocVertexAttribute;
+}
+
+
+void GlRenderTask::uploadValues()
+{
+    for (auto& property : mUniformPropertyBuffer)
+    {
+        PropertyValue& propertyVal = property.second.propertyValues;
+        switch (property.second.dataType) {
+            case VertexProperty::DataType::INT: {
+                switch (propertyVal.getStride()) {
+                    case 1:
+                        mProgram->setUniform1Value(property.second.propertyId, propertyVal.getCount(), (const int*)propertyVal.getData());
+                        break;
+                    case 2:
+                        mProgram->setUniform2Value(property.second.propertyId, propertyVal.getCount(), (const int*)propertyVal.getData());
+                        break;
+                    case 3:
+                        mProgram->setUniform3Value(property.second.propertyId, propertyVal.getCount(), (const int*)propertyVal.getData());
+                        break;
+                    case 4:
+                        mProgram->setUniform4Value(property.second.propertyId, propertyVal.getCount(), (const int*)propertyVal.getData());
+                    default: break;
+                }
+                break;
+            }
+            case VertexProperty::DataType::FLOAT: {
+                switch (propertyVal.getStride()) {
+                    case 1:
+                        mProgram->setUniform1Value(property.second.propertyId, propertyVal.getCount(), propertyVal.getData());
+                        break;
+                    case 2:
+                        mProgram->setUniform2Value(property.second.propertyId, propertyVal.getCount(), propertyVal.getData());
+                        break;
+                    case 3:
+                        mProgram->setUniform3Value(property.second.propertyId, propertyVal.getCount(), propertyVal.getData());
+                        break;
+                    case 4:
+                        mProgram->setUniform4Value(property.second.propertyId, propertyVal.getCount(), propertyVal.getData());
+                    default: break;
+                }
+                break;
+            }
+        }
+    }
+}
+
+
+std::shared_ptr<GlColorRenderTask> GlColorRenderTask::gen()
+{
+    return std::make_shared<GlColorRenderTask>();
+}
+
+
+GlColorRenderTask::GlColorRenderTask()
+    :GlRenderTask(GlRenderTask::RenderTypes::RT_Color, GlShader::gen(COLOR_VERT_SHADER, COLOR_FRAG_SHADER))
+{
+    VertexProperty* prop = nullptr;
+    ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "uColor", FORMAT_SIZE_VEC_4, mLocColor);
+}
+
+
+void GlColorRenderTask::setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
+{
+    if (mLocColor != -1)
+    {
+        PropertyInterface::setProperty(this, mLocColor, r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
+    }
+}
+
+
+GlGradientRenderTask::GlGradientRenderTask(GlRenderTask::RenderTypes renderType, std::shared_ptr<GlShader> shader)
+    :GlRenderTask(renderType, shader)
+{
+    VertexProperty* prop = nullptr;
+    ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "uSize", FORMAT_SIZE_VEC_2, mLocPrimitiveSize);
+    ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "uCanvasSize", FORMAT_SIZE_VEC_2, mLocCanvasSize);
+    ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "noise_level", FORMAT_SIZE_FLOAT, mLocNoise);
+    ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "nStops", FORMAT_SIZE_FLOAT, mLocStopCnt);
+    ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "stopPoints", FORMAT_SIZE_FLOAT, mLocStops);
+    ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "stopColors", FORMAT_SIZE_VEC_4, mLocStopColors);
+}
+
+
+void GlGradientRenderTask::setPrimitveSize(float width, float height)
+{
+    if (mLocPrimitiveSize != -1)
+    {
+        PropertyInterface::setProperty(this, mLocPrimitiveSize, width, height);
+    }
+}
+
+
+void GlGradientRenderTask::setCanvasSize(float width, float height)
+{
+    if (mLocCanvasSize != -1)
+    {
+        PropertyInterface::setProperty(this, mLocCanvasSize, width, height);
+    }
+}
+
+
+void GlGradientRenderTask::setNoise(float noise)
+{
+    if (mLocNoise != -1)
+    {
+        PropertyInterface::setProperty(this, mLocNoise, noise);
+    }
+}
+
+
+void GlGradientRenderTask::setStopCount(int32_t count)
+{
+    if (mLocStopCnt != -1)
+    {
+        PropertyInterface::setProperty(this, mLocStopCnt, (float)count);
+    }
+}
+
+void GlGradientRenderTask::setStopColor(int index, float stopVal, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
+{
+    if (index < MAX_GRADIENT_STOPS && mLocStops != -1 && mLocStopColors != -1)
+    {
+        PropertyInterface::setProperty(this, mLocStops, stopVal);
+        PropertyInterface::setProperty(this, mLocStopColors, r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
+    }
+}
+
+
+std::shared_ptr<GlLinearGradientRenderTask> GlLinearGradientRenderTask::gen()
+{
+    return std::make_shared<GlLinearGradientRenderTask>();
+}
+
+
+GlLinearGradientRenderTask::GlLinearGradientRenderTask()
+    :GlGradientRenderTask(GlRenderTask::RenderTypes::RT_LinGradient, GlShader::gen(GRADIENT_VERT_SHADER, LINEAR_GRADIENT_FRAG_SHADER))
+{
+    VertexProperty* prop = nullptr;
+    ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "gradStartPos", FORMAT_SIZE_VEC_2, mLocStartPos);
+    ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "gradEndPos", FORMAT_SIZE_VEC_2, mLocEndPos);
+}
+
+
+void GlLinearGradientRenderTask::setStartPosition(float posX, float posY)
+{
+    if (mLocStartPos != -1)
+    {
+        PropertyInterface::setProperty(this, mLocStartPos, posX, posY);
+    }
+}
+
+
+void GlLinearGradientRenderTask::setEndPosition(float posX, float posY)
+{
+    if (mLocEndPos != -1)
+    {
+        PropertyInterface::setProperty(this, mLocEndPos, posX, posY);
+    }
+}
+
+
+std::shared_ptr<GlRadialGradientRenderTask> GlRadialGradientRenderTask::gen()
+{
+    return std::make_shared<GlRadialGradientRenderTask>();
+}
+
+
+GlRadialGradientRenderTask::GlRadialGradientRenderTask()
+    :GlGradientRenderTask(GlRenderTask::RenderTypes::RT_RadGradient, GlShader::gen(GRADIENT_VERT_SHADER, RADIAL_GRADIENT_FRAG_SHADER))
+{
+    VertexProperty* prop = nullptr;
+    ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "gradStartPos", FORMAT_SIZE_VEC_2, mLocStartPos);
+    ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "stRadius", FORMAT_SIZE_FLOAT, mLocStRadius);
+}
+
+
+GlRadialGradientRenderTask::~GlRadialGradientRenderTask()
+{
+}
+
+
+void GlRadialGradientRenderTask::setStartPosition(float posX, float posY)
+{
+    if (mLocStartPos != -1)
+    {
+        PropertyInterface::setProperty(this, mLocStartPos, posX, posY);
+    }
+}
+
+
+void GlRadialGradientRenderTask::setStartRadius(float radius)
+{
+    if (mLocStRadius != -1)
+    {
+        PropertyInterface::setProperty(this, mLocStRadius, radius);
+    }
+}
+
+
+void GlRadialGradientRenderTask::setEndRadius(float radius)
+{
+    if (mLocEdRadius != -1)
+    {
+        PropertyInterface::setProperty(this, mLocEdRadius, radius);
+    }
+}
diff --git a/src/lib/gl_engine/tvgGlRenderTask.h b/src/lib/gl_engine/tvgGlRenderTask.h
new file mode 100755 (executable)
index 0000000..d4b28e5
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef _TVG_GL_RENDER_TASK_H_
+#define _TVG_GL_RENDER_TASK_H_
+
+#include "tvgGlShader.h"
+#include "tvgGlProgram.h"
+#include "tvgGlRendererProperties.h"
+
+#include <string>
+#include <memory>
+#include <map>
+
+#define MAX_GRADIENT_STOPS 4
+
+class GlRenderTask
+{
+public:
+    enum RenderTypes
+    {
+        RT_Color = 0,
+        RT_LinGradient,
+        RT_RadGradient,
+
+        RT_None,
+    };
+
+    GlRenderTask(RenderTypes renderType, std::shared_ptr<GlShader> shader);
+    RenderTypes getRenderType();
+
+    void load();
+    static void unload();
+    std::shared_ptr<GlProgram> getProgram();
+    std::map<int32_t, VertexProperty>& getAttributeVertexProperty();
+    std::map<int32_t, VertexProperty>& getUniformVertexProperty();
+    int32_t getLocationPropertyId() const;
+    void uploadValues();
+
+private:
+    RenderTypes mRenderType;
+
+    uint32_t    propertyFormatSize;
+    std::shared_ptr<GlProgram> mProgram;
+    std::map<int32_t, VertexProperty> mAttributePropertyBuffer;
+    std::map<int32_t, VertexProperty> mUniformPropertyBuffer;
+
+    int32_t mLocVertexAttribute;
+};
+
+class GlColorRenderTask : public GlRenderTask
+{
+public:
+    static std::shared_ptr<GlColorRenderTask> gen();
+    GlColorRenderTask();
+    void setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
+
+private:
+    int32_t mLocColor = -1;
+};
+
+class GlGradientRenderTask : public GlRenderTask
+{
+public:
+    GlGradientRenderTask(GlRenderTask::RenderTypes renderType, std::shared_ptr<GlShader> shader);
+    void setPrimitveSize(float width, float height);
+    void setCanvasSize(float width, float height);
+    void setNoise(float noise);
+    void setStopCount(int32_t count);
+    void setStopColor(int index, float stopVal, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
+
+private:
+    int32_t mLocPrimitiveSize = -1;
+    int32_t mLocCanvasSize = -1;
+    int32_t mLocNoise = -1;
+    int32_t mLocStopCnt = -1;
+    int32_t mLocStops;
+    int32_t mLocStopColors;
+};
+
+class GlLinearGradientRenderTask : public GlGradientRenderTask
+{
+public:
+    static std::shared_ptr<GlLinearGradientRenderTask> gen();
+    GlLinearGradientRenderTask();
+    void setStartPosition(float posX, float posY);
+    void setEndPosition(float posX, float posY);
+
+private:
+    int32_t mLocStartPos = -1;
+    int32_t mLocEndPos = -1;
+};
+
+class GlRadialGradientRenderTask : public GlGradientRenderTask
+{
+public:
+    static std::shared_ptr<GlRadialGradientRenderTask> gen();
+    GlRadialGradientRenderTask();
+    ~GlRadialGradientRenderTask();
+    void setStartPosition(float posX, float posY);
+    void setStartRadius(float radius);
+    void setEndRadius(float radius);
+
+private:
+    int32_t mLocStartPos = -1;
+    int32_t mLocStRadius = -1;
+    int32_t mLocEdRadius = -1;
+};
+
+
+#endif /* _TVG_GL_RENDER_TASK_H_ */
old mode 100644 (file)
new mode 100755 (executable)
index 9e9f8ef..266902a
@@ -24,6 +24,7 @@
 #include "tvgGlGeometry.h"
 #include "tvgGlCommon.h"
 #include "tvgGlRenderer.h"
+#include "tvgGlPropertyInterface.h"
 
 /************************************************************************/
 /* Internal Class Implementation                                        */
@@ -42,6 +43,8 @@ static void _termEngine()
 /* External Class Implementation                                        */
 /************************************************************************/
 
+#define NOISE_LEVEL 0.5f
+
 bool GlRenderer::clear()
 {
     //TODO: (Request) to clear target
@@ -65,16 +68,21 @@ bool GlRenderer::target(TVG_UNUSED uint32_t* buffer, uint32_t stride, uint32_t w
 bool GlRenderer::flush()
 {
     GL_CHECK(glFinish());
-    mColorProgram->unload();
-
+    GlRenderTask::unload();
     return true;
 }
 
 
 bool GlRenderer::preRender()
 {
-    // Blend function for pre multiplied alpha
-    GL_CHECK(glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
+    if (mRenderTasks.size() == 0)
+    {
+        initShaders();
+    }
+    GlRenderTask::unload();
+
+    // Blend function for straight alpha
+    GL_CHECK(glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
     GL_CHECK(glEnable(GL_BLEND));
     return true;
 }
@@ -98,19 +106,23 @@ bool GlRenderer::render(const Shape& shape, void *data)
 
     GL_CHECK(glViewport(0, 0, sdata->viewWd, sdata->viewHt));
 
-    uint32_t geometryCnt = sdata->geometry->getPrimitiveCount();
-    for (uint32_t i = 0; i < geometryCnt; ++i)
+    uint32_t primitiveCount = sdata->geometry->getPrimitiveCount();
+    for (uint32_t i = 0; i < primitiveCount; ++i)
     {
-        mColorProgram->load();
-        if (flags & RenderUpdateFlag::Color)
+        if (flags & RenderUpdateFlag::Gradient)
+        {
+            const Fill* gradient = shape.fill();
+            drawPrimitive(*sdata, gradient, i, RenderUpdateFlag::Gradient);
+        }
+        else if (flags & RenderUpdateFlag::Color)
         {
             shape.fill(&r, &g, &b, &a);
-            drawPrimitive(*(sdata->geometry), (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, (float)a / 255.0f, i, RenderUpdateFlag::Color);
+            drawPrimitive(*sdata, r, g, b, a, i, RenderUpdateFlag::Color);
         }
         if (flags & RenderUpdateFlag::Stroke)
         {
             shape.strokeColor(&r, &g, &b, &a);
-            drawPrimitive(*(sdata->geometry), (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, (float)a / 255.0f, i, RenderUpdateFlag::Stroke);
+            drawPrimitive(*sdata, r, g, b, a, i, RenderUpdateFlag::Stroke);
         }
     }
 
@@ -143,8 +155,6 @@ void* GlRenderer::prepare(const Shape& shape, void* data, TVG_UNUSED const Rende
 
     if (sdata->updateFlag == RenderUpdateFlag::None) return sdata;
 
-    initShaders();
-
     sdata->geometry = make_unique<GlGeometry>();
 
     //invisible?
@@ -153,9 +163,14 @@ void* GlRenderer::prepare(const Shape& shape, void* data, TVG_UNUSED const Rende
     shape.strokeColor(nullptr, nullptr, nullptr, &alphaS);
     auto strokeWd = shape.strokeWidth();
 
-    if (alphaF == 0 && alphaS == 0) return sdata;
+    if ( ((sdata->updateFlag & RenderUpdateFlag::Gradient) == 0) &&
+         ((sdata->updateFlag & RenderUpdateFlag::Color) && alphaF == 0) &&
+         ((sdata->updateFlag & RenderUpdateFlag::Stroke) && alphaS == 0) )
+    {
+        return sdata;
+    }
 
-    if (sdata->updateFlag & (RenderUpdateFlag::Color | RenderUpdateFlag::Stroke) )
+    if (sdata->updateFlag & (RenderUpdateFlag::Color | RenderUpdateFlag::Stroke | RenderUpdateFlag::Gradient) )
     {
         if (!sdata->geometry->decomposeOutline(shape)) return sdata;
         if (!sdata->geometry->generateAAPoints(shape, static_cast<float>(strokeWd), sdata->updateFlag)) return sdata;
@@ -198,10 +213,7 @@ GlRenderer* GlRenderer::gen()
 
 GlRenderer::~GlRenderer()
 {
-    if (mColorProgram.get())
-    {
-        mColorProgram.reset(nullptr);
-    }
+    mRenderTasks.clear();
 
     --rendererCnt;
     if (!initEngine) _termEngine();
@@ -210,21 +222,85 @@ GlRenderer::~GlRenderer()
 
 void GlRenderer::initShaders()
 {
-    if (!mColorProgram.get())
-    {
-        shared_ptr<GlShader> shader = GlShader::gen(COLOR_VERT_SHADER, COLOR_FRAG_SHADER);
-        mColorProgram = GlProgram::gen(shader);
-    }
-    mColorProgram->load();
-    mColorUniformLoc = mColorProgram->getUniformLocation("uColor");
-    mVertexAttrLoc = mColorProgram->getAttributeLocation("aLocation");
+    // Solid Color Renderer
+    mRenderTasks.push_back(GlColorRenderTask::gen());
+
+    // Linear Gradient Renderer
+    mRenderTasks.push_back(GlLinearGradientRenderTask::gen());
+
+    // Radial Gradient Renderer
+    mRenderTasks.push_back(GlRadialGradientRenderTask::gen());
 }
 
 
-void GlRenderer::drawPrimitive(GlGeometry& geometry, float r, float g, float b, float a, uint32_t primitiveIndex, RenderUpdateFlag flag)
+void GlRenderer::drawPrimitive(GlShape& sdata, uint8_t r, uint8_t g, uint8_t b, uint8_t a, uint32_t primitiveIndex, RenderUpdateFlag flag)
 {
-    mColorProgram->setUniformValue(mColorUniformLoc, r, g, b, a);
-    geometry.draw(mVertexAttrLoc, primitiveIndex, flag);
-    geometry.disableVertex(mVertexAttrLoc);
+    GlColorRenderTask* renderTask = static_cast<GlColorRenderTask*>(mRenderTasks[GlRenderTask::RenderTypes::RT_Color].get());
+    assert(renderTask);
+    renderTask->load();
+    PropertyInterface::clearData(renderTask);
+    renderTask->setColor(r, g, b, a);
+    int32_t vertexLoc = renderTask->getLocationPropertyId();
+    renderTask->uploadValues();
+    sdata.geometry->draw(vertexLoc, primitiveIndex, flag);
+    sdata.geometry->disableVertex(vertexLoc);
+
+}
+
+
+void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, uint32_t primitiveIndex, RenderUpdateFlag flag)
+{
+    const Fill::ColorStop* stops = nullptr;
+    auto stopCnt = fill->colorStops(&stops);
+    if (stopCnt < 2)
+    {
+        return;
+    }
+    GlGradientRenderTask* rTask = nullptr;
+    GlSize size = sdata.geometry->getPrimitiveSize(primitiveIndex);
+    switch (fill->id()) {
+        case FILL_ID_LINEAR: {
+            float x1, y1, x2, y2;
+            GlLinearGradientRenderTask *renderTask = static_cast<GlLinearGradientRenderTask*>(mRenderTasks[GlRenderTask::RenderTypes::RT_LinGradient].get());
+            assert(renderTask);
+            rTask = renderTask;
+            renderTask->load();
+            PropertyInterface::clearData(renderTask);
+            const LinearGradient* grad = static_cast<const LinearGradient*>(fill);
+            grad->linear(&x1, &y1, &x2, &y2);
+            renderTask->setStartPosition(x1, y1);
+            renderTask->setEndPosition(x2, y2);
+            break;
+        }
+        case FILL_ID_RADIAL: {
+            float x1, y1, r1;
+            GlRadialGradientRenderTask *renderTask = static_cast<GlRadialGradientRenderTask*>(mRenderTasks[GlRenderTask::RenderTypes::RT_RadGradient].get());
+            assert(renderTask);
+            rTask = renderTask;
+            renderTask->load();
+            PropertyInterface::clearData(renderTask);
+            const RadialGradient* grad = static_cast<const RadialGradient*>(fill);
+            grad->radial(&x1, &y1, &r1);
+            renderTask->setStartPosition(x1, y1);
+            renderTask->setStartRadius(r1);
+            break;
+        }
+    }
+    if (rTask)
+    {
+        int32_t vertexLoc = rTask->getLocationPropertyId();
+        rTask->setPrimitveSize(size.x, size.y);
+        rTask->setCanvasSize(sdata.viewWd, sdata.viewHt);
+        rTask->setNoise(NOISE_LEVEL);
+        rTask->setStopCount((int)stopCnt);
+        for (uint32_t i = 0; i < stopCnt; ++i)
+        {
+            rTask->setStopColor(i, stops[i].offset, stops[i].r, stops[i].g, stops[i].b, stops[i].a);
+        }
+
+        rTask->uploadValues();
+        sdata.geometry->draw(vertexLoc, primitiveIndex, flag);
+        sdata.geometry->disableVertex(vertexLoc);
+    }
+}
 
-}
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index a0f5715..79addd6
@@ -25,7 +25,7 @@
 
 #include "tvgGlCommon.h"
 #include "tvgGlProgram.h"
-
+#include "tvgGlRenderTask.h"
 
 class GlRenderer : public RenderMethod
 {
@@ -50,11 +50,10 @@ private:
     ~GlRenderer();
 
     void initShaders();
-    void drawPrimitive(GlGeometry& geometry, float r, float g, float b, float a, uint32_t primitiveIndex, RenderUpdateFlag flag);
+    void drawPrimitive(GlShape& sdata, uint8_t r, uint8_t g, uint8_t b, uint8_t a, uint32_t primitiveIndex, RenderUpdateFlag flag);
+    void drawPrimitive(GlShape& sdata, const Fill* fill, uint32_t primitiveIndex, RenderUpdateFlag flag);
 
-    unique_ptr<GlProgram>   mColorProgram = nullptr;
-    int32_t   mColorUniformLoc = 0;
-    uint32_t  mVertexAttrLoc = 0;
+    vector<shared_ptr<GlRenderTask>>  mRenderTasks;
 };
 
 #endif /* _TVG_GL_RENDERER_H_ */
diff --git a/src/lib/gl_engine/tvgGlRendererProperties.h b/src/lib/gl_engine/tvgGlRendererProperties.h
new file mode 100755 (executable)
index 0000000..dd00923
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef _TVG_GL_RENDER_PROPERTIES_H_
+#define _TVG_GL_RENDER_PROPERTIES_H_
+
+#include "tvgGlShader.h"
+#include "tvgGlProgram.h"
+
+#include <string>
+#include <memory>
+#include <vector>
+#include <map>
+
+class PropertyValue
+{
+public:
+    void setStride(uint32_t s)
+    {
+        stride = s;
+        if (values.capacity() == values.size())
+        {
+            values.reserve(values.size() + stride);
+        }
+    }
+
+    uint32_t getStride() const
+    {
+        return stride;
+    }
+
+    uint32_t getSize() const
+    {
+        return values.size();
+    }
+
+    uint32_t getCount() const
+    {
+        return (values.size() / stride);
+    }
+
+    void clear()
+    {
+        values.clear();
+    }
+
+    const float* getData()
+    {
+        return values.data();
+    }
+
+    void set(float v)
+    {
+        values.push_back(v);
+    }
+
+    template<typename... Args>
+    void set(float first, Args... args)
+    {
+        if (values.capacity() == values.size())
+        {
+            values.reserve(values.size() + stride);
+        }
+        set(first);
+        set(args...);
+    }
+
+private:
+    std::vector<float> values;
+    uint32_t stride = 0;
+};
+
+struct VertexProperty
+{
+public:
+    enum class DataType
+    {
+        INT = 0,
+        FLOAT
+    };
+    enum class PropertyType
+    {
+        ATTRIBUTE = 0,
+        UNIFORM
+    };
+
+    int32_t propertyId = -1;
+    std::string propertyName = "";
+    PropertyType propType = PropertyType::UNIFORM;
+    DataType dataType = DataType::FLOAT;
+    PropertyValue propertyValues;
+};
+
+
+#endif /* _TVG_GL_RENDER_PROPERTIES_H_ */
old mode 100644 (file)
new mode 100755 (executable)
index 135ef43..91c31de
 
 #include "tvgGlShaderSrc.h"
 
-const char* COLOR_VERT_SHADER =
-"attribute highp vec4 aLocation;                \n"
-"uniform highp vec4 uColor;                     \n"
-"varying highp vec4 vcolor;                     \n"
-"varying highp float vOpacity;                  \n"
-"void main()                                    \n"
-"{                                              \n"
-"   gl_Position = vec4(aLocation.xy, 0.0, 1.0); \n"
-"   vcolor = uColor;                            \n"
-"   vOpacity = aLocation.z;                     \n"
-"}                                              \n";
-
-const char* COLOR_FRAG_SHADER =
-"varying highp vec4 vcolor;                             \n"
-"varying highp float vOpacity;                          \n"
-"void main()                                            \n"
-"{                                                      \n"
-"  gl_FragColor = vec4(vcolor.xyz, vcolor.w*vOpacity);  \n"
-"}                                                      \n";
+#include <string>
 
+#define TVG_COMPOSE_SHADER(shader) #shader
+
+const char* COLOR_VERT_SHADER = TVG_COMPOSE_SHADER(
+    attribute mediump vec4 aLocation;                  \n
+    varying highp float vOpacity;                      \n
+    void main()                                        \n
+    {                                                  \n
+        gl_Position = vec4(aLocation.xy, 0.0, 1.0);    \n
+        vOpacity = aLocation.z;                        \n
+    });
+
+const char* COLOR_FRAG_SHADER = TVG_COMPOSE_SHADER(
+    uniform highp vec4 uColor;                               \n
+    varying highp float vOpacity;                            \n
+    void main()                                              \n
+    {                                                        \n
+       gl_FragColor = vec4(uColor.xyz, uColor.w*vOpacity);   \n
+    });
+
+const char* GRADIENT_VERT_SHADER = TVG_COMPOSE_SHADER(
+attribute highp vec4 aLocation;                                                 \n
+varying highp float vOpacity;                                                   \n
+varying highp vec2 vPos;                                                        \n
+                                                                                \n
+void main()                                                                     \n
+{                                                                               \n
+    gl_Position = vec4(aLocation.xy, 0.0, 1.0);                                 \n
+    vOpacity = aLocation.z;                                                     \n
+    vPos = vec2((aLocation.x + 1.0) / 2.0, ((-1.0 * aLocation.y) +1.0) / 2.0);  \n
+});
+
+
+std::string STR_GRADIENT_FRAG_COMMON_VARIABLES = TVG_COMPOSE_SHADER(
+precision highp float;                                                                                  \n
+const int MAX_STOP_COUNT = 4;                                                                           \n
+uniform highp vec2 uSize;                                                                               \n
+uniform highp vec2 uCanvasSize;                                                                         \n
+uniform float nStops;                                                                                  \n
+uniform float noise_level;                                                                              \n
+uniform float stopPoints[MAX_STOP_COUNT];                                                               \n
+uniform vec4 stopColors[MAX_STOP_COUNT];                                                                \n
+varying highp vec2 vPos;                                                                                \n
+varying highp float vOpacity;                                                                           \n
+);
+
+std::string STR_GRADIENT_FRAG_COMMON_FUNCTIONS = TVG_COMPOSE_SHADER(
+float gradientStep(float edge0, float edge1, float x)                                                   \n
+{                                                                                                       \n
+    // linear                                                                                           \n
+    x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);                                                 \n
+    return x;                                                                                           \n
+}                                                                                                       \n
+                                                                                                        \n
+vec4 gradient(float t)                                                                                  \n
+{                                                                                                       \n
+    vec4 col = vec4(0.0);                                                                               \n
+    int i = 0;                                                                                          \n
+    int count = int(nStops);                                                                            \n
+    if (t <= stopPoints[0])                                                                              \n
+    {                                                                                                   \n
+        col += stopColors[0];                                                                           \n
+    }                                                                                                   \n
+    else if (t >= stopPoints[count - 1])                                                                 \n
+    {                                                                                                   \n
+        col += stopColors[count - 1];                                                                   \n
+    }                                                                                                   \n
+    else                                                                                                \n
+    {                                                                                                   \n
+        for (i = 0; i < count - 1; ++i)                                                                 \n
+        {                                                                                               \n
+            if (t > stopPoints[i] && t < stopPoints[i + 1])                                            \n
+            {                                                                                           \n
+                col += (stopColors[i] * (1. - gradientStep(stopPoints[i], stopPoints[i + 1], t)));      \n
+                col += (stopColors[i + 1] * gradientStep(stopPoints[i], stopPoints[i + 1], t));         \n
+                break;                                                                                  \n
+            }                                                                                           \n
+        }                                                                                               \n
+    }                                                                                                   \n
+                                                                                                        \n
+    return col;                                                                                         \n
+}                                                                                                       \n
+                                                                                                        \n
+highp vec3 ScreenSpaceDither(vec2 vScreenPos)                                                           \n
+{                                                                                                       \n
+    highp vec3 vDither = vec3(dot(vec2(171.0, 231.0), vScreenPos.xy));                                  \n
+    vDither.rgb = fract(vDither.rgb / vec3(103.0, 71.0, 97.0));                                         \n
+    return vDither.rgb / 255.0;                                                                         \n
+});
+
+std::string STR_LINEAR_GRADIENT_VARIABLES = TVG_COMPOSE_SHADER(
+uniform highp vec2 gradStartPos;                                                                        \n
+uniform highp vec2 gradEndPos;                                                                          \n
+);
+
+std::string STR_LINEAR_GRADIENT_MAIN = TVG_COMPOSE_SHADER(
+void main()                                                                                             \n
+{                                                                                                       \n
+    highp vec2 pos = vec2(vPos.x * uCanvasSize.x, vPos.y * uCanvasSize.y);                              \n
+    highp vec2 spos = vec2(pos.x / uSize.x, pos.y / uSize.y);                                           \n
+    highp vec2 st = gradStartPos / (uSize.xy);                                                          \n
+    highp vec2 ed = gradEndPos / (uSize.xy);                                                            \n
+                                                                                                        \n
+    highp vec2 ba = ed - st;                                                                            \n
+                                                                                                        \n
+    highp float t = dot(spos - st, ba) / dot(ba, ba);                                                   \n
+                                                                                                        \n
+    //t = smoothstep(0.0, 1.0, clamp(t, 0.0, 1.0));                                                     \n
+    t = clamp(t, 0.0, 1.0);                                                                             \n
+                                                                                                        \n
+    vec4 color = gradient(t);                                                                           \n
+                                                                                                        \n
+    highp vec3 noise = 8.0 * noise_level * ScreenSpaceDither(pos);                                      \n
+    vec4 finalCol = vec4(color.xyz + noise, color.w);                                                   \n
+    gl_FragColor = vec4(finalCol.xyz, finalCol.w* vOpacity);                                            \n
+});
+
+std::string STR_RADIAL_GRADIENT_VARIABLES = TVG_COMPOSE_SHADER(
+    uniform highp vec2 gradStartPos;                                                                    \n
+    uniform highp float stRadius;                                                                       \n
+);
+
+std::string STR_RADIAL_GRADIENT_MAIN = TVG_COMPOSE_SHADER(
+void main()                                                                                             \n
+{                                                                                                       \n
+    highp vec2 pos = vec2(vPos.x * uCanvasSize.x, vPos.y * uCanvasSize.y);                              \n
+    highp vec2 spos = vec2(pos.x / uSize.x, pos.y / uSize.y);                                           \n
+                                                                                                        \n
+    highp float ba = stRadius;                                                                          \n
+    highp float d = distance(gradStartPos, pos);                                                        \n
+    d = (d / ba);                                                                                       \n
+                                                                                                        \n
+    //float t = smoothstep(0.0, 1.0, clamp(d, 0.0, 1.0));                                               \n
+    float t = clamp(d, 0.0, 1.0);                                                                       \n
+                                                                                                        \n
+    vec4 color = gradient(t);                                                                           \n
+                                                                                                        \n
+    highp vec3 noise = 8.0 * noise_level * ScreenSpaceDither(pos);                                      \n
+    vec4 finalCol = vec4(color.xyz + noise, color.w);                                                   \n
+    gl_FragColor = vec4(finalCol.xyz, finalCol.w * vOpacity);                                           \n
+});
+
+std::string STR_LINEAR_GRADIENT_FRAG_SHADER =
+STR_GRADIENT_FRAG_COMMON_VARIABLES +
+STR_LINEAR_GRADIENT_VARIABLES +
+STR_GRADIENT_FRAG_COMMON_FUNCTIONS +
+STR_LINEAR_GRADIENT_MAIN;
+
+const char* LINEAR_GRADIENT_FRAG_SHADER = STR_LINEAR_GRADIENT_FRAG_SHADER.c_str();
+
+std::string STR_RADIAL_GRADIENT_FRAG_SHADER =
+STR_GRADIENT_FRAG_COMMON_VARIABLES +
+STR_RADIAL_GRADIENT_VARIABLES +
+STR_GRADIENT_FRAG_COMMON_FUNCTIONS +
+STR_RADIAL_GRADIENT_MAIN;
+
+const char* RADIAL_GRADIENT_FRAG_SHADER = STR_RADIAL_GRADIENT_FRAG_SHADER.c_str();
old mode 100644 (file)
new mode 100755 (executable)
index 2299354..cc91910
@@ -25,5 +25,8 @@
 
 extern const char* COLOR_VERT_SHADER;
 extern const char* COLOR_FRAG_SHADER;
+extern const char* GRADIENT_VERT_SHADER;
+extern const char* LINEAR_GRADIENT_FRAG_SHADER;
+extern const char* RADIAL_GRADIENT_FRAG_SHADER;
 
 #endif /* _TVG_GL_SHADERSRC_H_ */
old mode 100644 (file)
new mode 100755 (executable)
index 235bacb..b425da0
@@ -67,7 +67,7 @@ Result GlCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t
     auto renderer = static_cast<GlRenderer*>(Canvas::pImpl.get()->renderer);
     if (!renderer) return Result::MemoryCorruption;
 
-    if (!renderer->target(buffer, stride, w, h, 0)) return Result::Unknown;
+    if (!renderer->target(buffer, stride, w, h)) return Result::Unknown;
 
     return Result::Success;
 #endif