1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2013 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 "SkDisplacementMapEffect.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBitmap.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorSpaceXformer.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkImageFilterPriv.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkReadBuffer.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSpecialImage.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkWriteBuffer.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkUnPreMultiply.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorData.h" 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrClip.h" 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrColorSpaceXform.h" 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContext.h" 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrCoordTransform.h" 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrRenderTargetContext.h" 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTexture.h" 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTextureProxy.h" 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGr.h" 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "effects/GrTextureDomain.h" 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "glsl/GrGLSLFragmentProcessor.h" 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "glsl/GrGLSLFragmentShaderBuilder.h" 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "glsl/GrGLSLProgramDataManager.h" 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "glsl/GrGLSLUniformHandler.h" 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace { 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define kChannelSelectorKeyBits 3; // Max value is 4, so 3 bits are required at most 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconst uint8_t gChannelTypeToShift[] = { 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 0, // unknown 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_R32_SHIFT, 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_G32_SHIFT, 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_B32_SHIFT, 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_A32_SHIFT, 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct Extractor { 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Extractor(SkDisplacementMapEffect::ChannelSelectorType typeX, 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDisplacementMapEffect::ChannelSelectorType typeY) 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : fShiftX(gChannelTypeToShift[typeX]) 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fShiftY(gChannelTypeToShift[typeY]) 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot {} 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned fShiftX, fShiftY; 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned getX(SkPMColor c) const { return (c >> fShiftX) & 0xFF; } 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned getY(SkPMColor c) const { return (c >> fShiftY) & 0xFF; } 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic SkPMColor unpremul_pm(SkPMColor c) { 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const U8CPU a = SkGetPackedA32(c); 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (0 == a) { 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return 0; 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else if (0xFF == a) { 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return c; 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const unsigned scale = SkUnPreMultiply::GetScale(a); 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkPackARGB32NoCheck(a, 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkUnPreMultiply::ApplyScale(scale, SkGetPackedR32(c)), 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkUnPreMultiply::ApplyScale(scale, SkGetPackedG32(c)), 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkUnPreMultiply::ApplyScale(scale, SkGetPackedB32(c))); 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid computeDisplacement(Extractor ex, const SkVector& scale, SkBitmap* dst, 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkBitmap& displ, const SkIPoint& offset, 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkBitmap& src, 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkIRect& bounds) { 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const SkScalar Inv8bit = SkScalarInvert(255); 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const int srcW = src.width(); 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const int srcH = src.height(); 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkVector scaleForColor = SkVector::Make(scale.fX * Inv8bit, scale.fY * Inv8bit); 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkVector scaleAdj = SkVector::Make(SK_ScalarHalf - scale.fX * SK_ScalarHalf, 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ScalarHalf - scale.fY * SK_ScalarHalf); 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPMColor* dstPtr = dst->getAddr32(0, 0); 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int y = bounds.top(); y < bounds.bottom(); ++y) { 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPMColor* displPtr = displ.getAddr32(bounds.left() + offset.fX, y + offset.fY); 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int x = bounds.left(); x < bounds.right(); ++x, ++displPtr) { 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPMColor c = unpremul_pm(*displPtr); 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar displX = scaleForColor.fX * ex.getX(c) + scaleAdj.fX; 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar displY = scaleForColor.fY * ex.getY(c) + scaleAdj.fY; 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Truncate the displacement values 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const int srcX = x + SkScalarTruncToInt(displX); 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const int srcY = y + SkScalarTruncToInt(displY); 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *dstPtr++ = ((srcX < 0) || (srcX >= srcW) || (srcY < 0) || (srcY >= srcH)) ? 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 0 : *(src.getAddr32(srcX, srcY)); 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool channel_selector_type_is_valid(SkDisplacementMapEffect::ChannelSelectorType cst) { 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (cst) { 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kUnknown_ChannelSelectorType: 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kR_ChannelSelectorType: 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kG_ChannelSelectorType: 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kB_ChannelSelectorType: 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kA_ChannelSelectorType: 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot default: 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} // end namespace 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////// 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkImageFilter> SkDisplacementMapEffect::Make(ChannelSelectorType xChannelSelector, 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ChannelSelectorType yChannelSelector, 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar scale, 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkImageFilter> displacement, 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkImageFilter> color, 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const CropRect* cropRect) { 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!channel_selector_type_is_valid(xChannelSelector) || 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot !channel_selector_type_is_valid(yChannelSelector)) { 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkImageFilter> inputs[2] = { std::move(displacement), std::move(color) }; 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return sk_sp<SkImageFilter>(new SkDisplacementMapEffect(xChannelSelector, 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot yChannelSelector, 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot scale, inputs, cropRect)); 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkDisplacementMapEffect::SkDisplacementMapEffect(ChannelSelectorType xChannelSelector, 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ChannelSelectorType yChannelSelector, 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar scale, 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkImageFilter> inputs[2], 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const CropRect* cropRect) 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(inputs, 2, cropRect) 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fXChannelSelector(xChannelSelector) 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fYChannelSelector(yChannelSelector) 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fScale(scale) { 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkDisplacementMapEffect::~SkDisplacementMapEffect() { 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkFlattenable> SkDisplacementMapEffect::CreateProc(SkReadBuffer& buffer) { 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2); 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ChannelSelectorType xsel = buffer.read32LE(kLast_ChannelSelectorType); 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ChannelSelectorType ysel = buffer.read32LE(kLast_ChannelSelectorType); 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar scale = buffer.readScalar(); 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return Make(xsel, ysel, scale, common.getInput(0), common.getInput(1), &common.cropRect()); 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkDisplacementMapEffect::flatten(SkWriteBuffer& buffer) const { 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->INHERITED::flatten(buffer); 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot buffer.writeInt((int) fXChannelSelector); 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot buffer.writeInt((int) fYChannelSelector); 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot buffer.writeScalar(fScale); 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrDisplacementMapEffect : public GrFragmentProcessor { 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static std::unique_ptr<GrFragmentProcessor> Make( 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, SkVector scale, 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrTextureProxy> displacement, const SkMatrix& offsetMatrix, 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrTextureProxy> color, const SkISize& colorDimensions) { 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return std::unique_ptr<GrFragmentProcessor>(new GrDisplacementMapEffect( 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xChannelSelector, yChannelSelector, scale, std::move(displacement), offsetMatrix, 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::move(color), colorDimensions)); 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ~GrDisplacementMapEffect() override; 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDisplacementMapEffect::ChannelSelectorType xChannelSelector() const { 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fXChannelSelector; 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDisplacementMapEffect::ChannelSelectorType yChannelSelector() const { 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fYChannelSelector; 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkVector& scale() const { return fScale; } 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* name() const override { return "DisplacementMap"; } 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrTextureDomain& domain() const { return fDomain; } 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::unique_ptr<GrFragmentProcessor> clone() const override; 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static OptimizationFlags OptimizationFlags(GrPixelConfig colorConfig); 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrDisplacementMapEffect(const GrDisplacementMapEffect&); 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override; 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool onIsEqual(const GrFragmentProcessor&) const override; 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkVector& scale, 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrTextureProxy> displacement, const SkMatrix& offsetMatrix, 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrTextureProxy> color, const SkISize& colorDimensions); 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GR_DECLARE_FRAGMENT_PROCESSOR_TEST 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrCoordTransform fDisplacementTransform; 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TextureSampler fDisplacementSampler; 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrCoordTransform fColorTransform; 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrTextureDomain fDomain; 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TextureSampler fColorSampler; 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector; 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector; 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkVector fScale; 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef GrFragmentProcessor INHERITED; 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkSpecialImage> SkDisplacementMapEffect::onFilterImage(SkSpecialImage* source, 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const Context& ctx, 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIPoint* offset) const { 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIPoint colorOffset = SkIPoint::Make(0, 0); 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkSpecialImage> color(this->filterInput(1, source, ctx, &colorOffset)); 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!color) { 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIPoint displOffset = SkIPoint::Make(0, 0); 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Creation of the displacement map should happen in a non-colorspace aware context. This 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // texture is a purely mathematical construct, so we want to just operate on the stored 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // values. Consider: 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // User supplies an sRGB displacement map. If we're rendering to a wider gamut, then we could 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // end up filtering the displacement map into that gamut, which has the effect of reducing 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // the amount of displacement that it represents (as encoded values move away from the 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // primaries). 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // With a more complex DAG attached to this input, it's not clear that working in ANY specific 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // color space makes sense, so we ignore color spaces (and gamma) entirely. This may not be 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // ideal, but it's at least consistent and predictable. 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Context displContext(ctx.ctm(), ctx.clipBounds(), ctx.cache(), OutputProperties(nullptr)); 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkSpecialImage> displ(this->filterInput(0, source, displContext, &displOffset)); 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!displ) { 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkIRect srcBounds = SkIRect::MakeXYWH(colorOffset.x(), colorOffset.y(), 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot color->width(), color->height()); 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Both paths do bounds checking on color pixel access, we don't need to 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // pad the color bitmap to bounds here. 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect bounds; 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!this->applyCropRect(ctx, srcBounds, &bounds)) { 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect displBounds; 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot displ = this->applyCropRect(ctx, displ.get(), &displOffset, &displBounds); 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!displ) { 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!bounds.intersect(displBounds)) { 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkIRect colorBounds = bounds.makeOffset(-colorOffset.x(), -colorOffset.y()); 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkVector scale = SkVector::Make(fScale, fScale); 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ctx.ctm().mapVectors(&scale, 1); 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (source->isTextureBacked()) { 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrContext* context = source->getContext(); 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrTextureProxy> colorProxy(color->asTextureProxyRef(context)); 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrTextureProxy> displProxy(displ->asTextureProxyRef(context)); 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!colorProxy || !displProxy) { 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix offsetMatrix = SkMatrix::MakeTrans(SkIntToScalar(colorOffset.fX - displOffset.fX), 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(colorOffset.fY - displOffset.fY)); 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkColorSpace* colorSpace = ctx.outputProperties().colorSpace(); 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrPixelConfig colorConfig = colorProxy->config(); 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::unique_ptr<GrFragmentProcessor> fp = 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrDisplacementMapEffect::Make(fXChannelSelector, 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fYChannelSelector, 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot scale, 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::move(displProxy), 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot offsetMatrix, 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::move(colorProxy), 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkISize::Make(color->width(), color->height())); 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fp = GrColorSpaceXformEffect::Make(std::move(fp), color->getColorSpace(), colorConfig, 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot colorSpace); 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrPaint paint; 303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.addColorFragmentProcessor(std::move(fp)); 304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setPorterDuffXPFactory(SkBlendMode::kSrc); 305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix matrix; 306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colorBounds.y())); 307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrRenderTargetContext> renderTargetContext( 309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot context->makeDeferredRenderTargetContext(SkBackingFit::kApprox, 310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bounds.width(), bounds.height(), 311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrRenderableConfigForColorSpace(colorSpace), 312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_ref_sp(colorSpace))); 313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!renderTargetContext) { 314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setGammaCorrect(renderTargetContext->colorSpaceInfo().isGammaCorrect()); 317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, matrix, 319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect::Make(colorBounds)); 320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot offset->fX = bounds.left(); 322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot offset->fY = bounds.top(); 323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkSpecialImage::MakeDeferredFromGpu( 324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot context, 325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect::MakeWH(bounds.width(), bounds.height()), 326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kNeedNewImageUniqueID_SpecialImage, 327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot renderTargetContext->asTextureProxyRef(), 328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot renderTargetContext->colorSpaceInfo().refColorSpace()); 329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap colorBM, displBM; 333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!color->getROPixels(&colorBM) || !displ->getROPixels(&displBM)) { 335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if ((colorBM.colorType() != kN32_SkColorType) || 339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (displBM.colorType() != kN32_SkColorType)) { 340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!colorBM.getPixels() || !displBM.getPixels()) { 344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkImageInfo info = SkImageInfo::MakeN32(bounds.width(), bounds.height(), 348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot colorBM.alphaType()); 349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap dst; 351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!dst.tryAllocPixels(info)) { 352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot computeDisplacement(Extractor(fXChannelSelector, fYChannelSelector), scale, &dst, 356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot displBM, colorOffset - displOffset, colorBM, colorBounds); 357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot offset->fX = bounds.left(); 359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot offset->fY = bounds.top(); 360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkSpecialImage::MakeFromRaster(SkIRect::MakeWH(bounds.width(), bounds.height()), 361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dst); 362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkImageFilter> SkDisplacementMapEffect::onMakeColorSpace(SkColorSpaceXformer* xformer) const { 365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(2 == this->countInputs()); 366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Intentionally avoid xforming the displacement filter. The values will be used as 367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // offsets, not as colors. 368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkImageFilter> displacement = sk_ref_sp(const_cast<SkImageFilter*>(this->getInput(0))); 369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkImageFilter> color = xformer->apply(this->getInput(1)); 370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (color.get() != this->getInput(1)) { 372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkDisplacementMapEffect::Make(fXChannelSelector, fYChannelSelector, fScale, 373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::move(displacement), std::move(color), 374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->getCropRectIfSet()); 375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->refMe(); 377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkRect SkDisplacementMapEffect::computeFastBounds(const SkRect& src) const { 380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect bounds = this->getColorInput() ? this->getColorInput()->computeFastBounds(src) : src; 381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bounds.outset(SkScalarAbs(fScale) * SK_ScalarHalf, SkScalarAbs(fScale) * SK_ScalarHalf); 382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return bounds; 383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkIRect SkDisplacementMapEffect::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm, 386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot MapDirection) const { 387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkVector scale = SkVector::Make(fScale, fScale); 388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ctm.mapVectors(&scale, 1); 389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return src.makeOutset(SkScalarCeilToInt(SkScalarAbs(scale.fX) * SK_ScalarHalf), 390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarCeilToInt(SkScalarAbs(scale.fY) * SK_ScalarHalf)); 391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkIRect SkDisplacementMapEffect::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot MapDirection direction) const { 395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Recurse only into color input. 396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->getColorInput()) { 397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->getColorInput()->filterBounds(src, ctm, direction); 398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return src; 400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SK_IGNORE_TO_STRING 403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkDisplacementMapEffect::toString(SkString* str) const { 404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str->appendf("SkDisplacementMapEffect: ("); 405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str->appendf("scale: %f ", fScale); 406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str->appendf("displacement: ("); 407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->getDisplacementInput()) { 408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->getDisplacementInput()->toString(str); 409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str->appendf(") color: ("); 411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->getColorInput()) { 412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->getColorInput()->toString(str); 413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str->appendf("))"); 415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////// 419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrGLDisplacementMapEffect : public GrGLSLFragmentProcessor { 422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void emitCode(EmitArgs&) override; 424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static inline void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*); 426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected: 428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override; 429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; 432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot UniformHandle fScaleUni; 434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrTextureDomain::GLDomain fGLDomain; 435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef GrGLSLFragmentProcessor INHERITED; 437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////// 440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrGLSLFragmentProcessor* GrDisplacementMapEffect::onCreateGLSLInstance() const { 442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return new GrGLDisplacementMapEffect; 443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrDisplacementMapEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, 446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrProcessorKeyBuilder* b) const { 447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLDisplacementMapEffect::GenKey(*this, caps, b); 448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrFragmentProcessor::OptimizationFlags GrDisplacementMapEffect::OptimizationFlags( 451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrPixelConfig colorConfig) { 452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return GrPixelConfigIsOpaque(colorConfig) 453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? GrFragmentProcessor::kPreservesOpaqueInput_OptimizationFlag 454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : GrFragmentProcessor::kNone_OptimizationFlags; 455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrDisplacementMapEffect::GrDisplacementMapEffect( 458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, 459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, 460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkVector& scale, 461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrTextureProxy> displacement, 462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& offsetMatrix, 463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrTextureProxy> color, 464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkISize& colorDimensions) 465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(kGrDisplacementMapEffect_ClassID, OptimizationFlags(color->config())) 466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fDisplacementTransform(offsetMatrix, displacement.get()) 467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fDisplacementSampler(displacement) 468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fColorTransform(color.get()) 469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fDomain(color.get(), GrTextureDomain::MakeTexelDomain(SkIRect::MakeSize(colorDimensions)), 470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrTextureDomain::kDecal_Mode) 471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fColorSampler(color) 472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fXChannelSelector(xChannelSelector) 473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fYChannelSelector(yChannelSelector) 474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fScale(scale) { 475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addCoordTransform(&fDisplacementTransform); 476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addTextureSampler(&fDisplacementSampler); 477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addCoordTransform(&fColorTransform); 478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addTextureSampler(&fColorSampler); 479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrDisplacementMapEffect::GrDisplacementMapEffect(const GrDisplacementMapEffect& that) 482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(kGrDisplacementMapEffect_ClassID, 483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot OptimizationFlags(that.fColorSampler.proxy()->config())) 484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fDisplacementTransform(that.fDisplacementTransform) 485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fDisplacementSampler(that.fDisplacementSampler) 486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fColorTransform(that.fColorTransform) 487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fDomain(that.fDomain) 488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fColorSampler(that.fColorSampler) 489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fXChannelSelector(that.fXChannelSelector) 490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fYChannelSelector(that.fYChannelSelector) 491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fScale(that.fScale) { 492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addCoordTransform(&fDisplacementTransform); 493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addTextureSampler(&fDisplacementSampler); 494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addCoordTransform(&fColorTransform); 495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addTextureSampler(&fColorSampler); 496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrDisplacementMapEffect::~GrDisplacementMapEffect() {} 499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstd::unique_ptr<GrFragmentProcessor> GrDisplacementMapEffect::clone() const { 501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return std::unique_ptr<GrFragmentProcessor>(new GrDisplacementMapEffect(*this)); 502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool GrDisplacementMapEffect::onIsEqual(const GrFragmentProcessor& sBase) const { 505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrDisplacementMapEffect& s = sBase.cast<GrDisplacementMapEffect>(); 506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fXChannelSelector == s.fXChannelSelector && 507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fYChannelSelector == s.fYChannelSelector && 508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fScale == s.fScale; 509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////// 512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDisplacementMapEffect); 514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_TEST_UTILS 516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstd::unique_ptr<GrFragmentProcessor> GrDisplacementMapEffect::TestCreate(GrProcessorTestData* d) { 517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int texIdxDispl = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrProcessorUnitTest::kAlphaTextureIdx; 519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int texIdxColor = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrProcessorUnitTest::kAlphaTextureIdx; 521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrTextureProxy> dispProxy = d->textureProxy(texIdxDispl); 522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrTextureProxy> colorProxy = d->textureProxy(texIdxColor); 523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const int kMaxComponent = 4; 524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDisplacementMapEffect::ChannelSelectorType xChannelSelector = 525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static_cast<SkDisplacementMapEffect::ChannelSelectorType>( 526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot d->fRandom->nextRangeU(1, kMaxComponent)); 527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDisplacementMapEffect::ChannelSelectorType yChannelSelector = 528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static_cast<SkDisplacementMapEffect::ChannelSelectorType>( 529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot d->fRandom->nextRangeU(1, kMaxComponent)); 530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkVector scale = SkVector::Make(d->fRandom->nextRangeScalar(0, 100.0f), 531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot d->fRandom->nextRangeScalar(0, 100.0f)); 532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkISize colorDimensions; 533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot colorDimensions.fWidth = d->fRandom->nextRangeU(0, colorProxy->width()); 534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot colorDimensions.fHeight = d->fRandom->nextRangeU(0, colorProxy->height()); 535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return GrDisplacementMapEffect::Make(xChannelSelector, yChannelSelector, scale, 536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::move(dispProxy), SkMatrix::I(), 537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::move(colorProxy), colorDimensions); 538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////// 543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrGLDisplacementMapEffect::emitCode(EmitArgs& args) { 545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrDisplacementMapEffect& displacementMap = args.fFp.cast<GrDisplacementMapEffect>(); 546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrTextureDomain& domain = displacementMap.domain(); 547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fScaleUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, "Scale"); 549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* scaleUni = args.fUniformHandler->getUniformCStr(fScaleUni); 550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* dColor = "dColor"; 551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* cCoords = "cCoords"; 552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* nearZero = "1e-6"; // Since 6.10352e-5 is the smallest half float, use 553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // a number smaller than that to approximate 0, but 554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // leave room for 32-bit float GPU rounding errors. 555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppendf("\t\thalf4 %s = ", dColor); 558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->appendTextureLookup(args.fTexSamplers[0], args.fTransformedCoords[0].c_str(), 559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fTransformedCoords[0].getType()); 560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppend(";\n"); 561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Unpremultiply the displacement 563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppendf( 564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "\t\t%s.rgb = (%s.a < %s) ? half3(0.0) : clamp(%s.rgb / %s.a, 0.0, 1.0);", 565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dColor, dColor, nearZero, dColor, dColor); 566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[1]); 567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppendf("\t\tfloat2 %s = %s + %s*(%s.", 568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cCoords, coords2D.c_str(), scaleUni, dColor); 569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (displacementMap.xChannelSelector()) { 571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kR_ChannelSelectorType: 572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppend("r"); 573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kG_ChannelSelectorType: 575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppend("g"); 576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kB_ChannelSelectorType: 578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppend("b"); 579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kA_ChannelSelectorType: 581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppend("a"); 582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kUnknown_ChannelSelectorType: 584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot default: 585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGFAIL("Unknown X channel selector"); 586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (displacementMap.yChannelSelector()) { 589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kR_ChannelSelectorType: 590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppend("r"); 591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kG_ChannelSelectorType: 593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppend("g"); 594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kB_ChannelSelectorType: 596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppend("b"); 597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kA_ChannelSelectorType: 599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppend("a"); 600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkDisplacementMapEffect::kUnknown_ChannelSelectorType: 602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot default: 603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGFAIL("Unknown Y channel selector"); 604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppend("-half2(0.5));\t\t"); 606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGLDomain.sampleTexture(fragBuilder, 608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fUniformHandler, 609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fShaderCaps, 610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot domain, 611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fOutputColor, 612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString(cCoords), 613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot args.fTexSamplers[1]); 614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fragBuilder->codeAppend(";\n"); 615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrGLDisplacementMapEffect::onSetData(const GrGLSLProgramDataManager& pdman, 618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrFragmentProcessor& proc) { 619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrDisplacementMapEffect& displacementMap = proc.cast<GrDisplacementMapEffect>(); 620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSurfaceProxy* proxy = displacementMap.textureSampler(1).proxy(); 621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrTexture* colorTex = proxy->priv().peekTexture(); 622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar scaleX = displacementMap.scale().fX / colorTex->width(); 624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar scaleY = displacementMap.scale().fY / colorTex->height(); 625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot pdman.set2f(fScaleUni, SkScalarToFloat(scaleX), 626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot proxy->origin() == kTopLeft_GrSurfaceOrigin ? 627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFloat(scaleY) : SkScalarToFloat(-scaleY)); 628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGLDomain.setData(pdman, displacementMap.domain(), proxy); 629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrGLDisplacementMapEffect::GenKey(const GrProcessor& proc, 632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrShaderCaps&, GrProcessorKeyBuilder* b) { 633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrDisplacementMapEffect& displacementMap = proc.cast<GrDisplacementMapEffect>(); 634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint32_t xKey = displacementMap.xChannelSelector(); 636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint32_t yKey = displacementMap.yChannelSelector() << kChannelSelectorKeyBits; 637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot b->add32(xKey | yKey); 639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 641