1c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org/* 2c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org * Copyright 2014 Google Inc. 3c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org * 4c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be 5c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org * found in the LICENSE file. 6c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org */ 7c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 830ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/builders/GrGLProgramBuilder.h" 9c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org#include "GrConvexPolyEffect.h" 10c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 11b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h" 12c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org#include "gl/GrGLSL.h" 13b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrTBackendProcessorFactory.h" 14c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 15c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org#include "SkPath.h" 16c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 17f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 18f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.orgclass GLAARectEffect; 19f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 20b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass AARectEffect : public GrFragmentProcessor { 21f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.orgpublic: 22b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GLAARectEffect GLProcessor; 23f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 24f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const SkRect& getRect() const { return fRect; } 25f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 26f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org static const char* Name() { return "AARect"; } 27f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 28b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static GrFragmentProcessor* Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) { 2955fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(AARectEffect, (edgeType, rect)); 30f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org } 31f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 32f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org virtual void getConstantColorComponents(GrColor* color, 33f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org uint32_t* validFlags) const SK_OVERRIDE { 34f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org if (fRect.isEmpty()) { 35f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org // An empty rect will have no coverage anywhere. 36f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org *color = 0x00000000; 37f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org *validFlags = kRGBA_GrColorComponentFlags; 38f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org } else { 39f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org *validFlags = 0; 40f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org } 41f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org } 42f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 43b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } 44d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org 45b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; 46f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 47f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.orgprivate: 48b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt AARectEffect(GrPrimitiveEdgeType edgeType, const SkRect& rect) : fRect(rect), fEdgeType(edgeType) { 49f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org this->setWillReadFragmentPosition(); 50f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org } 51f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 52b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE { 5349586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const AARectEffect& aare = other.cast<AARectEffect>(); 54f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org return fRect == aare.fRect; 55f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org } 56f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 57b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkRect fRect; 58b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType fEdgeType; 59d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org 60b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrFragmentProcessor INHERITED; 61f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 62b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 63f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 64f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org}; 65f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 66b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(AARectEffect); 67f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 68b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* AARectEffect::TestCreate(SkRandom* random, 69b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 70b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps& caps, 71b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture*[]) { 72f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org SkRect rect = SkRect::MakeLTRB(random->nextSScalar1(), 73f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org random->nextSScalar1(), 74f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org random->nextSScalar1(), 75f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org random->nextSScalar1()); 76b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrFragmentProcessor* fp; 77cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org do { 78b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->nextULessThan( 79b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt kGrProcessorEdgeTypeCnt)); 80cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org 81b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fp = AARectEffect::Create(edgeType, rect); 82b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt } while (NULL == fp); 83b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return fp; 84f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org} 85f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 86f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 87f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 88b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GLAARectEffect : public GrGLFragmentProcessor { 89f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.orgpublic: 90b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GLAARectEffect(const GrBackendProcessorFactory&, const GrProcessor&); 91f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 9230ba436f04e61d4505fb854d5fc56079636e0788joshualitt virtual void emitCode(GrGLProgramBuilder* builder, 93b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor& fp, 94b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 95f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const char* outputColor, 96f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const char* inputColor, 97f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const TransformedCoordsArray&, 98f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const TextureSamplerArray&) SK_OVERRIDE; 99f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 100b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*); 101f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 102b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE; 103f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 104f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.orgprivate: 1057510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fRectUniform; 1067510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkRect fPrevRect; 107b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLFragmentProcessor INHERITED; 108f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org}; 109f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 110b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGLAARectEffect::GLAARectEffect(const GrBackendProcessorFactory& factory, 111b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor& effect) 112f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org : INHERITED (factory) { 113f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org fPrevRect.fLeft = SK_ScalarNaN; 114f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org} 115f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 11630ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GLAARectEffect::emitCode(GrGLProgramBuilder* builder, 117b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor& fp, 118b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 119f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const char* outputColor, 120f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const char* inputColor, 121f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const TransformedCoordsArray&, 122f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const TextureSamplerArray& samplers) { 123b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const AARectEffect& aare = fp.cast<AARectEffect>(); 124f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const char *rectName; 125d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5), 126d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org // respectively. 12730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 128f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org kVec4f_GrSLType, 129f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org "rect", 130f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org &rectName); 13130ba436f04e61d4505fb854d5fc56079636e0788joshualitt 13230ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 13330ba436f04e61d4505fb854d5fc56079636e0788joshualitt const char* fragmentPos = fsBuilder->fragmentPosition(); 134b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (GrProcessorEdgeTypeIsAA(aare.getEdgeType())) { 135d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org // The amount of coverage removed in x and y by the edges is computed as a pair of negative 136d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org // numbers, xSub and ySub. 13730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n"); 13830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName); 13930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos); 14030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName); 14130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos); 142d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org // Now compute coverage in x and y and multiply them to get the fraction of the pixel 143d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org // covered. 14430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); 145d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org } else { 14630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); 14730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName); 14830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos); 14930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName); 15030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\talpha *= (%s.w - %s.y) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos); 151d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org } 152f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 153b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (GrProcessorEdgeTypeIsInverseFill(aare.getEdgeType())) { 15430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n"); 155d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org } 15630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, 157f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); 158f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org} 159f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 160b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLAARectEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) { 161b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const AARectEffect& aare = processor.cast<AARectEffect>(); 162f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const SkRect& rect = aare.getRect(); 163f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org if (rect != fPrevRect) { 1647510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f, 165f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org rect.fRight - 0.5f, rect.fBottom - 0.5f); 166f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org fPrevRect = rect; 167f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org } 168f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org} 169f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 170b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLAARectEffect::GenKey(const GrProcessor& processor, const GrGLCaps&, 171b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 172b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const AARectEffect& aare = processor.cast<AARectEffect>(); 17363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon b->add32(aare.getEdgeType()); 174d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org} 175d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org 176b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendFragmentProcessorFactory& AARectEffect::getFactory() const { 177b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return GrTBackendFragmentProcessorFactory<AARectEffect>::getInstance(); 178f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org} 179f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 180f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 181f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 182b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLConvexPolyEffect : public GrGLFragmentProcessor { 183c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.orgpublic: 184b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGLConvexPolyEffect(const GrBackendProcessorFactory&, const GrProcessor&); 185c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 18630ba436f04e61d4505fb854d5fc56079636e0788joshualitt virtual void emitCode(GrGLProgramBuilder* builder, 187b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor& fp, 188b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 189c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const char* outputColor, 190c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const char* inputColor, 191c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const TransformedCoordsArray&, 192c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const TextureSamplerArray&) SK_OVERRIDE; 193c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 194b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*); 195c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 196b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE; 197c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 198c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.orgprivate: 1997510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fEdgeUniform; 2007510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkScalar fPrevEdges[3 * GrConvexPolyEffect::kMaxEdges]; 201b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLFragmentProcessor INHERITED; 202c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org}; 203c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 204b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGLConvexPolyEffect::GrGLConvexPolyEffect(const GrBackendProcessorFactory& factory, 205b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor&) 206c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org : INHERITED (factory) { 207c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org fPrevEdges[0] = SK_ScalarNaN; 208c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 209c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 21030ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GrGLConvexPolyEffect::emitCode(GrGLProgramBuilder* builder, 211b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor& fp, 212b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 213c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const char* outputColor, 214c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const char* inputColor, 215c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const TransformedCoordsArray&, 216c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const TextureSamplerArray& samplers) { 217b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrConvexPolyEffect& cpe = fp.cast<GrConvexPolyEffect>(); 218c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 219c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const char *edgeArrayName; 22030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fEdgeUniform = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility, 221c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org kVec3f_GrSLType, 222c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org "edges", 223c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org cpe.getEdgeCount(), 224c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org &edgeArrayName); 22530ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 22630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tfloat alpha = 1.0;\n"); 22730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tfloat edge;\n"); 22830ba436f04e61d4505fb854d5fc56079636e0788joshualitt const char* fragmentPos = fsBuilder->fragmentPosition(); 229c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org for (int i = 0; i < cpe.getEdgeCount(); ++i) { 23030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n", 231c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org edgeArrayName, i, fragmentPos, fragmentPos); 232b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) { 23330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n"); 234cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org } else { 23530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n"); 236c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 23730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\talpha *= edge;\n"); 238c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 239c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 2406dee8759ab8c90dcffd76f114eec333405fd176ecommit-bot@chromium.org // Woe is me. See skbug.com/2149. 2416dee8759ab8c90dcffd76f114eec333405fd176ecommit-bot@chromium.org if (kTegra2_GrGLRenderer == builder->ctxInfo().renderer()) { 24230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n"); 2436dee8759ab8c90dcffd76f114eec333405fd176ecommit-bot@chromium.org } 244d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org 245b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (GrProcessorEdgeTypeIsInverseFill(cpe.getEdgeType())) { 24630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\talpha = 1.0 - alpha;\n"); 247d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org } 24830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, 249c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); 250c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 251c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 252b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GrGLConvexPolyEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& effect) { 25349586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrConvexPolyEffect& cpe = effect.cast<GrConvexPolyEffect>(); 254c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar); 255c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) { 2567510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges()); 257c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org memcpy(fPrevEdges, cpe.getEdges(), byteSize); 258c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 259c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 260c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 261b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GrGLConvexPolyEffect::GenKey(const GrProcessor& processor, const GrGLCaps&, 262b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 263b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrConvexPolyEffect& cpe = processor.cast<GrConvexPolyEffect>(); 264b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_STATIC_ASSERT(kGrProcessorEdgeTypeCnt <= 8); 26563e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon uint32_t key = (cpe.getEdgeCount() << 3) | cpe.getEdgeType(); 26663e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon b->add32(key); 267c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 268c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 269c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 270c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 271b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType type, const SkPath& path, 272b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const SkVector* offset) { 273b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (kHairlineAA_GrProcessorEdgeType == type) { 274cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org return NULL; 275cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org } 276c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org if (path.getSegmentMasks() != SkPath::kLine_SegmentMask || 277cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org !path.isConvex()) { 278c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org return NULL; 279c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 280c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 281c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org if (path.countPoints() > kMaxEdges) { 282c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org return NULL; 283c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 284c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 285c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkPoint pts[kMaxEdges]; 286c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkScalar edges[3 * kMaxEdges]; 287c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 288c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkPath::Direction dir; 289c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkAssertResult(path.cheapComputeDirection(&dir)); 290c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 291b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org SkVector t; 292b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org if (NULL == offset) { 293b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org t.set(0, 0); 294b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org } else { 295b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org t = *offset; 296b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org } 297b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org 298c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org int count = path.getPoints(pts, kMaxEdges); 299c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org int n = 0; 300c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org for (int lastPt = count - 1, i = 0; i < count; lastPt = i++) { 301c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org if (pts[lastPt] != pts[i]) { 302c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkVector v = pts[i] - pts[lastPt]; 303c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org v.normalize(); 304c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org if (SkPath::kCCW_Direction == dir) { 305c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org edges[3 * n] = v.fY; 306c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org edges[3 * n + 1] = -v.fX; 307c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } else { 308c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org edges[3 * n] = -v.fY; 309c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org edges[3 * n + 1] = v.fX; 310c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 311b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org SkPoint p = pts[i] + t; 312b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org edges[3 * n + 2] = -(edges[3 * n] * p.fX + edges[3 * n + 1] * p.fY); 313c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org ++n; 314c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 315c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 316cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org if (path.isInverseFillType()) { 317b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt type = GrInvertProcessorEdgeType(type); 318cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org } 319c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org return Create(type, n, edges); 320c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 321c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 322b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) { 323b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (kHairlineAA_GrProcessorEdgeType == edgeType){ 324cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org return NULL; 325cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org } 326d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org return AARectEffect::Create(edgeType, rect); 327f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org} 328f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 329c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.orgGrConvexPolyEffect::~GrConvexPolyEffect() {} 330c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 331c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.orgvoid GrConvexPolyEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { 332c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org *validFlags = 0; 333c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 334c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 335b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendFragmentProcessorFactory& GrConvexPolyEffect::getFactory() const { 336b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return GrTBackendFragmentProcessorFactory<GrConvexPolyEffect>::getInstance(); 337c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 338c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 339b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrConvexPolyEffect::GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, const SkScalar edges[]) 340c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org : fEdgeType(edgeType) 341c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org , fEdgeCount(n) { 342c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org // Factory function should have already ensured this. 343c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkASSERT(n <= kMaxEdges); 344c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org memcpy(fEdges, edges, 3 * n * sizeof(SkScalar)); 345c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org // Outset the edges by 0.5 so that a pixel with center on an edge is 50% covered in the AA case 346c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org // and 100% covered in the non-AA case. 347c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org for (int i = 0; i < n; ++i) { 348c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org fEdges[3 * i + 2] += SK_ScalarHalf; 349c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 350c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org this->setWillReadFragmentPosition(); 351c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 352c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 353b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool GrConvexPolyEffect::onIsEqual(const GrProcessor& other) const { 35449586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrConvexPolyEffect& cpe = other.cast<GrConvexPolyEffect>(); 355c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org // ignore the fact that 0 == -0 and just use memcmp. 356c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org return (cpe.fEdgeType == fEdgeType && cpe.fEdgeCount == fEdgeCount && 357c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 0 == memcmp(cpe.fEdges, fEdges, 3 * fEdgeCount * sizeof(SkScalar))); 358c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 359c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 360c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 361c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 362b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConvexPolyEffect); 363c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 364b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrConvexPolyEffect::TestCreate(SkRandom* random, 365b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 366b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps& caps, 367b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture*[]) { 36865ee5f424cb4dabd453268902c00086605d77c1dcommit-bot@chromium.org int count = random->nextULessThan(kMaxEdges) + 1; 369c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkScalar edges[kMaxEdges * 3]; 370c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org for (int i = 0; i < 3 * count; ++i) { 371c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org edges[i] = random->nextSScalar1(); 372c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 373c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 374b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrFragmentProcessor* fp; 375cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org do { 376b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>( 377b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt random->nextULessThan(kGrProcessorEdgeTypeCnt)); 378b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fp = GrConvexPolyEffect::Create(edgeType, count, edges); 379b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt } while (NULL == fp); 380b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return fp; 381c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 382