• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 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 "src/gpu/GrSWMaskHelper.h"
9 
10 #include "include/private/GrRecordingContext.h"
11 #include "src/gpu/GrCaps.h"
12 #include "src/gpu/GrProxyProvider.h"
13 #include "src/gpu/GrRecordingContextPriv.h"
14 #include "src/gpu/GrSurfaceContext.h"
15 #include "src/gpu/GrTextureProxy.h"
16 #include "src/gpu/geometry/GrShape.h"
17 
18 /*
19  * Convert a boolean operation into a transfer mode code
20  */
op_to_mode(SkRegion::Op op)21 static SkBlendMode op_to_mode(SkRegion::Op op) {
22 
23     static const SkBlendMode modeMap[] = {
24         SkBlendMode::kDstOut,   // kDifference_Op
25         SkBlendMode::kModulate, // kIntersect_Op
26         SkBlendMode::kSrcOver,  // kUnion_Op
27         SkBlendMode::kXor,      // kXOR_Op
28         SkBlendMode::kClear,    // kReverseDifference_Op
29         SkBlendMode::kSrc,      // kReplace_Op
30     };
31 
32     return modeMap[op];
33 }
34 
35 /**
36  * Draw a single rect element of the clip stack into the accumulation bitmap
37  */
drawRect(const SkRect & rect,const SkMatrix & matrix,SkRegion::Op op,GrAA aa,uint8_t alpha)38 void GrSWMaskHelper::drawRect(const SkRect& rect, const SkMatrix& matrix, SkRegion::Op op, GrAA aa,
39                               uint8_t alpha) {
40     SkPaint paint;
41     paint.setBlendMode(op_to_mode(op));
42     paint.setAntiAlias(GrAA::kYes == aa);
43     paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
44 
45     SkMatrix translatedMatrix = matrix;
46     translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY);
47     fDraw.fMatrix = &translatedMatrix;
48 
49     fDraw.drawRect(rect, paint);
50 }
51 
52 /**
53  * Draw a single path element of the clip stack into the accumulation bitmap
54  */
drawShape(const GrShape & shape,const SkMatrix & matrix,SkRegion::Op op,GrAA aa,uint8_t alpha)55 void GrSWMaskHelper::drawShape(const GrShape& shape, const SkMatrix& matrix, SkRegion::Op op,
56                                GrAA aa, uint8_t alpha) {
57     SkPaint paint;
58     paint.setPathEffect(shape.style().refPathEffect());
59     shape.style().strokeRec().applyToPaint(&paint);
60     paint.setAntiAlias(GrAA::kYes == aa);
61 
62     SkMatrix translatedMatrix = matrix;
63     translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY);
64     fDraw.fMatrix = &translatedMatrix;
65 
66     SkPath path;
67     shape.asPath(&path);
68     if (SkRegion::kReplace_Op == op && 0xFF == alpha) {
69         SkASSERT(0xFF == paint.getAlpha());
70         fDraw.drawPathCoverage(path, paint);
71     } else {
72         paint.setBlendMode(op_to_mode(op));
73         paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
74         fDraw.drawPath(path, paint);
75     }
76 };
77 
init(const SkIRect & resultBounds)78 bool GrSWMaskHelper::init(const SkIRect& resultBounds) {
79     // We will need to translate draws so the bound's UL corner is at the origin
80     fTranslate = {-SkIntToScalar(resultBounds.fLeft), -SkIntToScalar(resultBounds.fTop)};
81     SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), resultBounds.height());
82 
83     const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(bounds.width(), bounds.height());
84     if (!fPixels->tryAlloc(bmImageInfo)) {
85         return false;
86     }
87     fPixels->erase(0);
88 
89     fDraw.fDst      = *fPixels;
90     fRasterClip.setRect(bounds);
91     fDraw.fRC       = &fRasterClip;
92     return true;
93 }
94 
toTextureProxy(GrRecordingContext * context,SkBackingFit fit)95 sk_sp<GrTextureProxy> GrSWMaskHelper::toTextureProxy(GrRecordingContext* context,
96                                                      SkBackingFit fit) {
97     SkImageInfo ii = SkImageInfo::MakeA8(fPixels->width(), fPixels->height());
98     size_t rowBytes = fPixels->rowBytes();
99 
100     sk_sp<SkData> data = fPixels->detachPixelsAsData();
101     if (!data) {
102         return nullptr;
103     }
104 
105     sk_sp<SkImage> img = SkImage::MakeRasterData(ii, std::move(data), rowBytes);
106     if (!img) {
107         return nullptr;
108     }
109 
110     return context->priv().proxyProvider()->createTextureProxy(std::move(img), 1, SkBudgeted::kYes,
111                                                                fit);
112 }
113