GrBitmapTextGeoProc.cpp revision a511e6ad1042093bea5b015c22a920313fc57c0b
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright 2013 Google Inc.
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Use of this source code is governed by a BSD-style license that can be
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * found in the LICENSE file.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes#include "GrBitmapTextGeoProc.h"
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes#include "GrInvariantOutput.h"
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes#include "GrTexture.h"
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes#include "gl/GrGLFragmentProcessor.h"
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes#include "gl/GrGLTexture.h"
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes#include "gl/GrGLGeometryProcessor.h"
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes#include "gl/builders/GrGLProgramBuilder.h"
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes
1612eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiroclass GrGLBitmapTextGeoProc : public GrGLGeometryProcessor {
1712eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiropublic:
1812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro    GrGLBitmapTextGeoProc(const GrGeometryProcessor&, const GrBatchTracker&)
1912eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro        : fColor(GrColor_ILLEGAL) {}
20578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
21578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
22578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom        const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>();
2312eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
2412eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro        GrGLGPBuilder* pb = args.fPB;
2512eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro        GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
26d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
27d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        // emit attributes
28adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        vsBuilder->emitAttributes(cte);
29adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes
30adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        // compute numbers to be hardcoded to convert texture coordinates from int to float
31adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        SkASSERT(cte.numTextures() == 1);
3212eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro        GrTexture* atlas = cte.textureAccess(0).getTexture();
3312eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro        SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
34e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        SkScalar recipWidth = 1.0f / atlas->width();
35e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        SkScalar recipHeight = 1.0f / atlas->height();
36e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
37e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        GrGLVertToFrag v(kVec2f_GrSLType);
38adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        pb->addVarying("TextureCoords", &v);
39e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", v.vsOut(),
40e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro                               GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
41df1ce91ba97bc79a0637e5504b39318fb1c9f577Ian Rogers                               GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
4219c350a9197411d427b71b7ab15b18417701de10Logan Chien                               cte.inTextureCoords()->fName);
4319c350a9197411d427b71b7ab15b18417701de10Logan Chien
4419c350a9197411d427b71b7ab15b18417701de10Logan Chien        // Setup pass through color
4519c350a9197411d427b71b7ab15b18417701de10Logan Chien        if (!cte.colorIgnored()) {
4619c350a9197411d427b71b7ab15b18417701de10Logan Chien            if (cte.hasVertexColor()) {
4719c350a9197411d427b71b7ab15b18417701de10Logan Chien                pb->addPassThroughAttribute(cte.inColor(), args.fOutputColor);
4819c350a9197411d427b71b7ab15b18417701de10Logan Chien            } else {
4919c350a9197411d427b71b7ab15b18417701de10Logan Chien                this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
50df1ce91ba97bc79a0637e5504b39318fb1c9f577Ian Rogers            }
5119c350a9197411d427b71b7ab15b18417701de10Logan Chien        }
5219c350a9197411d427b71b7ab15b18417701de10Logan Chien
5319c350a9197411d427b71b7ab15b18417701de10Logan Chien        // Setup position
5419c350a9197411d427b71b7ab15b18417701de10Logan Chien        this->setupPosition(pb, gpArgs, cte.inPosition()->fName);
5519c350a9197411d427b71b7ab15b18417701de10Logan Chien
5619c350a9197411d427b71b7ab15b18417701de10Logan Chien        // emit transforms
5719c350a9197411d427b71b7ab15b18417701de10Logan Chien        this->emitTransforms(args.fPB, gpArgs->fPositionVar, cte.inPosition()->fName,
5819c350a9197411d427b71b7ab15b18417701de10Logan Chien                             cte.localMatrix(), args.fTransformsIn, args.fTransformsOut);
5919c350a9197411d427b71b7ab15b18417701de10Logan Chien
6019c350a9197411d427b71b7ab15b18417701de10Logan Chien        GrGLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
6119c350a9197411d427b71b7ab15b18417701de10Logan Chien        if (cte.maskFormat() == kARGB_GrMaskFormat) {
6219c350a9197411d427b71b7ab15b18417701de10Logan Chien            fsBuilder->codeAppendf("%s = ", args.fOutputColor);
6319c350a9197411d427b71b7ab15b18417701de10Logan Chien            fsBuilder->appendTextureLookupAndModulate(args.fOutputColor,
6419c350a9197411d427b71b7ab15b18417701de10Logan Chien                                                      args.fSamplers[0],
6519c350a9197411d427b71b7ab15b18417701de10Logan Chien                                                      v.fsIn(),
6619c350a9197411d427b71b7ab15b18417701de10Logan Chien                                                      kVec2f_GrSLType);
6719c350a9197411d427b71b7ab15b18417701de10Logan Chien            fsBuilder->codeAppend(";");
68df1ce91ba97bc79a0637e5504b39318fb1c9f577Ian Rogers            fsBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
6919c350a9197411d427b71b7ab15b18417701de10Logan Chien        } else {
7019c350a9197411d427b71b7ab15b18417701de10Logan Chien            fsBuilder->codeAppendf("%s = ", args.fOutputCoverage);
7119c350a9197411d427b71b7ab15b18417701de10Logan Chien            fsBuilder->appendTextureLookup(args.fSamplers[0], v.fsIn(), kVec2f_GrSLType);
7219c350a9197411d427b71b7ab15b18417701de10Logan Chien            fsBuilder->codeAppend(";");
7319c350a9197411d427b71b7ab15b18417701de10Logan Chien        }
7419c350a9197411d427b71b7ab15b18417701de10Logan Chien    }
7519c350a9197411d427b71b7ab15b18417701de10Logan Chien
7619c350a9197411d427b71b7ab15b18417701de10Logan Chien    virtual void setData(const GrGLProgramDataManager& pdman,
77a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers                         const GrPrimitiveProcessor& gp,
78a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers                         const GrBatchTracker& bt) override {
79a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers        const GrBitmapTextGeoProc& btgp = gp.cast<GrBitmapTextGeoProc>();
80a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers        if (btgp.color() != fColor && !btgp.hasVertexColor()) {
81ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao            GrGLfloat c[4];
82578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom            GrColorToRGBAFloat(btgp.color(), c);
8312eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro            pdman.set4fv(fColorUniform, 1, c);
84d84f49c0d682c9f657d22fc6974c9fa4320aa396Carl Shapiro            fColor = btgp.color();
8512eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro        }
86a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    }
8712eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
88adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    void setTransformData(const GrPrimitiveProcessor& primProc,
89e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro                          const GrGLProgramDataManager& pdman,
90e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro                          int index,
91e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro                          const SkTArray<const GrCoordTransform*, true>& transforms) override {
92e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        this->setTransformDataHelper<GrBitmapTextGeoProc>(primProc, pdman, index, transforms);
93e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    }
94e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
95e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    static inline void GenKey(const GrGeometryProcessor& proc,
96e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro                              const GrBatchTracker& bt,
97e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro                              const GrGLSLCaps&,
98e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro                              GrProcessorKeyBuilder* b) {
99e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        const GrBitmapTextGeoProc& gp = proc.cast<GrBitmapTextGeoProc>();
100e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        uint32_t key = 0;
101e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        key |= gp.usesLocalCoords() && gp.localMatrix().hasPerspective() ? 0x1 : 0x0;
102e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        key |= gp.colorIgnored() ? 0x2 : 0x0;
103e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        key |= gp.maskFormat() << 3;
104e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        b->add32(key);
105e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
106e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        // Currently we hardcode numbers to convert atlas coordinates to normalized floating point
107e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        SkASSERT(gp.numTextures() == 1);
108e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        GrTexture* atlas = gp.textureAccess(0).getTexture();
109e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        SkASSERT(atlas);
110e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        b->add32(atlas->width());
111e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        b->add32(atlas->height());
112e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    }
113e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
114e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroprivate:
115e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    GrColor fColor;
116e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    UniformHandle fColorUniform;
117e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
118e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    typedef GrGLGeometryProcessor INHERITED;
119e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
120e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
121e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro///////////////////////////////////////////////////////////////////////////////
122526643e38c344701d96068f351548a393c67b6beTDYa
123e4c1ce498f7933b91696caa4a527e6556128a8e2Carl ShapiroGrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, GrTexture* texture,
124e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro                                         const GrTextureParams& params, GrMaskFormat format,
125ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao                                         const SkMatrix& localMatrix, bool usesLocalCoords)
126ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    : fColor(color)
127ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    , fLocalMatrix(localMatrix)
128ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    , fUsesLocalCoords(usesLocalCoords)
129ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    , fTextureAccess(texture, params)
130ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    , fInColor(nullptr)
131ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    , fMaskFormat(format) {
132ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    this->initClassID<GrBitmapTextGeoProc>();
133ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
134ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
135ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    // TODO we could think about removing this attribute if color is ignored, but unfortunately
136ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    // we don't do text positioning in batch, so we can't quite do that yet.
137ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat;
138ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    if (hasVertexColor) {
139ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
140ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    }
141ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
142ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao                                                        kVec2s_GrVertexAttribType));
143ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    this->addTextureAccess(&fTextureAccess);
144ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao}
145ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
146ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhaovoid GrBitmapTextGeoProc::getGLProcessorKey(const GrBatchTracker& bt,
147ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao                                            const GrGLSLCaps& caps,
148ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao                                            GrProcessorKeyBuilder* b) const {
149ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    GrGLBitmapTextGeoProc::GenKey(*this, bt, caps, b);
150ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao}
151ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
152adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott HughesGrGLPrimitiveProcessor*
153a75a01313e801c53145df00bad1842d9f643c0a1Ian RogersGrBitmapTextGeoProc::createGLInstance(const GrBatchTracker& bt,
154a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers                                      const GrGLSLCaps& caps) const {
155a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    return new GrGLBitmapTextGeoProc(*this, bt);
156a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers}
157a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers
158a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers///////////////////////////////////////////////////////////////////////////////
159a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers
160a75a01313e801c53145df00bad1842d9f643c0a1Ian RogersGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrBitmapTextGeoProc);
16112eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
16212eb78e651f13f2c1f0c2c922048a5a213253adfCarl ShapiroGrGeometryProcessor* GrBitmapTextGeoProc::TestCreate(GrProcessorTestData* d) {
163a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
164a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers                                          GrProcessorUnitTest::kAlphaTextureIdx;
165a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    static const SkShader::TileMode kTileModes[] = {
166a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers        SkShader::kClamp_TileMode,
167a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers        SkShader::kRepeat_TileMode,
168e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        SkShader::kMirror_TileMode,
169adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    };
170e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    SkShader::TileMode tileModes[] = {
171adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
172adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes        kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
173adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    };
174adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams::kBilerp_FilterMode :
175adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes                                                           GrTextureParams::kNone_FilterMode);
176adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes
177e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    GrMaskFormat format;
17812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro    switch (d->fRandom->nextULessThan(3)) {
17912eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro        case 0:
180a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers            format = kA8_GrMaskFormat;
181a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers            break;
182a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers        case 1:
183a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers            format = kA565_GrMaskFormat;
184a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers            break;
18512eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro        case 2:
18612eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro            format = kARGB_GrMaskFormat;
187d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers            break;
18812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro    }
189ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
19012eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro    return GrBitmapTextGeoProc::Create(GrRandomColor(d->fRandom), d->fTextures[texIdx], params,
19112eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro                                       format, GrTest::TestMatrix(d->fRandom),
192adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes                                       d->fRandom->nextBool());
193adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes}
194adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes