Patch.cpp revision bd41a11078e94b755c8b6f78e1e4242c715fccd4
1fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy/*
2fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy * Copyright (C) 2010 The Android Open Source Project
3fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy *
4fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy * you may not use this file except in compliance with the License.
6fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy * You may obtain a copy of the License at
7fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy *
8fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy *
10fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy * Unless required by applicable law or agreed to in writing, software
11fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy * See the License for the specific language governing permissions and
14fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy * limitations under the License.
15fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy */
16fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
17fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy#define LOG_TAG "OpenGLRenderer"
18fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
196820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy#include <cmath>
20fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
214bb942083a0d4db746adf95349108dd8ef842e32Romain Guy#include <utils/Log.h>
224bb942083a0d4db746adf95349108dd8ef842e32Romain Guy
23fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy#include "Patch.h"
2403750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy#include "Caches.h"
25fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
26fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guynamespace android {
27fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guynamespace uirenderer {
28fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
29fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy///////////////////////////////////////////////////////////////////////////////
30fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy// Constructors/destructor
31fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy///////////////////////////////////////////////////////////////////////////////
32fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
336f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain GuyPatch::Patch(const uint32_t xCount, const uint32_t yCount, const int8_t emptyQuads):
346f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        mXCount(xCount), mYCount(yCount) {
35fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy    // 2 triangles per patch, 3 vertices per triangle
364bb942083a0d4db746adf95349108dd8ef842e32Romain Guy    verticesCount = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
3703750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy    mVertices = new TextureVertex[verticesCount];
385b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    hasEmptyQuads = emptyQuads > 0;
396f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    mUploaded = false;
406f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy
416f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    mColorKey = 0;
426f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    mXDivs = new int32_t[mXCount];
436f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    mYDivs = new int32_t[mYCount];
4403750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy
45bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy    PATCH_LOGD("    patch: xCount = %d, yCount = %d, emptyQuads = %d, vertices = %d",
46bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy            xCount, yCount, emptyQuads, verticesCount);
47bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy
4803750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy    glGenBuffers(1, &meshBuffer);
49fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy}
50fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
51fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain GuyPatch::~Patch() {
5203750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy    delete[] mVertices;
536f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    delete[] mXDivs;
546f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    delete[] mYDivs;
5503750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy    glDeleteBuffers(1, &meshBuffer);
56fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy}
57fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
58fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy///////////////////////////////////////////////////////////////////////////////
596f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy// Patch management
606f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy///////////////////////////////////////////////////////////////////////////////
616f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy
626f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guyvoid Patch::copy(const int32_t* xDivs, const int32_t* yDivs) {
636f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    memcpy(mXDivs, xDivs, mXCount * sizeof(int32_t));
646f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    memcpy(mYDivs, yDivs, mYCount * sizeof(int32_t));
656f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy}
666f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy
676f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guyvoid Patch::copy(const int32_t* yDivs) {
686f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    memcpy(mYDivs, yDivs, mYCount * sizeof(int32_t));
696f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy}
706f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy
716f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guyvoid Patch::updateColorKey(const uint32_t colorKey) {
726f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    mColorKey = colorKey;
736f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy}
746f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy
756f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guybool Patch::matches(const int32_t* xDivs, const int32_t* yDivs, const uint32_t colorKey) {
766f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    if (mColorKey != colorKey) {
776f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        updateColorKey(colorKey);
786f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        copy(xDivs, yDivs);
796f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        return false;
806f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    }
816f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy
826f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    for (uint32_t i = 0; i < mXCount; i++) {
836f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        if (mXDivs[i] != xDivs[i]) {
846f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy            // The Y divs may or may not match, copy everything
856f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy            copy(xDivs, yDivs);
866f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy            return false;
876f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        }
886f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    }
896f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy
906f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    for (uint32_t i = 0; i < mYCount; i++) {
916f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        if (mYDivs[i] != yDivs[i]) {
926f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy            // We know all the X divs match, copy only Y divs
936f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy            copy(yDivs);
946f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy            return false;
956f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        }
966f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    }
976f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy
986f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    return true;
996f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy}
1006f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy
1016f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy///////////////////////////////////////////////////////////////////////////////
102fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy// Vertices management
103fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy///////////////////////////////////////////////////////////////////////////////
104fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
105759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guyvoid Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
1066f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        float left, float top, float right, float bottom) {
1075b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    if (hasEmptyQuads) quads.clear();
1085b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
1096f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    const uint32_t xStretchCount = (mXCount + 1) >> 1;
1106f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    const uint32_t yStretchCount = (mYCount + 1) >> 1;
111fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
1126820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    float stretchX = 0.0f;
1136820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    float stretchY = 0.0;
114fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
115fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy    const float meshWidth = right - left;
116fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
117fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy    if (xStretchCount > 0) {
118fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy        uint32_t stretchSize = 0;
1196f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        for (uint32_t i = 1; i < mXCount; i += 2) {
1206f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy            stretchSize += mXDivs[i] - mXDivs[i - 1];
121fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy        }
1226820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        const float xStretchTex = stretchSize;
123fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy        const float fixed = bitmapWidth - stretchSize;
1246820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        const float xStretch = right - left - fixed;
1256820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        stretchX = xStretch / xStretchTex;
126fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy    }
127fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
128fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy    if (yStretchCount > 0) {
129fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy        uint32_t stretchSize = 0;
1306f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        for (uint32_t i = 1; i < mYCount; i += 2) {
1316f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy            stretchSize += mYDivs[i] - mYDivs[i - 1];
132fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy        }
1336820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        const float yStretchTex = stretchSize;
134fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy        const float fixed = bitmapHeight - stretchSize;
1356820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        const float yStretch = bottom - top - fixed;
1366820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        stretchY = yStretch / yStretchTex;
137fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy    }
138fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
13903750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy    TextureVertex* vertex = mVertices;
1404bb942083a0d4db746adf95349108dd8ef842e32Romain Guy    uint32_t quadCount = 0;
141fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
1426820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    float previousStepY = 0.0f;
143fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
1446820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    float y1 = 0.0f;
1456820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    float v1 = 0.0f;
1466820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy
1476f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    for (uint32_t i = 0; i < mYCount; i++) {
1486f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        float stepY = mYDivs[i];
1496820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy
1506820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        float y2 = 0.0f;
1516820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        if (i & 1) {
1526820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy            const float segment = stepY - previousStepY;
1536820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy            y2 = y1 + segment * stretchY;
154fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy        } else {
1556820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy            y2 = y1 + stepY - previousStepY;
156fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy        }
1576820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        float v2 = fmax(0.0f, stepY - 0.5f) / bitmapHeight;
1586820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy
1596f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        generateRow(vertex, y1, y2, v1, v2, stretchX, right - left, bitmapWidth, quadCount);
1606820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy
1616820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        y1 = y2;
1626820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        v1 = (stepY + 0.5f) / bitmapHeight;
1636820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy
1646820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        previousStepY = stepY;
165fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy    }
166fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
1676f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    generateRow(vertex, y1, bottom - top, v1, 1.0f, stretchX, right - left,
1686f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy            bitmapWidth, quadCount);
16903750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy
17003750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy    Caches::getInstance().bindMeshBuffer(meshBuffer);
1716f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    if (!mUploaded) {
1726f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        glBufferData(GL_ARRAY_BUFFER, sizeof(TextureVertex) * verticesCount,
1736f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy                mVertices, GL_DYNAMIC_DRAW);
1746f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        mUploaded = true;
1756f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    } else {
1766f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        glBufferSubData(GL_ARRAY_BUFFER, 0,
1776f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy                sizeof(TextureVertex) * verticesCount, mVertices);
1786f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    }
179fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy}
180fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
1815b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guyvoid Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
1826f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        float stretchX, float width, float bitmapWidth, uint32_t& quadCount) {
1836820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    float previousStepX = 0.0f;
1846820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy
1856820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    float x1 = 0.0f;
1866820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    float u1 = 0.0f;
187fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
1886820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    // Generate the row quad by quad
1896f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    for (uint32_t i = 0; i < mXCount; i++) {
1906f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        float stepX = mXDivs[i];
191fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
1926820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        float x2 = 0.0f;
1936820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        if (i & 1) {
1946820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy            const float segment = stepX - previousStepX;
1956820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy            x2 = x1 + segment * stretchX;
196fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy        } else {
1976820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy            x2 = x1 + stepX - previousStepX;
198fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy        }
1996820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        float u2 = fmax(0.0f, stepX - 0.5f) / bitmapWidth;
200fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
2016f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy        generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount);
2026820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy
2036820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        x1 = x2;
2046820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        u1 = (stepX + 0.5f) / bitmapWidth;
2056820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy
2066820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy        previousStepX = stepX;
207fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy    }
208fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
2096f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy    generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2, quadCount);
210fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy}
211fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
2125b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guyvoid Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
2136f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy            float u1, float v1, float u2, float v2, uint32_t& quadCount) {
214bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy    uint32_t oldQuadCount = quadCount;
215bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy
216bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy    // Degenerate quads are an artifact of our implementation and should not
217bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy    // be taken into account when checking for transparent quads
218bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy    if (x2 - x1 > 0.999f && y2 - y1 > 0.999f) {
219bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy        quadCount++;
220bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy    }
221bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy
222bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy    if (((mColorKey >> oldQuadCount) & 0x1) == 1) {
2234bb942083a0d4db746adf95349108dd8ef842e32Romain Guy        return;
2244bb942083a0d4db746adf95349108dd8ef842e32Romain Guy    }
2254bb942083a0d4db746adf95349108dd8ef842e32Romain Guy
2265b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    if (hasEmptyQuads) {
2275b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        Rect bounds(x1, y1, x2, y2);
2285b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        quads.add(bounds);
2295b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
2305b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
2316820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    // Left triangle
2326820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    TextureVertex::set(vertex++, x1, y1, u1, v1);
2336820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    TextureVertex::set(vertex++, x2, y1, u2, v1);
2346820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    TextureVertex::set(vertex++, x1, y2, u1, v2);
2356820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy
2366820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    // Right triangle
2376820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    TextureVertex::set(vertex++, x1, y2, u1, v2);
2386820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    TextureVertex::set(vertex++, x2, y1, u2, v1);
2396820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    TextureVertex::set(vertex++, x2, y2, u2, v2);
240fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy}
241fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy
242fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy}; // namespace uirenderer
243fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy}; // namespace android
244