aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLPath.cpp101
-rw-r--r--src/gpu/gl/GrGLPath.h43
-rw-r--r--src/gpu/gl/GrGpuGL.cpp21
-rw-r--r--src/gpu/gl/GrGpuGL.h10
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp13
5 files changed, 174 insertions, 14 deletions
diff --git a/src/gpu/gl/GrGLPath.cpp b/src/gpu/gl/GrGLPath.cpp
new file mode 100644
index 0000000000..2fceaa3209
--- /dev/null
+++ b/src/gpu/gl/GrGLPath.cpp
@@ -0,0 +1,101 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLPath.h"
+#include "GrGpuGL.h"
+
+#define GPUGL static_cast<GrGpuGL*>(this->getGpu())
+
+#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
+#define GL_CALL_RET(R, X) GR_GL_CALL_RET(GPUGL->glInterface(), R, X)
+
+namespace {
+inline GrGLubyte verb_to_gl_path_cmd(const SkPath::Verb verb) {
+ static const GrGLubyte gTable[] = {
+ GR_GL_MOVE_TO,
+ GR_GL_LINE_TO,
+ GR_GL_QUADRATIC_CURVE_TO,
+ GR_GL_CUBIC_CURVE_TO,
+ GR_GL_CLOSE_PATH,
+ };
+ GR_STATIC_ASSERT(0 == SkPath::kMove_Verb);
+ GR_STATIC_ASSERT(1 == SkPath::kLine_Verb);
+ GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb);
+ GR_STATIC_ASSERT(3 == SkPath::kCubic_Verb);
+ GR_STATIC_ASSERT(4 == SkPath::kClose_Verb);
+
+ GrAssert(verb >= 0 && verb < GR_ARRAY_COUNT(gTable));
+ return gTable[verb];
+}
+
+inline int num_pts(const SkPath::Verb verb) {
+ static const int gTable[] = {
+ 1, // move
+ 1, // line
+ 2, // quad
+ 3, // cubic
+ 0, // close
+ };
+ GR_STATIC_ASSERT(0 == SkPath::kMove_Verb);
+ GR_STATIC_ASSERT(1 == SkPath::kLine_Verb);
+ GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb);
+ GR_STATIC_ASSERT(3 == SkPath::kCubic_Verb);
+ GR_STATIC_ASSERT(4 == SkPath::kClose_Verb);
+
+ GrAssert(verb >= 0 && verb < GR_ARRAY_COUNT(gTable));
+ return gTable[verb];
+}
+}
+
+GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path) : INHERITED(gpu) {
+ GL_CALL_RET(fPathID, GenPaths(1));
+ SkPath::Iter iter(path, true);
+
+ SkSTArray<16, GrGLubyte, true> pathCommands;
+ GR_STATIC_ASSERT(SK_SCALAR_IS_FLOAT); // assuming SkPoint is floats
+ SkSTArray<16, SkPoint, true> pathPoints;
+
+ int verbCnt = path.countVerbs();
+ int pointCnt = path.countPoints();
+ pathCommands.resize_back(verbCnt);
+ pathPoints.resize_back(pointCnt);
+
+ // TODO: Direct access to path points since we could pass them on directly.
+ path.getPoints(&pathPoints[0], pointCnt);
+ path.getVerbs(&pathCommands[0], verbCnt);
+
+ GR_DEBUGCODE(int numPts = 0);
+ for (int i = 0; i < verbCnt; ++i) {
+ SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]);
+ pathCommands[i] = verb_to_gl_path_cmd(v);
+ GR_DEBUGCODE(numPts += num_pts(v));
+ }
+ GrAssert(pathPoints.count() == numPts);
+
+ GL_CALL(PathCommands(fPathID,
+ verbCnt, &pathCommands[0],
+ 2 * pointCnt, GR_GL_FLOAT, &pathPoints[0]));
+ GrRect bounds = path.getBounds();
+ bounds.roundOut(&fBounds);
+}
+
+GrGLPath::~GrGLPath() {
+ this->release();
+}
+
+void GrGLPath::onRelease() {
+ if (0 != fPathID) {
+ GL_CALL(DeletePaths(1, fPathID));
+ fPathID = 0;
+ }
+}
+
+void GrGLPath::onAbandon() {
+ fPathID = 0;
+}
+
diff --git a/src/gpu/gl/GrGLPath.h b/src/gpu/gl/GrGLPath.h
new file mode 100644
index 0000000000..f9febb46b6
--- /dev/null
+++ b/src/gpu/gl/GrGLPath.h
@@ -0,0 +1,43 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLPath_DEFINED
+#define GrGLPath_DEFINED
+
+#include "../GrPath.h"
+#include "gl/GrGLFunctions.h"
+
+class GrGpuGL;
+class SkPath;
+
+/**
+ * Currently this represents a path built using GL_NV_path_rendering. If we
+ * support other GL path extensions then this would have to have a type enum
+ * and/or be subclassed.
+ */
+
+class GrGLPath : public GrPath {
+public:
+ GrGLPath(GrGpuGL* gpu, const SkPath& path);
+ virtual ~GrGLPath();
+ GrGLuint pathID() const { return fPathID; }
+ // TODO: Figure out how to get an approximate size of the path in Gpu
+ // memory.
+ virtual size_t sizeInBytes() const SK_OVERRIDE { return 100; }
+
+protected:
+ virtual void onRelease() SK_OVERRIDE;
+ virtual void onAbandon() SK_OVERRIDE;
+
+private:
+ GrGLuint fPathID;
+
+ typedef GrPath INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index da168cda13..77d875837b 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -8,6 +8,7 @@
#include "GrGpuGL.h"
#include "GrGLStencilBuffer.h"
+#include "GrGLPath.h"
#include "GrTypes.h"
#include "SkTemplates.h"
@@ -1325,6 +1326,14 @@ GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) {
return NULL;
}
+GrPath* GrGpuGL::onCreatePath(const SkPath& inPath) {
+ GrPath* path = NULL;
+ if (fCaps.fPathStencilingSupport) {
+ path = new GrGLPath(this, inPath);
+ }
+ return path;
+}
+
void GrGpuGL::enableScissoring(const GrIRect& rect) {
const GrDrawState& drawState = this->getDrawState();
const GrGLRenderTarget* rt =
@@ -1718,6 +1727,10 @@ void GrGpuGL::onGpuDrawNonIndexed(GrPrimitiveType type,
#endif
}
+void GrGpuGL::onGpuStencilPath(const GrPath&, GrPathFill) {
+ GrCrash("Not implemented yet. Should not get here.");
+}
+
void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
@@ -1955,7 +1968,7 @@ void GrGpuGL::flushStencil() {
}
}
-void GrGpuGL::flushAAState(GrPrimitiveType type) {
+void GrGpuGL::flushAAState(bool isLines) {
const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
if (kDesktop_GrGLBinding == this->glBinding()) {
// ES doesn't support toggling GL_MULTISAMPLE and doesn't have
@@ -1963,7 +1976,7 @@ void GrGpuGL::flushAAState(GrPrimitiveType type) {
// we prefer smooth lines over multisampled lines
bool smoothLines = false;
- if (GrIsPrimTypeLines(type)) {
+ if (isLines) {
smoothLines = this->willUseHWAALines();
if (smoothLines) {
if (kYes_TriState != fHWAAState.fSmoothLineEnabled) {
@@ -1999,10 +2012,10 @@ void GrGpuGL::flushAAState(GrPrimitiveType type) {
}
}
-void GrGpuGL::flushBlend(GrPrimitiveType type,
+void GrGpuGL::flushBlend(bool isLines,
GrBlendCoeff srcCoeff,
GrBlendCoeff dstCoeff) {
- if (GrIsPrimTypeLines(type) && this->willUseHWAALines()) {
+ if (isLines && this->willUseHWAALines()) {
if (kYes_TriState != fHWBlendState.fEnabled) {
GL_CALL(Enable(GR_GL_BLEND));
fHWBlendState.fEnabled = kYes_TriState;
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 290617099d..51e49ec1ec 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -67,6 +67,7 @@ protected:
bool dynamic) SK_OVERRIDE;
virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
bool dynamic) SK_OVERRIDE;
+ virtual GrPath* onCreatePath(const SkPath&) SK_OVERRIDE;
virtual GrTexture* onCreatePlatformTexture(
const GrPlatformTextureDesc& desc) SK_OVERRIDE;
virtual GrRenderTarget* onCreatePlatformRenderTarget(
@@ -106,13 +107,14 @@ protected:
virtual void onGpuDrawNonIndexed(GrPrimitiveType type,
uint32_t vertexCount,
uint32_t numVertices) SK_OVERRIDE;
+ virtual void onGpuStencilPath(const GrPath&, GrPathFill) SK_OVERRIDE;
virtual void enableScissoring(const GrIRect& rect) SK_OVERRIDE;
virtual void disableScissor() SK_OVERRIDE;
virtual void clearStencil() SK_OVERRIDE;
virtual void clearStencilClip(const GrIRect& rect,
bool insideClip) SK_OVERRIDE;
- virtual bool flushGraphicsState(GrPrimitiveType type) SK_OVERRIDE;
+ virtual bool flushGraphicsState(DrawType) SK_OVERRIDE;
virtual void setupGeometry(int* startVertex,
int* startIndex,
int vertexCount,
@@ -135,7 +137,7 @@ private:
// The params should be the final coeffecients to apply
// (after any blending optimizations or dual source blending considerations
// have been accounted for).
- void flushBlend(GrPrimitiveType type,
+ void flushBlend(bool isLines,
GrBlendCoeff srcCoeff,
GrBlendCoeff dstCoeff);
@@ -233,7 +235,7 @@ private:
static void DeleteProgram(const GrGLInterface* gl,
CachedData* programData);
- void buildProgram(GrPrimitiveType typeBlend,
+ void buildProgram(bool isPoints,
BlendOptFlags blendOpts,
GrBlendCoeff dstCoeff,
GrCustomStage** customStages);
@@ -261,7 +263,7 @@ private:
// NULL means whole target. Can be an empty rect.
void flushRenderTarget(const GrIRect* bound);
void flushStencil();
- void flushAAState(GrPrimitiveType type);
+ void flushAAState(bool isLines);
bool configToGLFormats(GrPixelConfig config,
bool getSizedInternal,
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index a38ae2dc98..97f9b6d817 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -370,7 +370,7 @@ void GrGpuGL::flushCoverage(GrColor coverage) {
}
}
-bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) {
+bool GrGpuGL::flushGraphicsState(DrawType type) {
const GrDrawState& drawState = this->getDrawState();
// GrGpu::setupClipAndFlushState should have already checked this
@@ -379,7 +379,7 @@ bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) {
this->flushMiscFixedFunctionState();
this->flushStencil();
- this->flushAAState(type);
+ this->flushAAState(kDrawLines_DrawType == type);
GrBlendCoeff srcCoeff;
GrBlendCoeff dstCoeff;
@@ -389,7 +389,8 @@ bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) {
}
GrCustomStage* customStages [GrDrawState::kNumStages];
- this->buildProgram(type, blendOpts, dstCoeff, customStages);
+ this->buildProgram(kDrawPoints_DrawType == type,
+ blendOpts, dstCoeff, customStages);
fProgramData = fProgramCache->getProgramData(fCurrentProgram,
customStages);
if (NULL == fProgramData) {
@@ -402,7 +403,7 @@ bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) {
fHWProgramID = fProgramData->fProgramID;
}
fCurrentProgram.overrideBlend(&srcCoeff, &dstCoeff);
- this->flushBlend(type, srcCoeff, dstCoeff);
+ this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
GrColor color;
GrColor coverage;
@@ -635,7 +636,7 @@ void setup_custom_stage(GrGLProgram::ProgramDesc::StageDesc* stage,
}
-void GrGpuGL::buildProgram(GrPrimitiveType type,
+void GrGpuGL::buildProgram(bool isPoints,
BlendOptFlags blendOpts,
GrBlendCoeff dstCoeff,
GrCustomStage** customStages) {
@@ -658,7 +659,7 @@ void GrGpuGL::buildProgram(GrPrimitiveType type,
// Must initialize all fields or cache will have false negatives!
desc.fVertexLayout = this->getVertexLayout();
- desc.fEmitsPointSize = kPoints_GrPrimitiveType == type;
+ desc.fEmitsPointSize = isPoints;
bool requiresAttributeColors =
!skipColor && SkToBool(desc.fVertexLayout & kColor_VertexLayoutBit);