SkCanvas* SkSurface_Compute::onNewCanvas() { uint32_t w = 0,h = 0; // skc_interop_size_get(compute->interop,&w,&h); TODO skc.h SkDevice_Compute * const device_compute = new SkDevice_Compute(compute,w,h);; SkCanvas * const canvas = new SkCanvas(device_compute,SkCanvas::kConservativeRasterClip_InitFlag); // // destroy device upon surface destruction // device = sk_sp<SkBaseDevice>(device_compute); // // move origin from upper left to lower left // SkMatrix matrix; matrix.setScaleTranslate(1.0f,-1.0f,0.0f,(SkScalar)h); canvas->setMatrix(matrix); return canvas; }
void onDraw(SkCanvas* canvas) override { static const SkFilterQuality kFilterQuality = SkFilterQuality::kHigh_SkFilterQuality; static const bool kDoAA = true; { SkRect r1 = SkRect::MakeXYWH(50.0f, 0.0f, 50.0f, 50.0f); SkPaint p1; p1.setAntiAlias(kDoAA); p1.setFilterQuality(kFilterQuality); SkMatrix localMat; localMat.setScaleTranslate(2.0f, 2.0f, 50.0f, 0.0f); p1.setShader(SkImageShader::Make(fTop, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMat)); canvas->drawRect(r1, p1); } { SkRect r2 = SkRect::MakeXYWH(50.0f, 50.0f, 50.0f, 36.0f); SkPaint p2; p2.setColor(SK_ColorWHITE); p2.setAntiAlias(kDoAA); p2.setFilterQuality(kFilterQuality); canvas->drawRect(r2, p2); } { SkRect r3 = SkRect::MakeXYWH(50.0f, 86.0f, 50.0f, 50.0f); SkPaint p3; p3.setAntiAlias(kDoAA); p3.setFilterQuality(kFilterQuality); SkMatrix localMat; localMat.setScaleTranslate(2.0f, 2.0f, 50.0f, 86.0f); p3.setShader(SkImageShader::Make(fBot, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMat)); canvas->drawRect(r3, p3); } }
std::unique_ptr<GrFillRRectOp> GrFillRRectOp::Make( GrRecordingContext* ctx, GrAAType aaType, const SkMatrix& viewMatrix, const SkRRect& rrect, const GrCaps& caps, GrPaint&& paint) { if (!caps.instanceAttribSupport()) { return nullptr; } Flags flags = Flags::kNone; if (GrAAType::kCoverage == aaType) { // TODO: Support perspective in a follow-on CL. This shouldn't be difficult, since we // already use HW derivatives. The only trick will be adjusting the AA outset to account for // perspective. (i.e., outset = 0.5 * z.) if (viewMatrix.hasPerspective()) { return nullptr; } if (can_use_hw_derivatives_with_coverage(*caps.shaderCaps(), viewMatrix, rrect)) { // HW derivatives (more specifically, fwidth()) are consistently faster on all platforms // in coverage mode. We use them as long as the approximation will be accurate enough. flags |= Flags::kUseHWDerivatives; } } else { if (GrAAType::kMSAA == aaType) { if (!caps.sampleLocationsSupport() || !caps.shaderCaps()->sampleVariablesSupport()) { return nullptr; } } if (viewMatrix.hasPerspective()) { // HW derivatives are consistently slower on all platforms in sample mask mode. We // therefore only use them when there is perspective, since then we can't interpolate // the symbolic screen-space gradient. flags |= Flags::kUseHWDerivatives | Flags::kHasPerspective; } } // Produce a matrix that draws the round rect from normalized [-1, -1, +1, +1] space. float l = rrect.rect().left(), r = rrect.rect().right(), t = rrect.rect().top(), b = rrect.rect().bottom(); SkMatrix m; // Unmap the normalized rect [-1, -1, +1, +1] back to [l, t, r, b]. m.setScaleTranslate((r - l)/2, (b - t)/2, (l + r)/2, (t + b)/2); // Map to device space. m.postConcat(viewMatrix); SkRect devBounds; if (!(flags & Flags::kHasPerspective)) { // Since m is an affine matrix that maps the rect [-1, -1, +1, +1] into the shape's // device-space quad, it's quite simple to find the bounding rectangle: devBounds = SkRect::MakeXYWH(m.getTranslateX(), m.getTranslateY(), 0, 0); devBounds.outset(SkScalarAbs(m.getScaleX()) + SkScalarAbs(m.getSkewX()), SkScalarAbs(m.getSkewY()) + SkScalarAbs(m.getScaleY())); } else { viewMatrix.mapRect(&devBounds, rrect.rect()); } if (GrAAType::kMSAA == aaType && caps.preferTrianglesOverSampleMask()) { // We are on a platform that prefers fine triangles instead of using the sample mask. See if // the round rect is large enough that it will be faster for us to send it off to the // default path renderer instead. The 200x200 threshold was arrived at using the // "shapes_rrect" benchmark on an ARM Galaxy S9. if (devBounds.height() * devBounds.width() > 200 * 200) { return nullptr; } } GrOpMemoryPool* pool = ctx->priv().opMemoryPool(); return pool->allocate<GrFillRRectOp>(aaType, rrect, flags, m, std::move(paint), devBounds); }