Home | History | Annotate | Download | only in ops
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "GrDrawPathOp.h"
      9 #include "GrAppliedClip.h"
     10 #include "GrMemoryPool.h"
     11 #include "GrRenderTargetContext.h"
     12 #include "GrRenderTargetPriv.h"
     13 #include "SkTemplates.h"
     14 
     15 GrDrawPathOpBase::GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&& paint,
     16                                    GrPathRendering::FillType fill, GrAAType aaType)
     17         : INHERITED(classID)
     18         , fViewMatrix(viewMatrix)
     19         , fInputColor(paint.getColor4f())
     20         , fFillType(fill)
     21         , fAAType(aaType)
     22         , fProcessorSet(std::move(paint)) {}
     23 
     24 #ifdef SK_DEBUG
     25 SkString GrDrawPathOp::dumpInfo() const {
     26     SkString string;
     27     string.printf("PATH: 0x%p", fPath.get());
     28     string.append(INHERITED::dumpInfo());
     29     return string;
     30 }
     31 #endif
     32 
     33 GrPipeline::InitArgs GrDrawPathOpBase::pipelineInitArgs(const GrOpFlushState& state) {
     34     static constexpr GrUserStencilSettings kCoverPass{
     35             GrUserStencilSettings::StaticInit<
     36                     0x0000,
     37                     GrUserStencilTest::kNotEqual,
     38                     0xffff,
     39                     GrUserStencilOp::kZero,
     40                     GrUserStencilOp::kKeep,
     41                     0xffff>()
     42     };
     43     GrPipeline::InitArgs args;
     44     if (GrAATypeIsHW(fAAType)) {
     45         args.fFlags |= GrPipeline::kHWAntialias_Flag;
     46     }
     47     args.fUserStencil = &kCoverPass;
     48     args.fCaps = &state.caps();
     49     args.fResourceProvider = state.resourceProvider();
     50     args.fDstProxy = state.drawOpArgs().fDstProxy;
     51     return args;
     52 }
     53 
     54 //////////////////////////////////////////////////////////////////////////////
     55 
     56 void init_stencil_pass_settings(const GrOpFlushState& flushState,
     57                                 GrPathRendering::FillType fillType, GrStencilSettings* stencil) {
     58     const GrAppliedClip* appliedClip = flushState.drawOpArgs().fAppliedClip;
     59     bool stencilClip = appliedClip && appliedClip->hasStencilClip();
     60     stencil->reset(GrPathRendering::GetStencilPassSettings(fillType), stencilClip,
     61                    flushState.drawOpArgs().renderTarget()->renderTargetPriv().numStencilBits());
     62 }
     63 
     64 //////////////////////////////////////////////////////////////////////////////
     65 
     66 std::unique_ptr<GrDrawOp> GrDrawPathOp::Make(GrContext* context,
     67                                              const SkMatrix& viewMatrix,
     68                                              GrPaint&& paint,
     69                                              GrAAType aaType,
     70                                              GrPath* path) {
     71     GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
     72 
     73     return pool->allocate<GrDrawPathOp>(viewMatrix, std::move(paint), aaType, path);
     74 }
     75 
     76 void GrDrawPathOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
     77     GrAppliedClip appliedClip = state->detachAppliedClip();
     78     GrPipeline::FixedDynamicState fixedDynamicState(appliedClip.scissorState().rect());
     79     GrPipeline pipeline(this->pipelineInitArgs(*state), this->detachProcessors(),
     80                         std::move(appliedClip));
     81     sk_sp<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(), this->viewMatrix()));
     82 
     83     GrStencilSettings stencil;
     84     init_stencil_pass_settings(*state, this->fillType(), &stencil);
     85     state->gpu()->pathRendering()->drawPath(state->drawOpArgs().renderTarget(),
     86                                             state->drawOpArgs().origin(),
     87                                             *pathProc, pipeline, fixedDynamicState, stencil,
     88                                             fPath.get());
     89 }
     90 
     91 //////////////////////////////////////////////////////////////////////////////
     92 
     93 inline void pre_translate_transform_values(const float* xforms,
     94                                            GrPathRendering::PathTransformType type, int count,
     95                                            SkScalar x, SkScalar y, float* dst) {
     96     if (0 == x && 0 == y) {
     97         memcpy(dst, xforms, count * GrPathRendering::PathTransformSize(type) * sizeof(float));
     98         return;
     99     }
    100     switch (type) {
    101         case GrPathRendering::kNone_PathTransformType:
    102             SK_ABORT("Cannot pre-translate kNone_PathTransformType.");
    103             break;
    104         case GrPathRendering::kTranslateX_PathTransformType:
    105             SkASSERT(0 == y);
    106             for (int i = 0; i < count; i++) {
    107                 dst[i] = xforms[i] + x;
    108             }
    109             break;
    110         case GrPathRendering::kTranslateY_PathTransformType:
    111             SkASSERT(0 == x);
    112             for (int i = 0; i < count; i++) {
    113                 dst[i] = xforms[i] + y;
    114             }
    115             break;
    116         case GrPathRendering::kTranslate_PathTransformType:
    117             for (int i = 0; i < 2 * count; i += 2) {
    118                 dst[i] = xforms[i] + x;
    119                 dst[i + 1] = xforms[i + 1] + y;
    120             }
    121             break;
    122         case GrPathRendering::kAffine_PathTransformType:
    123             for (int i = 0; i < 6 * count; i += 6) {
    124                 dst[i] = xforms[i];
    125                 dst[i + 1] = xforms[i + 1];
    126                 dst[i + 2] = xforms[i] * x + xforms[i + 1] * y + xforms[i + 2];
    127                 dst[i + 3] = xforms[i + 3];
    128                 dst[i + 4] = xforms[i + 4];
    129                 dst[i + 5] = xforms[i + 3] * x + xforms[i + 4] * y + xforms[i + 5];
    130             }
    131             break;
    132         default:
    133             SK_ABORT("Unknown transform type.");
    134             break;
    135     }
    136 }
    137