blob: 4b6bb3757190fbf95e6cd5e961036dc988295d09 [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
19#include <cstring>
20
21#include <utils/Log.h>
22
23#include "Patch.h"
24
25namespace android {
26namespace uirenderer {
27
28///////////////////////////////////////////////////////////////////////////////
29// Constructors/destructor
30///////////////////////////////////////////////////////////////////////////////
31
32Patch::Patch(const uint32_t xCount, const uint32_t yCount):
33 xCount(xCount + 2), yCount(yCount + 2) {
34 verticesCount = (xCount + 2) * (yCount + 2);
35 vertices = new TextureVertex[verticesCount];
36
37 // 2 triangles per patch, 3 vertices per triangle
38 indicesCount = (xCount + 1) * (yCount + 1) * 2 * 3;
39 indices = new uint16_t[indicesCount];
40
41 const uint32_t xNum = xCount + 1;
42 const uint32_t yNum = yCount + 1;
43
44 uint16_t* startIndices = indices;
45 uint32_t n = 0;
46 for (uint32_t y = 0; y < yNum; y++) {
47 for (uint32_t x = 0; x < xNum; x++) {
48 *startIndices++ = n;
49 *startIndices++ = n + 1;
50 *startIndices++ = n + xNum + 2;
51
52 *startIndices++ = n;
53 *startIndices++ = n + xNum + 2;
54 *startIndices++ = n + xNum + 1;
55
56 n += 1;
57 }
58 n += 1;
59 }
60}
61
62Patch::~Patch() {
63 delete indices;
64 delete vertices;
65}
66
67///////////////////////////////////////////////////////////////////////////////
68// Vertices management
69///////////////////////////////////////////////////////////////////////////////
70
71void Patch::updateVertices(const SkBitmap* bitmap, float left, float top, float right,
72 float bottom, const int32_t* xDivs, const int32_t* yDivs, const uint32_t width,
73 const uint32_t height) {
74 const uint32_t xStretchCount = (width + 1) >> 1;
75 const uint32_t yStretchCount = (height + 1) >> 1;
76
77 float xStretch = 0;
78 float yStretch = 0;
79 float xStretchTex = 0;
80 float yStretchTex = 0;
81
82 const float meshWidth = right - left;
83
84 const float bitmapWidth = float(bitmap->width());
85 const float bitmapHeight = float(bitmap->height());
86
87 if (xStretchCount > 0) {
88 uint32_t stretchSize = 0;
89 for (uint32_t i = 1; i < width; i += 2) {
90 stretchSize += xDivs[i] - xDivs[i - 1];
91 }
92 xStretchTex = (stretchSize / bitmapWidth) / xStretchCount;
93 const float fixed = bitmapWidth - stretchSize;
94 xStretch = (right - left - fixed) / xStretchCount;
95 }
96
97 if (yStretchCount > 0) {
98 uint32_t stretchSize = 0;
99 for (uint32_t i = 1; i < height; i += 2) {
100 stretchSize += yDivs[i] - yDivs[i - 1];
101 }
102 yStretchTex = (stretchSize / bitmapHeight) / yStretchCount;
103 const float fixed = bitmapHeight - stretchSize;
104 yStretch = (bottom - top - fixed) / yStretchCount;
105 }
106
107 float vy = 0.0f;
108 float ty = 0.0f;
109 TextureVertex* vertex = vertices;
110
111 generateVertices(vertex, 0.0f, 0.0f, xDivs, width, xStretch, xStretchTex,
112 meshWidth, bitmapWidth);
113 vertex += width + 2;
114
115 for (uint32_t y = 0; y < height; y++) {
116 if (y & 1) {
117 vy += yStretch;
118 ty += yStretchTex;
119 } else {
120 const float step = float(yDivs[y]);
121 vy += step;
122 ty += step / bitmapHeight;
123 }
124 generateVertices(vertex, vy, ty, xDivs, width, xStretch, xStretchTex,
125 meshWidth, bitmapWidth);
126 vertex += width + 2;
127 }
128
129 generateVertices(vertex, bottom - top, 1.0f, xDivs, width, xStretch, xStretchTex,
130 meshWidth, bitmapWidth);
131}
132
133inline void Patch::generateVertices(TextureVertex* vertex, float y, float v,
134 const int32_t xDivs[], uint32_t xCount, float xStretch, float xStretchTex,
135 float width, float widthTex) {
136 float vx = 0.0f;
137 float tx = 0.0f;
138
139 TextureVertex::set(vertex, vx, y, tx, v);
140 vertex++;
141
142 for (uint32_t x = 0; x < xCount; x++) {
143 if (x & 1) {
144 vx += xStretch;
145 tx += xStretchTex;
146 } else {
147 const float step = float(xDivs[x]);
148 vx += step;
149 tx += step / widthTex;
150 }
151
152 TextureVertex::set(vertex, vx, y, tx, v);
153 vertex++;
154 }
155
156 TextureVertex::set(vertex, width, y, 1.0f, v);
157 vertex++;
158}
159
160///////////////////////////////////////////////////////////////////////////////
161// Debug tools
162///////////////////////////////////////////////////////////////////////////////
163
164void Patch::dump() {
165 LOGD("Vertices [");
166 for (uint32_t y = 0; y < yCount; y++) {
167 char buffer[512];
168 buffer[0] = '\0';
169 uint32_t offset = 0;
170 for (uint32_t x = 0; x < xCount; x++) {
171 TextureVertex* v = &vertices[y * xCount + x];
172 offset += sprintf(&buffer[offset], " (%.4f,%.4f)-(%.4f,%.4f)",
173 v->position[0], v->position[1], v->texture[0], v->texture[1]);
174 }
175 LOGD(" [%s ]", buffer);
176 }
177 LOGD("]\nIndices [ ");
178 char buffer[4096];
179 buffer[0] = '\0';
180 uint32_t offset = 0;
181 for (uint32_t i = 0; i < indicesCount; i++) {
182 offset += sprintf(&buffer[offset], "%d ", indices[i]);
183 }
184 LOGD(" %s\n]", buffer);
185}
186
187}; // namespace uirenderer
188}; // namespace android