Patch.cpp revision 41d35aef06c2a570a45474a01ca95a6cb9c29d9e
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" 25a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy#include "Properties.h" 26fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 27fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guynamespace android { 28fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guynamespace uirenderer { 29fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 30fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy/////////////////////////////////////////////////////////////////////////////// 31fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy// Constructors/destructor 32fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy/////////////////////////////////////////////////////////////////////////////// 33fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 346f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain GuyPatch::Patch(const uint32_t xCount, const uint32_t yCount, const int8_t emptyQuads): 35a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy mXCount(xCount), mYCount(yCount), mEmptyQuads(emptyQuads) { 36a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy // Initialized with the maximum number of vertices we will need 37fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy // 2 triangles per patch, 3 vertices per triangle 388ab4079ca27e36e5c584495bcd71b573598ac021Romain Guy uint32_t maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3; 39a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy mVertices = new TextureVertex[maxVertices]; 406f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy mUploaded = false; 416f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 42a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy verticesCount = 0; 43a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy hasEmptyQuads = emptyQuads > 0; 44a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy 456f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy mColorKey = 0; 466f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy mXDivs = new int32_t[mXCount]; 476f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy mYDivs = new int32_t[mYCount]; 4803750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy 49a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy PATCH_LOGD(" patch: xCount = %d, yCount = %d, emptyQuads = %d, max vertices = %d", 50a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy xCount, yCount, emptyQuads, maxVertices); 51bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy 5203750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy glGenBuffers(1, &meshBuffer); 53fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy} 54fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 55fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain GuyPatch::~Patch() { 5603750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy delete[] mVertices; 576f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy delete[] mXDivs; 586f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy delete[] mYDivs; 5903750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy glDeleteBuffers(1, &meshBuffer); 60fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy} 61fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 62fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy/////////////////////////////////////////////////////////////////////////////// 636f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy// Patch management 646f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy/////////////////////////////////////////////////////////////////////////////// 656f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 666f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guyvoid Patch::copy(const int32_t* xDivs, const int32_t* yDivs) { 676f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy memcpy(mXDivs, xDivs, mXCount * sizeof(int32_t)); 686f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy memcpy(mYDivs, yDivs, mYCount * sizeof(int32_t)); 696f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy} 706f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 716f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guyvoid Patch::copy(const int32_t* yDivs) { 726f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy memcpy(mYDivs, yDivs, mYCount * sizeof(int32_t)); 736f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy} 746f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 756f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guyvoid Patch::updateColorKey(const uint32_t colorKey) { 766f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy mColorKey = colorKey; 776f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy} 786f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 796f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guybool Patch::matches(const int32_t* xDivs, const int32_t* yDivs, const uint32_t colorKey) { 806f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy if (mColorKey != colorKey) { 816f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy updateColorKey(colorKey); 826f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy copy(xDivs, yDivs); 836f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy return false; 846f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy } 856f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 866f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy for (uint32_t i = 0; i < mXCount; i++) { 876f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy if (mXDivs[i] != xDivs[i]) { 886f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy // The Y divs may or may not match, copy everything 896f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy copy(xDivs, yDivs); 906f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy return false; 916f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy } 926f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy } 936f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 946f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy for (uint32_t i = 0; i < mYCount; i++) { 956f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy if (mYDivs[i] != yDivs[i]) { 966f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy // We know all the X divs match, copy only Y divs 976f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy copy(yDivs); 986f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy return false; 996f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy } 1006f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy } 1016f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 1026f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy return true; 1036f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy} 1046f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 1056f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy/////////////////////////////////////////////////////////////////////////////// 106fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy// Vertices management 107fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy/////////////////////////////////////////////////////////////////////////////// 108fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 109759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guyvoid Patch::updateVertices(const float bitmapWidth, const float bitmapHeight, 1106f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy float left, float top, float right, float bottom) { 1115b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy if (hasEmptyQuads) quads.clear(); 112a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy 113a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy // Reset the vertices count here, we will count exactly how many 114a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy // vertices we actually need when generating the quads 115a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy verticesCount = 0; 1165b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy 1176f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy const uint32_t xStretchCount = (mXCount + 1) >> 1; 1186f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy const uint32_t yStretchCount = (mYCount + 1) >> 1; 119fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 1206820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy float stretchX = 0.0f; 12141d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy float stretchY = 0.0f; 12241d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy 12341d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy float rescaleX = 1.0f; 12441d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy float rescaleY = 1.0f; 125fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 126fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy const float meshWidth = right - left; 127fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 128fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy if (xStretchCount > 0) { 129fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy uint32_t stretchSize = 0; 1306f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy for (uint32_t i = 1; i < mXCount; i += 2) { 1316f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy stretchSize += mXDivs[i] - mXDivs[i - 1]; 132fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy } 1336820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy const float xStretchTex = stretchSize; 134fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy const float fixed = bitmapWidth - stretchSize; 13541d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy const float xStretch = fmaxf(right - left - fixed, 0.0f); 1366820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy stretchX = xStretch / xStretchTex; 13741d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy rescaleX = fminf(fmaxf(right - left, 0.0f) / fixed, 1.0f); 138fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy } 139fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 140fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy if (yStretchCount > 0) { 141fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy uint32_t stretchSize = 0; 1426f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy for (uint32_t i = 1; i < mYCount; i += 2) { 1436f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy stretchSize += mYDivs[i] - mYDivs[i - 1]; 144fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy } 1456820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy const float yStretchTex = stretchSize; 146fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy const float fixed = bitmapHeight - stretchSize; 14741d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy const float yStretch = fmaxf(bottom - top - fixed, 0.0f); 1486820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy stretchY = yStretch / yStretchTex; 14941d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy rescaleY = fminf(fmaxf(bottom - top, 0.0f) / fixed, 1.0f); 150fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy } 151fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 15203750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy TextureVertex* vertex = mVertices; 1534bb942083a0d4db746adf95349108dd8ef842e32Romain Guy uint32_t quadCount = 0; 154fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 1556820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy float previousStepY = 0.0f; 156fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 1576820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy float y1 = 0.0f; 158f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy float y2 = 0.0f; 1596820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy float v1 = 0.0f; 1606820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy 161eb6a4a17a07f1aa41bd58d418b2982cddb97685aRomain Guy for (uint32_t i = 0; i < mYCount; i++) { 1626f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy float stepY = mYDivs[i]; 1635e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy const float segment = stepY - previousStepY; 1646820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy 1656820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy if (i & 1) { 1668ab4079ca27e36e5c584495bcd71b573598ac021Romain Guy y2 = y1 + floorf(segment * stretchY + 0.5f); 167fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy } else { 16841d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy y2 = y1 + segment * rescaleY; 169fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy } 1705e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy 1715e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy float vOffset = y1 == y2 ? 0.0f : 0.5 - (0.5 * segment / (y2 - y1)); 1725e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy float v2 = fmax(0.0f, stepY - vOffset) / bitmapHeight; 1735e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy v1 += vOffset / bitmapHeight; 1746820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy 175eb6a4a17a07f1aa41bd58d418b2982cddb97685aRomain Guy if (stepY > 0.0f) { 176f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy#if DEBUG_EXPLODE_PATCHES 177f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy y1 += i * EXPLODE_GAP; 178f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy y2 += i * EXPLODE_GAP; 179f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy#endif 18041d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy generateRow(vertex, y1, y2, v1, v2, stretchX, rescaleX, right - left, 181eb6a4a17a07f1aa41bd58d418b2982cddb97685aRomain Guy bitmapWidth, quadCount); 182f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy#if DEBUG_EXPLODE_PATCHES 183f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy y2 -= i * EXPLODE_GAP; 184f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy#endif 185eb6a4a17a07f1aa41bd58d418b2982cddb97685aRomain Guy } 1866820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy 1876820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy y1 = y2; 1885e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy v1 = stepY / bitmapHeight; 1896820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy 1906820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy previousStepY = stepY; 191fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy } 192fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 193fdbec3e4828f93bfa5cde758ad0e77b89c5c2ecdRomain Guy if (previousStepY != bitmapHeight) { 194f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy y2 = bottom - top; 195f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy#if DEBUG_EXPLODE_PATCHES 196f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy y1 += mYCount * EXPLODE_GAP; 197f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy y2 += mYCount * EXPLODE_GAP; 198f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy#endif 19941d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy generateRow(vertex, y1, y2, v1, 1.0f, stretchX, rescaleX, right - left, 20041d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy bitmapWidth, quadCount); 201fdbec3e4828f93bfa5cde758ad0e77b89c5c2ecdRomain Guy } 20203750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy 203a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy if (verticesCount > 0) { 204f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy Caches& caches = Caches::getInstance(); 205f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy caches.bindMeshBuffer(meshBuffer); 206a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy if (!mUploaded) { 207a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy glBufferData(GL_ARRAY_BUFFER, sizeof(TextureVertex) * verticesCount, 208a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy mVertices, GL_DYNAMIC_DRAW); 209a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy mUploaded = true; 210a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy } else { 211a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy glBufferSubData(GL_ARRAY_BUFFER, 0, 212a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy sizeof(TextureVertex) * verticesCount, mVertices); 213a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy } 214f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy caches.resetVertexPointers(); 2156f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy } 216a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy 217a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy PATCH_LOGD(" patch: new vertices count = %d", verticesCount); 218fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy} 219fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 2205b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guyvoid Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2, 22141d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy float stretchX, float rescaleX, float width, float bitmapWidth, uint32_t& quadCount) { 2226820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy float previousStepX = 0.0f; 2236820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy 2246820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy float x1 = 0.0f; 225f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy float x2 = 0.0f; 2266820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy float u1 = 0.0f; 227fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 2286820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy // Generate the row quad by quad 229eb6a4a17a07f1aa41bd58d418b2982cddb97685aRomain Guy for (uint32_t i = 0; i < mXCount; i++) { 2306f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy float stepX = mXDivs[i]; 2315e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy const float segment = stepX - previousStepX; 232fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 2336820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy if (i & 1) { 2348ab4079ca27e36e5c584495bcd71b573598ac021Romain Guy x2 = x1 + floorf(segment * stretchX + 0.5f); 235fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy } else { 23641d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy x2 = x1 + segment * rescaleX; 237fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy } 2385e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy 2395e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy float uOffset = x1 == x2 ? 0.0f : 0.5 - (0.5 * segment / (x2 - x1)); 2405e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy float u2 = fmax(0.0f, stepX - uOffset) / bitmapWidth; 2415e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy u1 += uOffset / bitmapWidth; 242fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 243eb6a4a17a07f1aa41bd58d418b2982cddb97685aRomain Guy if (stepX > 0.0f) { 244f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy#if DEBUG_EXPLODE_PATCHES 245f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy x1 += i * EXPLODE_GAP; 246f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy x2 += i * EXPLODE_GAP; 247f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy#endif 248eb6a4a17a07f1aa41bd58d418b2982cddb97685aRomain Guy generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount); 249f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy#if DEBUG_EXPLODE_PATCHES 250f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy x2 -= i * EXPLODE_GAP; 251f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy#endif 252eb6a4a17a07f1aa41bd58d418b2982cddb97685aRomain Guy } 2536820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy 2546820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy x1 = x2; 2555e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy u1 = stepX / bitmapWidth; 2566820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy 2576820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy previousStepX = stepX; 258fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy } 259fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 260fdbec3e4828f93bfa5cde758ad0e77b89c5c2ecdRomain Guy if (previousStepX != bitmapWidth) { 261f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy x2 = width; 262f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy#if DEBUG_EXPLODE_PATCHES 263f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy x1 += mXCount * EXPLODE_GAP; 264f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy x2 += mXCount * EXPLODE_GAP; 265f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy#endif 266f504a2fa144504ca1efd39a4ef9208e3d4d336c5Romain Guy generateQuad(vertex, x1, y1, x2, y2, u1, v1, 1.0f, v2, quadCount); 267fdbec3e4828f93bfa5cde758ad0e77b89c5c2ecdRomain Guy } 268fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy} 269fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 2707444da512680df0c52af39ea521e35adbe0c167dRomain Guyvoid Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2, 271eb6a4a17a07f1aa41bd58d418b2982cddb97685aRomain Guy float u1, float v1, float u2, float v2, uint32_t& quadCount) { 272a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy const uint32_t oldQuadCount = quadCount; 273eb6a4a17a07f1aa41bd58d418b2982cddb97685aRomain Guy quadCount++; 274bd41a11078e94b755c8b6f78e1e4242c715fccd4Romain Guy 27570561df470c31513056df181571632851fd0d081Romain Guy if (x1 < 0.0f) x1 = 0.0f; 27670561df470c31513056df181571632851fd0d081Romain Guy if (x2 < 0.0f) x2 = 0.0f; 27770561df470c31513056df181571632851fd0d081Romain Guy if (y1 < 0.0f) y1 = 0.0f; 27870561df470c31513056df181571632851fd0d081Romain Guy if (y2 < 0.0f) y2 = 0.0f; 27970561df470c31513056df181571632851fd0d081Romain Guy 280a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy // Skip degenerate and transparent (empty) quads 28141d35aef06c2a570a45474a01ca95a6cb9c29d9eRomain Guy if (((mColorKey >> oldQuadCount) & 0x1) || x1 >= x2 || y1 >= y2) { 282fb13abd800cd610c7f46815848545feff83e5748Romain Guy#if DEBUG_PATCHES_EMPTY_VERTICES 283fb13abd800cd610c7f46815848545feff83e5748Romain Guy PATCH_LOGD(" quad %d (empty)", oldQuadCount); 2845e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy PATCH_LOGD(" left, top = %.2f, %.2f\t\tu1, v1 = %.4f, %.4f", x1, y1, u1, v1); 2855e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy PATCH_LOGD(" right, bottom = %.2f, %.2f\t\tu2, v2 = %.4f, %.4f", x2, y2, u2, v2); 286fb13abd800cd610c7f46815848545feff83e5748Romain Guy#endif 2877444da512680df0c52af39ea521e35adbe0c167dRomain Guy return; 2884bb942083a0d4db746adf95349108dd8ef842e32Romain Guy } 2894bb942083a0d4db746adf95349108dd8ef842e32Romain Guy 290a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy // Record all non empty quads 2915b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy if (hasEmptyQuads) { 2925b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy Rect bounds(x1, y1, x2, y2); 2935b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy quads.add(bounds); 2945b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy } 2955b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy 2966820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy // Left triangle 2976820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy TextureVertex::set(vertex++, x1, y1, u1, v1); 2986820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy TextureVertex::set(vertex++, x2, y1, u2, v1); 2996820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy TextureVertex::set(vertex++, x1, y2, u1, v2); 3006820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy 3016820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy // Right triangle 3026820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy TextureVertex::set(vertex++, x1, y2, u1, v2); 3036820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy TextureVertex::set(vertex++, x2, y1, u2, v1); 3046820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy TextureVertex::set(vertex++, x2, y2, u2, v2); 305a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy 306a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy // A quad is made of 2 triangles, 6 vertices 307a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy verticesCount += 6; 308a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy 309a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy#if DEBUG_PATCHES_VERTICES 310a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy PATCH_LOGD(" quad %d", oldQuadCount); 3115e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy PATCH_LOGD(" left, top = %.2f, %.2f\t\tu1, v1 = %.4f, %.4f", x1, y1, u1, v1); 3125e7c469c7a3039af7696789a797f8d91a45227ebRomain Guy PATCH_LOGD(" right, bottom = %.2f, %.2f\t\tu2, v2 = %.4f, %.4f", x2, y2, u2, v2); 313a5ef39a21683189e5906c9f252b997f0508e350dRomain Guy#endif 314fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy} 315fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy 316fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy}; // namespace uirenderer 317fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6cRomain Guy}; // namespace android 318