GlopBuilder.cpp revision 117bdbcfa3e8306dad21e7e01fa71b00cdfa7265
1031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik/*
2031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik * Copyright (C) 2015 The Android Open Source Project
3031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik *
4031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik * Licensed under the Apache License, Version 2.0 (the "License");
5031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik * you may not use this file except in compliance with the License.
6031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik * You may obtain a copy of the License at
7031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik *
8031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik *      http://www.apache.org/licenses/LICENSE-2.0
9031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik *
10031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik * Unless required by applicable law or agreed to in writing, software
11031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik * distributed under the License is distributed on an "AS IS" BASIS,
12031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik * See the License for the specific language governing permissions and
14031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik * limitations under the License.
15031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik */
16031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik#include "GlopBuilder.h"
17031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
18031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik#include "Caches.h"
19031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik#include "Glop.h"
20031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik#include "Matrix.h"
21031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik#include "renderstate/MeshState.h"
22031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik#include "renderstate/RenderState.h"
23117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik#include "SkiaShader.h"
24117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik#include "Texture.h"
25031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik#include "utils/PaintUtils.h"
26117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik#include "VertexBuffer.h"
27031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
28031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik#include <GLES2/gl2.h>
29031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik#include <SkPaint.h>
30031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
31031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craiknamespace android {
32031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craiknamespace uirenderer {
33031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
34117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik#define TRIGGER_STAGE(stageFlag) \
35117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    LOG_ALWAYS_FATAL_IF(stageFlag & mStageFlags, "Stage %d cannot be run twice"); \
36117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mStageFlags = static_cast<StageFlags>(mStageFlags | stageFlag)
37117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik
38031888744e24b5c7243ac99ec98b78aff5db1c78Chris CraikGlopBuilder::GlopBuilder(RenderState& renderState, Caches& caches, Glop* outGlop)
39031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik        : mRenderState(renderState)
40031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik        , mCaches(caches)
41031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik        , mOutGlop(outGlop){
42117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mStageFlags = kInitialStage;
43117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik}
44117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik
45117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris CraikGlopBuilder& GlopBuilder::setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp) {
46117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    TRIGGER_STAGE(kMeshStage);
47117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik
48117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    const VertexBuffer::MeshFeatureFlags flags = vertexBuffer.getMeshFeatureFlags();
49117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik
50117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    bool alphaVertex = flags & VertexBuffer::kAlpha;
51117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    bool indices = flags & VertexBuffer::kIndices;
52117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->mesh.vertexFlags = alphaVertex ? kAlpha_Attrib : kNone_Attrib;
53117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
54117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->mesh.vertexBufferObject = 0;
55117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->mesh.vertices = vertexBuffer.getBuffer();
56117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->mesh.indexBufferObject = 0;
57117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->mesh.indices = vertexBuffer.getIndices();
58117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->mesh.vertexCount = indices
59117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            ? vertexBuffer.getIndexCount() : vertexBuffer.getVertexCount();
60117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->mesh.stride = alphaVertex ? kAlphaVertexStride : kVertexStride;
61117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik
62117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mDescription.hasVertexAlpha = alphaVertex;
63117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mDescription.useShadowAlphaInterp = shadowInterp;
64117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    return *this;
65031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik}
66031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
67031888744e24b5c7243ac99ec98b78aff5db1c78Chris CraikGlopBuilder& GlopBuilder::setMeshUnitQuad() {
68117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    TRIGGER_STAGE(kMeshStage);
69117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik
70117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->mesh.vertexFlags = kNone_Attrib;
71031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
72031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    mOutGlop->mesh.vertexBufferObject = mRenderState.meshState().getUnitQuadVBO();
73117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->mesh.vertices = nullptr;
74031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    mOutGlop->mesh.indexBufferObject = 0;
75117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->mesh.indices = nullptr;
76031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    mOutGlop->mesh.vertexCount = 4;
77031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    mOutGlop->mesh.stride = kTextureVertexStride;
78031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    return *this;
79031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik}
80031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
81117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris CraikGlopBuilder& GlopBuilder::setTransform(const Matrix4& ortho,
82117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        const Matrix4& transform, bool fudgingOffset) {
83117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    TRIGGER_STAGE(kTransformStage);
84031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
85117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->transform.ortho.load(ortho);
86031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    mOutGlop->transform.canvas.load(transform);
87117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->transform.fudgingOffset = fudgingOffset;
88117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    return *this;
89117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik}
90031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
91117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris CraikGlopBuilder& GlopBuilder::setModelViewMapUnitToRect(const Rect destination) {
92117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    TRIGGER_STAGE(kModelViewStage);
93117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->transform.modelView.loadTranslate(destination.left, destination.top, 0.0f);
94117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->transform.modelView.scale(destination.getWidth(), destination.getHeight(), 1.0f);
95117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->bounds = destination;
96117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    return *this;
97117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik}
98031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
99117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris CraikGlopBuilder& GlopBuilder::setModelViewOffsetRect(float offsetX, float offsetY, const Rect source) {
100117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    TRIGGER_STAGE(kModelViewStage);
101117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f);
102117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->bounds = source;
103117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->bounds.translate(offsetX, offsetY);
104031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    return *this;
105031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik}
106031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
107031888744e24b5c7243ac99ec98b78aff5db1c78Chris CraikGlopBuilder& GlopBuilder::setPaint(const SkPaint* paint, float alphaScale) {
108117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    TRIGGER_STAGE(kFillStage);
109117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik
110031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    // TODO: support null paint
111031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    const SkShader* shader = paint->getShader();
112031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    const SkColorFilter* colorFilter = paint->getColorFilter();
113031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
114031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    SkXfermode::Mode mode = PaintUtils::getXfermode(paint->getXfermode());
115031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    if (mode != SkXfermode::kClear_Mode) {
116031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik        int color = paint->getColor();
117031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik        float alpha = (SkColorGetA(color) / 255.0f) * alphaScale;
118117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        if (!shader) {
119117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            float colorScale = alpha / 255.0f;
120117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            mOutGlop->fill.color = {
121117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik                    alpha,
122117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik                    colorScale * SkColorGetR(color),
123117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik                    colorScale * SkColorGetG(color),
124117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik                    colorScale * SkColorGetB(color)
125117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            };
126117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        } else {
127117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            mOutGlop->fill.color = { alpha, 1, 1, 1 };
128031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik        }
129031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    } else {
130031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik        mOutGlop->fill.color = { 1, 0, 0, 0 };
131031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    }
132031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    const bool SWAP_SRC_DST = false;
133031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
134117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->blend = { GL_ZERO, GL_ZERO };
135031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    if (mOutGlop->fill.color.a < 1.0f
136117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            || PaintUtils::isBlendedShader(shader)
137031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik            || PaintUtils::isBlendedColorFilter(colorFilter)
138031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik            || mode != SkXfermode::kSrcOver_Mode) {
139031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik        if (CC_LIKELY(mode <= SkXfermode::kScreen_Mode)) {
140031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik            Blend::getFactors(mode, SWAP_SRC_DST,
141031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik                    &mOutGlop->blend.src, &mOutGlop->blend.dst);
142031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik        } else {
143031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik            // These blend modes are not supported by OpenGL directly and have
144031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik            // to be implemented using shaders. Since the shader will perform
145031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik            // the blending, don't enable GL blending off here
146031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik            // If the blend mode cannot be implemented using shaders, fall
147031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik            // back to the default SrcOver blend mode instead
148117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            if (CC_UNLIKELY(mCaches.extensions().hasFramebufferFetch())) {
149031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik                mDescription.framebufferMode = mode;
150031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik                mDescription.swapSrcDst = SWAP_SRC_DST;
151031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik                // blending in shader, don't enable
152031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik            } else {
153031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik                // unsupported
154031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik                Blend::getFactors(SkXfermode::kSrcOver_Mode, SWAP_SRC_DST,
155031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik                        &mOutGlop->blend.src, &mOutGlop->blend.dst);
156031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik            }
157031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik        }
158031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    }
159031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
160117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    if (shader) {
161117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        SkiaShader::describe(&mCaches, mDescription, mCaches.extensions(), *shader);
162117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        // TODO: store shader data
163117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        LOG_ALWAYS_FATAL("shaders not yet supported");
164117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    }
165117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik
166117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    if (colorFilter) {
167117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        SkColor color;
168117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        SkXfermode::Mode mode;
169117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        SkScalar srcColorMatrix[20];
170117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        if (colorFilter->asColorMode(&color, &mode)) {
171117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            mOutGlop->fill.filterMode = mDescription.colorOp = ProgramDescription::kColorBlend;
172117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            mDescription.colorMode = mode;
173117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik
174117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            const float alpha = SkColorGetA(color) / 255.0f;
175117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            float colorScale = alpha / 255.0f;
176117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            mOutGlop->fill.filter.color = {
177117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik                    alpha,
178117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik                    colorScale * SkColorGetR(color),
179117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik                    colorScale * SkColorGetG(color),
180117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik                    colorScale * SkColorGetB(color),
181117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            };
182117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        } else if (colorFilter->asColorMatrix(srcColorMatrix)) {
183117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            mOutGlop->fill.filterMode = mDescription.colorOp = ProgramDescription::kColorMatrix;
184117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik
185117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            float* colorMatrix = mOutGlop->fill.filter.matrix.matrix;
186117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            memcpy(colorMatrix, srcColorMatrix, 4 * sizeof(float));
187117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            memcpy(&colorMatrix[4], &srcColorMatrix[5], 4 * sizeof(float));
188117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            memcpy(&colorMatrix[8], &srcColorMatrix[10], 4 * sizeof(float));
189117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            memcpy(&colorMatrix[12], &srcColorMatrix[15], 4 * sizeof(float));
190117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik
191117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            // Skia uses the range [0..255] for the addition vector, but we need
192117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            // the [0..1] range to apply the vector in GLSL
193117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            float* colorVector = mOutGlop->fill.filter.matrix.vector;
194117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            colorVector[0] = srcColorMatrix[4] / 255.0f;
195117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            colorVector[1] = srcColorMatrix[9] / 255.0f;
196117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            colorVector[2] = srcColorMatrix[14] / 255.0f;
197117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik            colorVector[3] = srcColorMatrix[19] / 255.0f;
198117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        }
199117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    } else {
200117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        mOutGlop->fill.filterMode = ProgramDescription::kColorNone;
201117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    }
202031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
203031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    return *this;
204031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik}
205031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
206031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craikvoid GlopBuilder::build() {
207117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    LOG_ALWAYS_FATAL_IF(mStageFlags != kAllStages, "glop not fully prepared!");
208117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik
209031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
210031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    mOutGlop->fill.program = mCaches.programCache.get(mDescription);
211117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    mOutGlop->transform.canvas.mapRect(mOutGlop->bounds);
212031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik}
213031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
214031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik} /* namespace uirenderer */
215031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik} /* namespace android */
216031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik
217