Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(333)

Unified Diff: src/gpu/gl/GrGpuGL.cpp

Issue 209413006: Make it possible to draw multiple paths at once to a draw target (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: address review comment Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/gl/GrGpuGL.h ('k') | src/gpu/gl/GrGpuGL_program.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/gl/GrGpuGL.cpp
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 5fb268863b25a256113631ca3f06705e0024116a..0aa072cd8463c8972090bba2c2dcb15133434096 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1695,6 +1695,99 @@ void GrGpuGL::onGpuDrawPath(const GrPath* path, SkPath::FillType fill) {
}
}
+void GrGpuGL::onGpuDrawPaths(size_t pathCount, const GrPath** paths,
+ const SkMatrix* transforms,
+ SkPath::FillType fill,
+ SkStrokeRec::Style stroke) {
+ SkASSERT(this->caps()->pathRenderingSupport());
+ SkASSERT(NULL != this->drawState()->getRenderTarget());
+ SkASSERT(NULL != this->drawState()->getRenderTarget()->getStencilBuffer());
+ SkASSERT(!fCurrentProgram->hasVertexShader());
+ SkASSERT(stroke != SkStrokeRec::kHairline_Style);
+
+ SkAutoMalloc pathData(pathCount * sizeof(GrGLuint));
+ SkAutoMalloc transformData(pathCount * sizeof(GrGLfloat) * 6);
+ GrGLfloat* transformValues =
+ reinterpret_cast<GrGLfloat*>(transformData.get());
+ GrGLuint* pathIDs = reinterpret_cast<GrGLuint*>(pathData.get());
+
+ for (size_t i = 0; i < pathCount; ++i) {
+ SkASSERT(transforms[i].asAffine(NULL));
+ const SkMatrix& m = transforms[i];
+ transformValues[i * 6] = m.getScaleX();
+ transformValues[i * 6 + 1] = m.getSkewY();
+ transformValues[i * 6 + 2] = m.getSkewX();
+ transformValues[i * 6 + 3] = m.getScaleY();
+ transformValues[i * 6 + 4] = m.getTranslateX();
+ transformValues[i * 6 + 5] = m.getTranslateY();
+ pathIDs[i] = static_cast<const GrGLPath*>(paths[i])->pathID();
+ }
+
+ flushPathStencilSettings(fill);
+
+ SkPath::FillType nonInvertedFill =
+ SkPath::ConvertToNonInverseFillType(fill);
+
+ SkASSERT(!fHWPathStencilSettings.isTwoSided());
+ GrGLenum fillMode =
+ gr_stencil_op_to_gl_path_rendering_fill_mode(
+ fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
+ GrGLint writeMask =
+ fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
+
+ bool doFill = stroke == SkStrokeRec::kFill_Style
+ || stroke == SkStrokeRec::kStrokeAndFill_Style;
+ bool doStroke = stroke == SkStrokeRec::kStroke_Style
+ || stroke == SkStrokeRec::kStrokeAndFill_Style;
+
+ if (doFill) {
+ GL_CALL(StencilFillPathInstanced(pathCount, GR_GL_UNSIGNED_INT,
+ pathIDs, 0,
+ fillMode, writeMask,
+ GR_GL_AFFINE_2D, transformValues));
+ }
+ if (doStroke) {
+ GL_CALL(StencilStrokePathInstanced(pathCount, GR_GL_UNSIGNED_INT,
+ pathIDs, 0,
+ 0xffff, writeMask,
+ GR_GL_AFFINE_2D, transformValues));
+ }
+
+ if (nonInvertedFill == fill) {
+ if (doStroke) {
+ GL_CALL(CoverStrokePathInstanced(
+ pathCount, GR_GL_UNSIGNED_INT, pathIDs, 0,
+ GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
+ GR_GL_AFFINE_2D, transformValues));
+ } else {
+ GL_CALL(CoverFillPathInstanced(
+ pathCount, GR_GL_UNSIGNED_INT, pathIDs, 0,
+ GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
+ GR_GL_AFFINE_2D, transformValues));
+
+ }
+ } else {
+ GrDrawState* drawState = this->drawState();
+ GrDrawState::AutoViewMatrixRestore avmr;
+ SkRect bounds = SkRect::MakeLTRB(0, 0,
+ SkIntToScalar(drawState->getRenderTarget()->width()),
+ SkIntToScalar(drawState->getRenderTarget()->height()));
+ SkMatrix vmi;
+ // mapRect through persp matrix may not be correct
+ if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
+ vmi.mapRect(&bounds);
+ // theoretically could set bloat = 0, instead leave it because of matrix inversion
+ // precision.
+ SkScalar bloat = drawState->getViewMatrix().getMaxStretch() * SK_ScalarHalf;
+ bounds.outset(bloat, bloat);
+ } else {
+ avmr.setIdentity(drawState);
+ }
+
+ this->drawSimpleRect(bounds, NULL);
+ }
+}
+
void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
if (rt->needsResolve()) {
« no previous file with comments | « src/gpu/gl/GrGpuGL.h ('k') | src/gpu/gl/GrGpuGL_program.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698