Support CHROMIUM_path_rendering
This is partial support for CHROMIUM_path_rendering
and implements basic path management and non-instanced
rendering.
BUG=angleproject:1382
Change-Id: I9c0e88183e0a915d522889323933439d25b45b5f
Reviewed-on: https://chromium-review.googlesource.com/348630
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 2ab9f3a..2559657 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -11,7 +11,9 @@
#include <iterator>
#include <sstream>
+#include <string.h>
+#include "common/matrix_utils.h"
#include "common/platform.h"
#include "common/utilities.h"
#include "libANGLE/Buffer.h"
@@ -20,6 +22,7 @@
#include "libANGLE/Fence.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Path.h"
#include "libANGLE/Program.h"
#include "libANGLE/Query.h"
#include "libANGLE/Renderbuffer.h"
@@ -437,6 +440,17 @@
return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
}
+GLuint Context::createPaths(GLsizei range)
+{
+ auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
+ if (resultOrError.isError())
+ {
+ handleError(resultOrError.getError());
+ return 0;
+ }
+ return resultOrError.getResult();
+}
+
GLuint Context::createVertexArray()
{
GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
@@ -534,6 +548,96 @@
mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
}
+void Context::deletePaths(GLuint first, GLsizei range)
+{
+ mResourceManager->deletePaths(first, range);
+}
+
+bool Context::hasPathData(GLuint path) const
+{
+ const auto *pathObj = mResourceManager->getPath(path);
+ if (pathObj == nullptr)
+ return false;
+
+ return pathObj->hasPathData();
+}
+
+bool Context::hasPath(GLuint path) const
+{
+ return mResourceManager->hasPath(path);
+}
+
+void Context::setPathCommands(GLuint path,
+ GLsizei numCommands,
+ const GLubyte *commands,
+ GLsizei numCoords,
+ GLenum coordType,
+ const void *coords)
+{
+ auto *pathObject = mResourceManager->getPath(path);
+
+ handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
+}
+
+void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
+{
+ auto *pathObj = mResourceManager->getPath(path);
+
+ switch (pname)
+ {
+ case GL_PATH_STROKE_WIDTH_CHROMIUM:
+ pathObj->setStrokeWidth(value);
+ break;
+ case GL_PATH_END_CAPS_CHROMIUM:
+ pathObj->setEndCaps(static_cast<GLenum>(value));
+ break;
+ case GL_PATH_JOIN_STYLE_CHROMIUM:
+ pathObj->setJoinStyle(static_cast<GLenum>(value));
+ break;
+ case GL_PATH_MITER_LIMIT_CHROMIUM:
+ pathObj->setMiterLimit(value);
+ break;
+ case GL_PATH_STROKE_BOUND_CHROMIUM:
+ pathObj->setStrokeBound(value);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
+{
+ const auto *pathObj = mResourceManager->getPath(path);
+
+ switch (pname)
+ {
+ case GL_PATH_STROKE_WIDTH_CHROMIUM:
+ *value = pathObj->getStrokeWidth();
+ break;
+ case GL_PATH_END_CAPS_CHROMIUM:
+ *value = static_cast<GLfloat>(pathObj->getEndCaps());
+ break;
+ case GL_PATH_JOIN_STYLE_CHROMIUM:
+ *value = static_cast<GLfloat>(pathObj->getJoinStyle());
+ break;
+ case GL_PATH_MITER_LIMIT_CHROMIUM:
+ *value = pathObj->getMiterLimit();
+ break;
+ case GL_PATH_STROKE_BOUND_CHROMIUM:
+ *value = pathObj->getStrokeBound();
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ mGLState.setPathStencilFunc(func, ref, mask);
+}
+
void Context::deleteVertexArray(GLuint vertexArray)
{
auto iter = mVertexArrayMap.find(vertexArray);
@@ -1016,6 +1120,16 @@
case GL_MAX_TEXTURE_LOD_BIAS:
*params = mCaps.maxLODBias;
break;
+
+ case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
+ case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
+ {
+ ASSERT(mExtensions.pathRendering);
+ const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
+ memcpy(params, m, 16 * sizeof(GLfloat));
+ }
+ break;
+
default:
mGLState.getFloatv(pname, params);
break;
@@ -1269,6 +1383,94 @@
mGLState.setCoverageModulation(components);
}
+void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
+{
+ mGLState.loadPathRenderingMatrix(matrixMode, matrix);
+}
+
+void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
+{
+ GLfloat I[16];
+ angle::Matrix<GLfloat>::setToIdentity(I);
+
+ mGLState.loadPathRenderingMatrix(matrixMode, I);
+}
+
+void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
+{
+ const auto *pathObj = mResourceManager->getPath(path);
+ if (!pathObj)
+ return;
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
+
+ mImplementation->stencilFillPath(pathObj, fillMode, mask);
+}
+
+void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
+{
+ const auto *pathObj = mResourceManager->getPath(path);
+ if (!pathObj)
+ return;
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
+
+ mImplementation->stencilStrokePath(pathObj, reference, mask);
+}
+
+void Context::coverFillPath(GLuint path, GLenum coverMode)
+{
+ const auto *pathObj = mResourceManager->getPath(path);
+ if (!pathObj)
+ return;
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
+
+ mImplementation->coverFillPath(pathObj, coverMode);
+}
+
+void Context::coverStrokePath(GLuint path, GLenum coverMode)
+{
+ const auto *pathObj = mResourceManager->getPath(path);
+ if (!pathObj)
+ return;
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
+
+ mImplementation->coverStrokePath(pathObj, coverMode);
+}
+
+void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
+{
+ const auto *pathObj = mResourceManager->getPath(path);
+ if (!pathObj)
+ return;
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
+
+ mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
+}
+
+void Context::stencilThenCoverStrokePath(GLuint path,
+ GLint reference,
+ GLuint mask,
+ GLenum coverMode)
+{
+ const auto *pathObj = mResourceManager->getPath(path);
+ if (!pathObj)
+ return;
+
+ // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
+ syncRendererState();
+
+ mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
+}
+
void Context::handleError(const Error &error)
{
if (error.isError())