From a72eef322c686954cdffa849dc26d8133b802f1d Mon Sep 17 00:00:00 2001 From: "robertphillips@google.com" Date: Tue, 1 May 2012 17:22:59 +0000 Subject: [PATCH] Added gpu AA clipping to old shader path http://codereview.appspot.com/6139065/ git-svn-id: http://skia.googlecode.com/svn/trunk@3812 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/gpu/GrClipMaskManager.cpp | 47 +++++++++++++++++++++++++++++++++-- src/gpu/GrClipMaskManager.h | 5 +++- src/gpu/GrDrawState.h | 2 +- src/gpu/GrDrawTarget.cpp | 2 +- src/gpu/GrDrawTarget.h | 13 ++++++++++ 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 027ec5bb4e..a1ac0ab9b1 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -11,6 +11,10 @@ #include "GrRenderTarget.h" #include "GrStencilBuffer.h" #include "GrPathRenderer.h" +#include "GrPaint.h" + +//#define GR_AA_CLIP 1 + //////////////////////////////////////////////////////////////////////////////// void ScissoringSettings::setupScissoring(GrGpu* gpu) { @@ -22,6 +26,34 @@ void ScissoringSettings::setupScissoring(GrGpu* gpu) { gpu->enableScissoring(fScissorRect); } +namespace { +// set up the draw state to enable the aa clipping mask. Besides setting up the +// sampler matrix this also alters the vertex layout +void setupDrawStateAAClip(GrGpu* gpu, GrTexture* result, const GrRect &bound) { + GrDrawState* drawState = gpu->drawState(); + GrAssert(drawState); + + static const int maskStage = GrPaint::kTotalStages+1; + + GrMatrix mat; + mat.setIDiv(result->width(), result->height()); + mat.preTranslate(-bound.fLeft, -bound.fTop); + mat.preConcat(drawState->getViewMatrix()); + + drawState->sampler(maskStage)->reset(GrSamplerState::kClamp_WrapMode, + GrSamplerState::kNearest_Filter, + mat); + + drawState->setTexture(maskStage, result); + + // The AA clipping determination happens long after the geometry has + // been set up to draw. Here we directly enable the AA clip mask stage + gpu->addToVertexLayout( + GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(maskStage)); +} + +} + //////////////////////////////////////////////////////////////////////////////// // sort out what kind of clip mask needs to be created: alpha, stencil // or scissor @@ -53,8 +85,12 @@ bool GrClipMaskManager::createClipMask(GrGpu* gpu, // size for the mask (rather than being bound by the size of the // render target) we aren't going to use scissoring like the stencil // path does (see scissorSettings below) - if (this->createAlphaClipMask(gpu, clipIn)) { + GrTexture* result = NULL; + GrRect bound; + if (this->createAlphaClipMask(gpu, clipIn, &result, &bound)) { fClipMaskInAlpha = true; + + setupDrawStateAAClip(gpu, result, bound); return true; } @@ -319,7 +355,10 @@ void clear(GrGpu* gpu, //////////////////////////////////////////////////////////////////////////////// // Create a 8-bit clip mask in alpha -bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu, const GrClip& clipIn) { +bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu, + const GrClip& clipIn, + GrTexture** result, + GrRect *resultBounds) { GrDrawState* origDrawState = gpu->drawState(); GrAssert(origDrawState->isClipState()); @@ -353,6 +392,8 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu, const GrClip& clipIn) { // path doesn't leave any room for antialiasing (esp. w.r.t. rects) bounds.outset(SkIntToScalar(1), SkIntToScalar(1)); + // TODO: make sure we don't outset if bounds are still 0,0 @ min + GrAssert(SkScalarIsInt(bounds.width())); GrAssert(SkScalarIsInt(bounds.height())); @@ -464,6 +505,8 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu, const GrClip& clipIn) { } } + *result = accum; + *resultBounds = bounds; return true; } diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h index e698791677..be6873edd9 100644 --- a/src/gpu/GrClipMaskManager.h +++ b/src/gpu/GrClipMaskManager.h @@ -76,7 +76,10 @@ private: const GrClip& clip, const GrRect& bounds, ScissoringSettings* scissorSettings); - bool createAlphaClipMask(GrGpu* gpu, const GrClip& clipIn); + bool createAlphaClipMask(GrGpu* gpu, + const GrClip& clipIn, + GrTexture** result, + GrRect *resultBounds); bool drawPath(GrGpu* gpu, const SkPath& path, diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index cf2b63ad4a..fee22bfaf4 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -331,7 +331,7 @@ public: //// /** - * Sets the matrix applied to veretx positions. + * Sets the matrix applied to vertex positions. * * In the post-view-matrix space the rectangle [0,w]x[0,h] * fully covers the render target. (w and h are the width and height of the diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index c5dd3ec399..037f0f8530 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -20,7 +20,7 @@ namespace { /** * This function generates some masks that we like to have known at compile * time. When the number of stages or tex coords is bumped or the way bits - * are defined in GrDrawTarget.h changes this funcion should be rerun to + * are defined in GrDrawTarget.h changes this function should be rerun to * generate the new masks. (We attempted to force the compiler to generate the * masks using recursive templates but always wound up with static initializers * under gcc, even if they were just a series of immediate->memory moves.) diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index ca499dbff0..273ef3c043 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -209,6 +209,19 @@ public: return (1 << (TEX_COORD_BIT_CNT + stage)); } + /** + * Modify the existing vertex layout. Realistically the only thing that + * can be added w/o recomputing the vertex layout is one of the + * StagePosAsTexCoordVertexLayoutBit flags + */ + void addToVertexLayout(int flag) { + GrAssert((1 << TEX_COORD_BIT_CNT) == flag || + (1 << (TEX_COORD_BIT_CNT + 1)) == flag || + (1 << (TEX_COORD_BIT_CNT + 2)) == flag || + (1 << (TEX_COORD_BIT_CNT + 3)) == flag); + fGeoSrcStateStack.back().fVertexLayout |= flag; + } + private: static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + GrDrawState::kNumStages;