1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2011 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBlurMask.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBlurMaskFilter.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBlurDrawLooper.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorFilter.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkEmbossMaskFilter.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkLayerDrawLooper.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMaskFilterBase.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMath.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPaint.h" 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPath.h" 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPerlinNoiseShader.h" 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurface.h" 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Test.h" 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContextFactory.h" 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGpuDevice.h" 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define WRITE_CSV 0 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////// 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define ILLEGAL_MODE ((SkXfermode::Mode)-1) 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const int outset = 100; 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const SkColor bgColor = SK_ColorWHITE; 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const int strokeWidth = 4; 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void create(SkBitmap* bm, const SkIRect& bound) { 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bm->allocN32Pixels(bound.width(), bound.height()); 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void drawBG(SkCanvas* canvas) { 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawColor(bgColor); 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct BlurTest { 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void (*addPath)(SkPath*); 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int viewLen; 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect views[9]; 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//Path Draw Procs 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//Beware that paths themselves my draw differently depending on the clip. 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw50x50Rect(SkPath* path) { 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path->addRect(0, 0, SkIntToScalar(50), SkIntToScalar(50)); 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//Tests 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic BlurTest tests[] = { 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { draw50x50Rect, 3, { 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //inner half of blur 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 0, 0, 50, 50 }, 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //blur, but no path. 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 50 + strokeWidth/2, 50 + strokeWidth/2, 100, 100 }, 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //just an edge 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 40, strokeWidth, 60, 50 - strokeWidth }, 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }}, 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** Assumes that the ref draw was completely inside ref canvas -- 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot implies that everything outside is "bgColor". 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Checks that all overlap is the same and that all non-overlap on the 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ref is "bgColor". 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic bool compare(const SkBitmap& ref, const SkIRect& iref, 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkBitmap& test, const SkIRect& itest) 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot{ 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const int xOff = itest.fLeft - iref.fLeft; 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const int yOff = itest.fTop - iref.fTop; 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int y = 0; y < test.height(); ++y) { 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int x = 0; x < test.width(); ++x) { 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkColor testColor = test.getColor(x, y); 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int refX = x + xOff; 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int refY = y + yOff; 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkColor refColor; 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (refX >= 0 && refX < ref.width() && 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot refY >= 0 && refY < ref.height()) 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot refColor = ref.getColor(refX, refY); 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot refColor = bgColor; 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (refColor != testColor) { 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(BlurDrawing, reporter) { 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setColor(SK_ColorGRAY); 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setStyle(SkPaint::kStroke_Style); 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setStrokeWidth(SkIntToScalar(strokeWidth)); 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5)); 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int style = 0; style <= kLastEnum_SkBlurStyle; ++style) { 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBlurStyle blurStyle = static_cast<SkBlurStyle>(style); 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const uint32_t flagPermutations = SkBlurMaskFilter::kAll_BlurFlag; 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (uint32_t flags = 0; flags < flagPermutations; ++flags) { 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setMaskFilter(SkBlurMaskFilter::Make(blurStyle, sigma, flags)); 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t test = 0; test < SK_ARRAY_COUNT(tests); ++test) { 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath path; 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tests[test].addPath(&path); 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath strokedPath; 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.getFillPath(path, &strokedPath); 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect refBound = strokedPath.getBounds(); 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect iref; 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot refBound.roundOut(&iref); 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot iref.inset(-outset, -outset); 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap refBitmap; 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot create(&refBitmap, iref); 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas refCanvas(refBitmap); 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot refCanvas.translate(SkIntToScalar(-iref.fLeft), 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(-iref.fTop)); 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot drawBG(&refCanvas); 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot refCanvas.drawPath(path, paint); 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int view = 0; view < tests[test].viewLen; ++view) { 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect itest = tests[test].views[view]; 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap testBitmap; 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot create(&testBitmap, itest); 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas testCanvas(testBitmap); 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot testCanvas.translate(SkIntToScalar(-itest.fLeft), 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(-itest.fTop)); 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot drawBG(&testCanvas); 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot testCanvas.drawPath(path, paint); 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot compare(refBitmap, iref, testBitmap, itest)); 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////// 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Use SkBlurMask::BlurGroundTruth to blur a 'width' x 'height' solid 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// white rect. Return the right half of the middle row in 'result'. 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void ground_truth_2d(int width, int height, 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar sigma, 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int* result, int resultCount) { 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMask src, dst; 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot src.fBounds.set(0, 0, width, height); 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot src.fFormat = SkMask::kA8_Format; 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot src.fRowBytes = src.fBounds.width(); 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot src.fImage = SkMask::AllocImage(src.computeTotalImageSize()); 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot memset(src.fImage, 0xff, src.computeTotalImageSize()); 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!SkBlurMask::BlurGroundTruth(sigma, &dst, src, kNormal_SkBlurStyle)) { 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int midX = dst.fBounds.centerX(); 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int midY = dst.fBounds.centerY(); 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint8_t* bytes = dst.getAddr8(midX, midY); 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int i; 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (i = 0; i < dst.fBounds.width()-(midX-dst.fBounds.fLeft); ++i) { 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (i < resultCount) { 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot result[i] = bytes[i]; 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for ( ; i < resultCount; ++i) { 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot result[i] = 0; 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMask::FreeImage(src.fImage); 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMask::FreeImage(dst.fImage); 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Implement a step function that is 255 between min and max; 0 elsewhere. 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic int step(int x, SkScalar min, SkScalar max) { 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (min < x && x < max) { 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return 255; 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return 0; 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Implement a Gaussian function with 0 mean and std.dev. of 'sigma'. 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic float gaussian(int x, SkScalar sigma) { 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float k = SK_Scalar1/(sigma * sqrtf(2.0f*SK_ScalarPI)); 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float exponent = -(x * x) / (2 * sigma * sigma); 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return k * expf(exponent); 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Perform a brute force convolution of a step function with a Gaussian. 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Return the right half in 'result' 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void brute_force_1d(SkScalar stepMin, SkScalar stepMax, 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar gaussianSigma, 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int* result, int resultCount) { 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int gaussianRange = SkScalarCeilToInt(10 * gaussianSigma); 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < resultCount; ++i) { 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar sum = 0.0f; 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int j = -gaussianRange; j < gaussianRange; ++j) { 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sum += gaussian(j, gaussianSigma) * step(i-j, stepMin, stepMax); 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot result[i] = SkClampMax(SkClampPos(int(sum + 0.5f)), 255); 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void blur_path(SkCanvas* canvas, const SkPath& path, 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar gaussianSigma) { 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar midX = path.getBounds().centerX(); 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar midY = path.getBounds().centerY(); 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->translate(-midX, -midY); 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint blurPaint; 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot blurPaint.setColor(SK_ColorWHITE); 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot blurPaint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, gaussianSigma, 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBlurMaskFilter::kHighQuality_BlurFlag)); 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawColor(SK_ColorBLACK); 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawPath(path, blurPaint); 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Readback the blurred draw results from the canvas 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void readback(const SkBitmap& src, int* result, int resultCount) { 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap readback; 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot readback.allocN32Pixels(resultCount, 30); 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPixmap pm; 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot readback.peekPixels(&pm); 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot src.readPixels(pm, 0, 0); 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPMColor* pixels = pm.addr32(0, 15); 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < resultCount; ++i) { 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot result[i] = SkColorGetR(pixels[i]); 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Draw a blurred version of the provided path. 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Return the right half of the middle row in 'result'. 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void cpu_blur_path(const SkPath& path, SkScalar gaussianSigma, 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int* result, int resultCount) { 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap bitmap; 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bitmap.allocN32Pixels(resultCount, 30); 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas canvas(bitmap); 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot blur_path(&canvas, path, gaussianSigma); 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot readback(bitmap, result, resultCount); 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if WRITE_CSV 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void write_as_csv(const char* label, SkScalar scale, int* data, int count) { 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("%s_%.2f,", label, scale); 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < count-1; ++i) { 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("%d,", data[i]); 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("%d\n", data[count-1]); 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic bool match(int* first, int* second, int count, int tol) { 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int delta; 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < count; ++i) { 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot delta = first[i] - second[i]; 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (delta > tol || delta < -tol) { 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Test out the normal blur style with a wide range of sigmas 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(BlurSigmaRange, reporter) { 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const int kSize = 100; 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The geometry is offset a smidge to trigger: 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // https://code.google.com/p/chromium/issues/detail?id=282418 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath rectPath; 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rectPath.addRect(0.3f, 0.3f, 100.3f, 100.3f); 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint polyPts[] = { 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 0.3f, 0.3f }, 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 100.3f, 0.3f }, 303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 100.3f, 100.3f }, 304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 0.3f, 100.3f }, 305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 2.3f, 50.3f } // a little divet to throw off the rect special case 306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath polyPath; 308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot polyPath.addPoly(polyPts, SK_ARRAY_COUNT(polyPts), true); 309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int rectSpecialCaseResult[kSize]; 311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int generalCaseResult[kSize]; 312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int groundTruthResult[kSize]; 313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int bruteForce1DResult[kSize]; 314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar sigma = 10.0f; 316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < 4; ++i, sigma /= 10) { 318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cpu_blur_path(rectPath, sigma, rectSpecialCaseResult, kSize); 320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cpu_blur_path(polyPath, sigma, generalCaseResult, kSize); 321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ground_truth_2d(100, 100, sigma, groundTruthResult, kSize); 323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot brute_force_1d(-50.0f, 50.0f, sigma, bruteForce1DResult, kSize); 324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, match(rectSpecialCaseResult, bruteForce1DResult, kSize, 5)); 326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, match(generalCaseResult, bruteForce1DResult, kSize, 15)); 327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, match(groundTruthResult, bruteForce1DResult, kSize, 1)); 328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if WRITE_CSV 330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot write_as_csv("RectSpecialCase", sigma, rectSpecialCaseResult, kSize); 331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot write_as_csv("GeneralCase", sigma, generalCaseResult, kSize); 332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot write_as_csv("GPU", sigma, gpuResult, kSize); 334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot write_as_csv("GroundTruth2D", sigma, groundTruthResult, kSize); 336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot write_as_csv("BruteForce1D", sigma, bruteForce1DResult, kSize); 337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////////////////// 342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic SkBlurQuality blurMaskFilterFlags_as_quality(uint32_t blurMaskFilterFlags) { 344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return (blurMaskFilterFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? 345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kHigh_SkBlurQuality : kLow_SkBlurQuality; 346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_blurDrawLooper(skiatest::Reporter* reporter, SkScalar sigma, 349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBlurStyle style, uint32_t blurMaskFilterFlags) { 350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (kNormal_SkBlurStyle != style) { 351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; // blurdrawlooper only supports normal 352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkColor color = 0xFF335577; 355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkScalar dx = 10; 356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkScalar dy = -5; 357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkDrawLooper> lp(SkBlurDrawLooper::Make(color, sigma, dx, dy)); 358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const bool expectSuccess = sigma > 0; 359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (nullptr == lp) { 361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, sigma <= 0); 362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDrawLooper::BlurShadowRec rec; 364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool success = lp->asABlurShadow(&rec); 365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, success == expectSuccess); 366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (success) { 367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, rec.fSigma == sigma); 368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, rec.fOffset.x() == dx); 369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, rec.fOffset.y() == dy); 370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, rec.fColor == color); 371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, rec.fStyle == style); 372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, rec.fQuality == kLow_SkBlurQuality); 373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_looper(skiatest::Reporter* reporter, sk_sp<SkDrawLooper> lp, SkScalar sigma, 378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBlurStyle style, SkBlurQuality quality, bool expectSuccess) { 379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDrawLooper::BlurShadowRec rec; 380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool success = lp->asABlurShadow(&rec); 381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, success == expectSuccess); 382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (success != expectSuccess) { 383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot lp->asABlurShadow(&rec); 384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (success) { 386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, rec.fSigma == sigma); 387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, rec.fStyle == style); 388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, rec.fQuality == quality); 389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void make_noop_layer(SkLayerDrawLooper::Builder* builder) { 393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkLayerDrawLooper::LayerInfo info; 394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fPaintBits = 0; 396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColorMode = SkBlendMode::kDst; 397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot builder->addLayer(info); 398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void make_blur_layer(SkLayerDrawLooper::Builder* builder, sk_sp<SkMaskFilter> mf) { 401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkLayerDrawLooper::LayerInfo info; 402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fPaintBits = SkLayerDrawLooper::kMaskFilter_Bit; 404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColorMode = SkBlendMode::kSrc; 405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint* paint = builder->addLayer(info); 406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint->setMaskFilter(std::move(mf)); 407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_layerDrawLooper(skiatest::Reporter* reporter, sk_sp<SkMaskFilter> mf, 410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar sigma, SkBlurStyle style, SkBlurQuality quality, 411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool expectSuccess) { 412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkLayerDrawLooper::LayerInfo info; 414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkLayerDrawLooper::Builder builder; 415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 1 layer is too few 417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot make_noop_layer(&builder); 418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_looper(reporter, builder.detach(), sigma, style, quality, false); 419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 2 layers is good, but need blur 421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot make_noop_layer(&builder); 422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot make_noop_layer(&builder); 423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_looper(reporter, builder.detach(), sigma, style, quality, false); 424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 2 layers is just right 426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot make_noop_layer(&builder); 427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot make_blur_layer(&builder, mf); 428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_looper(reporter, builder.detach(), sigma, style, quality, expectSuccess); 429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 3 layers is too many 431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot make_noop_layer(&builder); 432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot make_blur_layer(&builder, mf); 433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot make_noop_layer(&builder); 434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_looper(reporter, builder.detach(), sigma, style, quality, false); 435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(BlurAsABlur, reporter) { 438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkBlurStyle styles[] = { 439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kNormal_SkBlurStyle, kSolid_SkBlurStyle, kOuter_SkBlurStyle, kInner_SkBlurStyle 440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkScalar sigmas[] = { 442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // values <= 0 should not success for a blur 443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot -1, 0, 0.5f, 2 444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Test asABlur for SkBlurMaskFilter 447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t i = 0; i < SK_ARRAY_COUNT(styles); ++i) { 449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkBlurStyle style = styles[i]; 450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t j = 0; j < SK_ARRAY_COUNT(sigmas); ++j) { 451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkScalar sigma = sigmas[j]; 452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int flags = 0; flags <= SkBlurMaskFilter::kAll_BlurFlag; ++flags) { 453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkBlurQuality quality = blurMaskFilterFlags_as_quality(flags); 454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkMaskFilter> mf(SkBlurMaskFilter::Make(style, sigma, flags)); 456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (nullptr == mf.get()) { 457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, sigma <= 0); 458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, sigma > 0); 460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMaskFilterBase::BlurRec rec; 461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool success = as_MFB(mf)->asABlur(&rec); 462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (flags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) { 463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, !success); 464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, success); 466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, rec.fSigma == sigma); 467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, rec.fStyle == style); 468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, rec.fQuality == quality); 469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_layerDrawLooper(reporter, std::move(mf), sigma, style, quality, success); 471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_blurDrawLooper(reporter, sigma, style, flags); 473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Test asABlur for SkEmbossMaskFilter -- should never succeed 478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkEmbossMaskFilter::Light light = { 481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 1, 1, 1 }, 0, 127, 127 482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t j = 0; j < SK_ARRAY_COUNT(sigmas); ++j) { 484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkScalar sigma = sigmas[j]; 485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto mf(SkEmbossMaskFilter::Make(sigma, light)); 486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (mf) { 487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMaskFilterBase::BlurRec rec; 488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool success = as_MFB(mf)->asABlur(&rec); 489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, !success); 490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This exercises the problem discovered in crbug.com/570232. The return value from 498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// SkBlurMask::BoxBlur wasn't being checked in SkBlurMaskFilter.cpp::GrRRectBlurEffect::Create 499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SmallBoxBlurBug, reporter, ctxInfo) { 500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkImageInfo info = SkImageInfo::MakeN32Premul(128, 128); 502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto surface(SkSurface::MakeRenderTarget(ctxInfo.grContext(), SkBudgeted::kNo, info)); 503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = surface->getCanvas(); 504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect r = SkRect::MakeXYWH(10, 10, 100, 100); 506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect rr = SkRRect::MakeRectXY(r, 10, 10); 507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint p; 509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot p.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, 0.01f)); 510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRRect(rr, p); 512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(BlurredRRectNinePatchComputation, reporter) { 518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect r = SkRect::MakeXYWH(10, 10, 100, 100); 519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const SkScalar kBlurRad = 3.0f; 520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool ninePatchable; 522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect rrectToDraw; 523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkISize size; 524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar rectXs[SkBlurMaskFilter::kMaxDivisions], rectYs[SkBlurMaskFilter::kMaxDivisions]; 525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar texXs[SkBlurMaskFilter::kMaxDivisions], texYs[SkBlurMaskFilter::kMaxDivisions]; 526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int numX, numY; 527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint32_t skipMask; 528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // not nine-patchable 530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkVector radii[4] = { { 100, 100 }, { 0, 0 }, { 100, 100 }, { 0, 0 } }; 532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect rr; 534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rr.setRectRadii(r, radii); 535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams(rr, rr, SkRect::MakeEmpty(), 537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kBlurRad, kBlurRad, 538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &rrectToDraw, &size, 539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rectXs, rectYs, texXs, texYs, 540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &numX, &numY, &skipMask); 541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, !ninePatchable); 542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // simple circular 545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const SkScalar kCornerRad = 10.0f; 547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect rr; 548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rr.setRectXY(r, kCornerRad, kCornerRad); 549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams(rr, rr, SkRect::MakeEmpty(), 551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kBlurRad, kBlurRad, 552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &rrectToDraw, &size, 553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rectXs, rectYs, texXs, texYs, 554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &numX, &numY, &skipMask); 555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const SkScalar kAns = 12.0f * kBlurRad + 2.0f * kCornerRad + 1.0f; 557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, ninePatchable); 558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SkIntToScalar(size.fWidth), kAns)); 559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SkIntToScalar(size.fHeight), kAns)); 560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 4 == numX && 4 == numY); 561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, !skipMask); 562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // simple elliptical 565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const SkScalar kXCornerRad = 2.0f; 567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const SkScalar kYCornerRad = 10.0f; 568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect rr; 569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rr.setRectXY(r, kXCornerRad, kYCornerRad); 570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams(rr, rr, SkRect::MakeEmpty(), 572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kBlurRad, kBlurRad, 573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &rrectToDraw, &size, 574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rectXs, rectYs, texXs, texYs, 575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &numX, &numY, &skipMask); 576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const SkScalar kXAns = 12.0f * kBlurRad + 2.0f * kXCornerRad + 1.0f; 578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const SkScalar kYAns = 12.0f * kBlurRad + 2.0f * kYCornerRad + 1.0f; 579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, ninePatchable); 581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SkIntToScalar(size.fWidth), kXAns)); 582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SkIntToScalar(size.fHeight), kYAns)); 583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 4 == numX && 4 == numY); 584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, !skipMask); 585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // test-out occlusion 588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const SkScalar kCornerRad = 10.0f; 590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect rr; 591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rr.setRectXY(r, kCornerRad, kCornerRad); 592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The rectXs & rectYs should be { 1, 29, 91, 119 }. Add two more points around each. 594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar testLocs[] = { 595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot -18.0f, -9.0f, 596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1.0f, 597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 9.0f, 18.0f, 598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 29.0f, 599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 39.0f, 49.0f, 600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 91.0f, 601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 109.0f, 118.0f, 602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 119.0f, 603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 139.0f, 149.0f 604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int minY = 0; minY < (int)SK_ARRAY_COUNT(testLocs); ++minY) { 607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int maxY = minY+1; maxY < (int)SK_ARRAY_COUNT(testLocs); ++maxY) { 608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int minX = 0; minX < (int)SK_ARRAY_COUNT(testLocs); ++minX) { 609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int maxX = minX+1; maxX < (int)SK_ARRAY_COUNT(testLocs); ++maxX) { 610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect occluder = SkRect::MakeLTRB(testLocs[minX], testLocs[minY], 611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot testLocs[maxX], testLocs[maxY]); 612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (occluder.isEmpty()) { 613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot continue; 614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams( 617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rr, rr, occluder, 618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kBlurRad, kBlurRad, 619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &rrectToDraw, &size, 620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rectXs, rectYs, texXs, texYs, 621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &numX, &numY, &skipMask); 622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const SkScalar kAns = 12.0f * kBlurRad + 2.0f * kCornerRad + 1.0f; 624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, ninePatchable); 625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarNearlyEqual(SkIntToScalar(size.fWidth), kAns)); 627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarNearlyEqual(SkIntToScalar(size.fHeight), kAns)); 629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int checkBit = 0x1; 631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int y = 0; y < numY-1; ++y) { 632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int x = 0; x < numX-1; ++x) { 633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect cell = SkRect::MakeLTRB(rectXs[x], rectYs[y], 634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rectXs[x+1], rectYs[y+1]); 635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkToBool(skipMask & checkBit) == 637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (cell.isEmpty() || occluder.contains(cell))); 638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, texXs[x] >= 0 && 640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot texXs[x] <= size.fWidth); 641fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, texYs[y] >= 0 && 642fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot texXs[y] <= size.fHeight); 643fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 644fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot checkBit <<= 1; 645fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 646fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 647fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 648fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 649fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 650fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 651fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 652fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 653fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 654fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 655fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 656fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 657fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// https://crbugs.com/787712 658fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(EmbossPerlinCrash, reporter) { 659fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint p; 660fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 661fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static constexpr SkEmbossMaskFilter::Light light = { 662fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 1, 1, 1 }, 0, 127, 127 663fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 664fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot p.setMaskFilter(SkEmbossMaskFilter::Make(1, light)); 665fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot p.setShader(SkPerlinNoiseShader::MakeFractalNoise(1.0f, 1.0f, 2, 0.0f)); 666fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 667fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(100, 100); 668fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot surface->getCanvas()->drawPaint(p); 669fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 670fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 671fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////////////////// 672