blob: 100575875b6e725b731dc5309ae4e8eb4bb3c8e5 [file] [log] [blame]
robertphillips@google.com58b20212012-06-27 20:44:52 +00001/*
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 "GrSWMaskHelper.h"
Brian Osmanf9810662017-08-30 10:02:10 -04009
robertphillips976f5f02016-06-03 10:59:20 -070010#include "GrContext.h"
Robert Phillipse305cc1f2016-12-14 12:19:05 -050011#include "GrContextPriv.h"
bsalomon8acedde2016-06-24 10:42:16 -070012#include "GrShape.h"
Robert Phillipse305cc1f2016-12-14 12:19:05 -050013#include "GrSurfaceContext.h"
14#include "GrTextureProxy.h"
robertphillips@google.com58b20212012-06-27 20:44:52 +000015
robertphillips@google.com58b20212012-06-27 20:44:52 +000016/*
17 * Convert a boolean operation into a transfer mode code
18 */
reed374772b2016-10-05 17:33:02 -070019static SkBlendMode op_to_mode(SkRegion::Op op) {
robertphillips@google.com58b20212012-06-27 20:44:52 +000020
reed374772b2016-10-05 17:33:02 -070021 static const SkBlendMode modeMap[] = {
22 SkBlendMode::kDstOut, // kDifference_Op
23 SkBlendMode::kModulate, // kIntersect_Op
24 SkBlendMode::kSrcOver, // kUnion_Op
25 SkBlendMode::kXor, // kXOR_Op
26 SkBlendMode::kClear, // kReverseDifference_Op
27 SkBlendMode::kSrc, // kReplace_Op
robertphillips@google.com58b20212012-06-27 20:44:52 +000028 };
29
30 return modeMap[op];
31}
32
robertphillips@google.com58b20212012-06-27 20:44:52 +000033/**
34 * Draw a single rect element of the clip stack into the accumulation bitmap
35 */
Brian Salomon74077562017-08-30 13:55:35 -040036void GrSWMaskHelper::drawRect(const SkRect& rect, const SkMatrix& matrix, SkRegion::Op op, GrAA aa,
37 uint8_t alpha) {
robertphillips@google.com58b20212012-06-27 20:44:52 +000038 SkPaint paint;
reed374772b2016-10-05 17:33:02 -070039 paint.setBlendMode(op_to_mode(op));
Brian Salomon0e8fc8b2016-12-09 15:10:07 -050040 paint.setAntiAlias(GrAA::kYes == aa);
robertphillips@google.com366f1c62012-06-29 21:38:47 +000041 paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
robertphillips@google.com58b20212012-06-27 20:44:52 +000042
Brian Salomon74077562017-08-30 13:55:35 -040043 SkMatrix translatedMatrix = matrix;
44 translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY);
45 fDraw.fMatrix = &translatedMatrix;
46
robertphillips@google.com366f1c62012-06-29 21:38:47 +000047 fDraw.drawRect(rect, paint);
robertphillips@google.com58b20212012-06-27 20:44:52 +000048}
49
50/**
51 * Draw a single path element of the clip stack into the accumulation bitmap
52 */
Brian Salomon74077562017-08-30 13:55:35 -040053void GrSWMaskHelper::drawShape(const GrShape& shape, const SkMatrix& matrix, SkRegion::Op op,
54 GrAA aa, uint8_t alpha) {
robertphillips@google.com58b20212012-06-27 20:44:52 +000055 SkPaint paint;
Robert Phillipsf809c1e2017-01-13 11:02:42 -050056 paint.setPathEffect(shape.style().refPathEffect());
bsalomon8acedde2016-06-24 10:42:16 -070057 shape.style().strokeRec().applyToPaint(&paint);
Brian Salomon0e8fc8b2016-12-09 15:10:07 -050058 paint.setAntiAlias(GrAA::kYes == aa);
reed@google.com84e922b2013-11-04 20:57:36 +000059
Brian Salomon74077562017-08-30 13:55:35 -040060 SkMatrix translatedMatrix = matrix;
61 translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY);
62 fDraw.fMatrix = &translatedMatrix;
63
bsalomon8acedde2016-06-24 10:42:16 -070064 SkPath path;
65 shape.asPath(&path);
reed@google.com126f7f52013-11-07 16:06:53 +000066 if (SkRegion::kReplace_Op == op && 0xFF == alpha) {
67 SkASSERT(0xFF == paint.getAlpha());
robertphillips98377402016-05-13 05:47:23 -070068 fDraw.drawPathCoverage(path, paint);
reed@google.com126f7f52013-11-07 16:06:53 +000069 } else {
reed374772b2016-10-05 17:33:02 -070070 paint.setBlendMode(op_to_mode(op));
reed@google.com126f7f52013-11-07 16:06:53 +000071 paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
robertphillips98377402016-05-13 05:47:23 -070072 fDraw.drawPath(path, paint);
reed@google.com126f7f52013-11-07 16:06:53 +000073 }
Brian Salomon74077562017-08-30 13:55:35 -040074};
robertphillips@google.com58b20212012-06-27 20:44:52 +000075
Brian Salomon74077562017-08-30 13:55:35 -040076bool GrSWMaskHelper::init(const SkIRect& resultBounds) {
77 // We will need to translate draws so the bound's UL corner is at the origin
78 fTranslate = {-SkIntToScalar(resultBounds.fLeft), -SkIntToScalar(resultBounds.fTop)};
robertphillips98377402016-05-13 05:47:23 -070079 SkIRect bounds = SkIRect::MakeWH(resultBounds.width(), resultBounds.height());
krajcevski25a67bc2014-07-29 11:44:26 -070080
robertphillips98377402016-05-13 05:47:23 -070081 const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(bounds.width(), bounds.height());
Brian Osmanf9810662017-08-30 10:02:10 -040082 if (!fPixels->tryAlloc(bmImageInfo)) {
robertphillips98377402016-05-13 05:47:23 -070083 return false;
krajcevskib8ccc2f2014-08-07 08:15:14 -070084 }
Brian Osmanf9810662017-08-30 10:02:10 -040085 fPixels->erase(0);
krajcevskib8ccc2f2014-08-07 08:15:14 -070086
reed41e010c2015-06-09 12:16:53 -070087 sk_bzero(&fDraw, sizeof(fDraw));
Brian Osmanf9810662017-08-30 10:02:10 -040088 fDraw.fDst = *fPixels;
robertphillips@google.com58b20212012-06-27 20:44:52 +000089 fRasterClip.setRect(bounds);
reed41e010c2015-06-09 12:16:53 -070090 fDraw.fRC = &fRasterClip;
robertphillips@google.com58b20212012-06-27 20:44:52 +000091 return true;
92}
93
Robert Phillipsd3749482017-03-14 09:17:43 -040094sk_sp<GrTextureProxy> GrSWMaskHelper::toTextureProxy(GrContext* context, SkBackingFit fit) {
bsalomonf2703d82014-10-28 14:33:06 -070095 GrSurfaceDesc desc;
Robert Phillipsd3749482017-03-14 09:17:43 -040096 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
Brian Osmanf9810662017-08-30 10:02:10 -040097 desc.fWidth = fPixels->width();
98 desc.fHeight = fPixels->height();
krajcevskib3abe902014-07-30 13:08:11 -070099 desc.fConfig = kAlpha_8_GrPixelConfig;
krajcevskifb4f5cb2014-06-12 09:20:38 -0700100
Robert Phillipse305cc1f2016-12-14 12:19:05 -0500101 sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeDeferredSurfaceContext(
102 desc,
Greg Daniel65c7f662017-10-30 13:39:09 -0400103 GrMipMapped::kNo,
Robert Phillipse305cc1f2016-12-14 12:19:05 -0500104 fit,
105 SkBudgeted::kYes);
Robert Phillipsf200a902017-01-30 13:27:37 -0500106 if (!sContext || !sContext->asTextureProxy()) {
Robert Phillipse305cc1f2016-12-14 12:19:05 -0500107 return nullptr;
bsalomon39ef7fb2016-09-21 11:16:05 -0700108 }
robertphillips@google.com58b20212012-06-27 20:44:52 +0000109
Robert Phillipsc949ce92017-01-19 16:59:04 -0500110 SkImageInfo ii = SkImageInfo::MakeA8(desc.fWidth, desc.fHeight);
Brian Osmanf9810662017-08-30 10:02:10 -0400111 if (!sContext->writePixels(ii, fPixels->addr(), fPixels->rowBytes(), 0, 0)) {
Robert Phillipse305cc1f2016-12-14 12:19:05 -0500112 return nullptr;
113 }
cblumeed828002016-02-16 13:00:01 -0800114
Robert Phillipsf200a902017-01-30 13:27:37 -0500115 return sContext->asTextureProxyRef();
robertphillips@google.com58b20212012-06-27 20:44:52 +0000116}