blob: 560decf15d38a0e5fcfcb6870413e6a8e0f41746 [file] [log] [blame]
Romain Guyfb5e23c2010-07-09 13:52:56 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "OpenGLRenderer"
18
Romain Guy6820ac82010-09-15 18:11:50 -070019#include <cmath>
Romain Guyfb5e23c2010-07-09 13:52:56 -070020
Romain Guy4bb94202010-10-12 15:59:26 -070021#include <utils/Log.h>
22
Romain Guyfb5e23c2010-07-09 13:52:56 -070023#include "Patch.h"
24
25namespace android {
26namespace uirenderer {
27
28///////////////////////////////////////////////////////////////////////////////
29// Constructors/destructor
30///////////////////////////////////////////////////////////////////////////////
31
Romain Guy4bb94202010-10-12 15:59:26 -070032Patch::Patch(const uint32_t xCount, const uint32_t yCount, const int8_t emptyQuads) {
Romain Guyfb5e23c2010-07-09 13:52:56 -070033 // 2 triangles per patch, 3 vertices per triangle
Romain Guy4bb94202010-10-12 15:59:26 -070034 verticesCount = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
Romain Guy6820ac82010-09-15 18:11:50 -070035 vertices = new TextureVertex[verticesCount];
Romain Guyfb5e23c2010-07-09 13:52:56 -070036}
37
38Patch::~Patch() {
Romain Guy31529ff2010-09-17 10:26:31 -070039 delete[] vertices;
Romain Guyfb5e23c2010-07-09 13:52:56 -070040}
41
42///////////////////////////////////////////////////////////////////////////////
43// Vertices management
44///////////////////////////////////////////////////////////////////////////////
45
Romain Guy759ea802010-09-16 20:49:46 -070046void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
47 float left, float top, float right, float bottom,
Romain Guy4bb94202010-10-12 15:59:26 -070048 const int32_t* xDivs, const int32_t* yDivs,
49 const uint32_t width, const uint32_t height, const uint32_t colorKey) {
Romain Guyfb5e23c2010-07-09 13:52:56 -070050 const uint32_t xStretchCount = (width + 1) >> 1;
51 const uint32_t yStretchCount = (height + 1) >> 1;
52
Romain Guy6820ac82010-09-15 18:11:50 -070053 float stretchX = 0.0f;
54 float stretchY = 0.0;
Romain Guyfb5e23c2010-07-09 13:52:56 -070055
56 const float meshWidth = right - left;
57
Romain Guyfb5e23c2010-07-09 13:52:56 -070058 if (xStretchCount > 0) {
59 uint32_t stretchSize = 0;
60 for (uint32_t i = 1; i < width; i += 2) {
61 stretchSize += xDivs[i] - xDivs[i - 1];
62 }
Romain Guy6820ac82010-09-15 18:11:50 -070063 const float xStretchTex = stretchSize;
Romain Guyfb5e23c2010-07-09 13:52:56 -070064 const float fixed = bitmapWidth - stretchSize;
Romain Guy6820ac82010-09-15 18:11:50 -070065 const float xStretch = right - left - fixed;
66 stretchX = xStretch / xStretchTex;
Romain Guyfb5e23c2010-07-09 13:52:56 -070067 }
68
69 if (yStretchCount > 0) {
70 uint32_t stretchSize = 0;
71 for (uint32_t i = 1; i < height; i += 2) {
72 stretchSize += yDivs[i] - yDivs[i - 1];
73 }
Romain Guy6820ac82010-09-15 18:11:50 -070074 const float yStretchTex = stretchSize;
Romain Guyfb5e23c2010-07-09 13:52:56 -070075 const float fixed = bitmapHeight - stretchSize;
Romain Guy6820ac82010-09-15 18:11:50 -070076 const float yStretch = bottom - top - fixed;
77 stretchY = yStretch / yStretchTex;
Romain Guyfb5e23c2010-07-09 13:52:56 -070078 }
79
Romain Guyfb5e23c2010-07-09 13:52:56 -070080 TextureVertex* vertex = vertices;
Romain Guy4bb94202010-10-12 15:59:26 -070081 uint32_t quadCount = 0;
Romain Guyfb5e23c2010-07-09 13:52:56 -070082
Romain Guy6820ac82010-09-15 18:11:50 -070083 float previousStepY = 0.0f;
Romain Guyfb5e23c2010-07-09 13:52:56 -070084
Romain Guy6820ac82010-09-15 18:11:50 -070085 float y1 = 0.0f;
86 float v1 = 0.0f;
87
88 for (uint32_t i = 0; i < height; i++) {
89 float stepY = yDivs[i];
90
91 float y2 = 0.0f;
92 if (i & 1) {
93 const float segment = stepY - previousStepY;
94 y2 = y1 + segment * stretchY;
Romain Guyfb5e23c2010-07-09 13:52:56 -070095 } else {
Romain Guy6820ac82010-09-15 18:11:50 -070096 y2 = y1 + stepY - previousStepY;
Romain Guyfb5e23c2010-07-09 13:52:56 -070097 }
Romain Guy6820ac82010-09-15 18:11:50 -070098 float v2 = fmax(0.0f, stepY - 0.5f) / bitmapHeight;
99
100 generateRow(vertex, y1, y2, v1, v2, xDivs, width, stretchX,
Romain Guy4bb94202010-10-12 15:59:26 -0700101 right - left, bitmapWidth, quadCount, colorKey);
Romain Guy6820ac82010-09-15 18:11:50 -0700102
103 y1 = y2;
104 v1 = (stepY + 0.5f) / bitmapHeight;
105
106 previousStepY = stepY;
Romain Guyfb5e23c2010-07-09 13:52:56 -0700107 }
108
Romain Guy6820ac82010-09-15 18:11:50 -0700109 generateRow(vertex, y1, bottom - top, v1, 1.0f, xDivs, width, stretchX,
Romain Guy4bb94202010-10-12 15:59:26 -0700110 right - left, bitmapWidth, quadCount, colorKey);
Romain Guyfb5e23c2010-07-09 13:52:56 -0700111}
112
Romain Guy6820ac82010-09-15 18:11:50 -0700113inline void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
Romain Guy4bb94202010-10-12 15:59:26 -0700114 const int32_t xDivs[], uint32_t xCount, float stretchX, float width, float bitmapWidth,
115 uint32_t& quadCount, const uint32_t colorKey) {
Romain Guy6820ac82010-09-15 18:11:50 -0700116 float previousStepX = 0.0f;
Romain Guyfb5e23c2010-07-09 13:52:56 -0700117
Romain Guy6820ac82010-09-15 18:11:50 -0700118 float x1 = 0.0f;
119 float u1 = 0.0f;
Romain Guyfb5e23c2010-07-09 13:52:56 -0700120
Romain Guy6820ac82010-09-15 18:11:50 -0700121 // Generate the row quad by quad
122 for (uint32_t i = 0; i < xCount; i++) {
123 float stepX = xDivs[i];
124
125 float x2 = 0.0f;
126 if (i & 1) {
127 const float segment = stepX - previousStepX;
128 x2 = x1 + segment * stretchX;
Romain Guyfb5e23c2010-07-09 13:52:56 -0700129 } else {
Romain Guy6820ac82010-09-15 18:11:50 -0700130 x2 = x1 + stepX - previousStepX;
Romain Guyfb5e23c2010-07-09 13:52:56 -0700131 }
Romain Guy6820ac82010-09-15 18:11:50 -0700132 float u2 = fmax(0.0f, stepX - 0.5f) / bitmapWidth;
Romain Guyfb5e23c2010-07-09 13:52:56 -0700133
Romain Guy4bb94202010-10-12 15:59:26 -0700134 generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount, colorKey);
Romain Guy6820ac82010-09-15 18:11:50 -0700135
136 x1 = x2;
137 u1 = (stepX + 0.5f) / bitmapWidth;
138
139 previousStepX = stepX;
Romain Guyfb5e23c2010-07-09 13:52:56 -0700140 }
141
Romain Guy4bb94202010-10-12 15:59:26 -0700142 generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2, quadCount, colorKey);
Romain Guyfb5e23c2010-07-09 13:52:56 -0700143}
144
Romain Guy6820ac82010-09-15 18:11:50 -0700145inline void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
Romain Guy4bb94202010-10-12 15:59:26 -0700146 float u1, float v1, float u2, float v2, uint32_t& quadCount, const uint32_t colorKey) {
147 if (((colorKey >> quadCount++) & 0x1) == 1) {
148 return;
149 }
150
Romain Guy6820ac82010-09-15 18:11:50 -0700151 // Left triangle
152 TextureVertex::set(vertex++, x1, y1, u1, v1);
153 TextureVertex::set(vertex++, x2, y1, u2, v1);
154 TextureVertex::set(vertex++, x1, y2, u1, v2);
Romain Guyfb5e23c2010-07-09 13:52:56 -0700155
Romain Guy6820ac82010-09-15 18:11:50 -0700156 // Right triangle
157 TextureVertex::set(vertex++, x1, y2, u1, v2);
158 TextureVertex::set(vertex++, x2, y1, u2, v1);
159 TextureVertex::set(vertex++, x2, y2, u2, v2);
Romain Guyfb5e23c2010-07-09 13:52:56 -0700160}
161
162}; // namespace uirenderer
163}; // namespace android