diff options
author | Romain Guy <romainguy@google.com> | 2010-07-09 13:52:56 -0700 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2010-07-09 13:52:56 -0700 |
commit | fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6c (patch) | |
tree | 8637af6593869b9e3f31a8b35c4388016eb690ac /libs/hwui/Patch.cpp | |
parent | 3465d5f532b65b0e50d21f5b23bc3badc73248ba (diff) | |
download | frameworks_base-fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6c.zip frameworks_base-fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6c.tar.gz frameworks_base-fb5e23c327cd5f8f93d1eaa7c10f34d6fd3efb6c.tar.bz2 |
Refactoring to move vertex computing to the Patch class.
This change is mostly cleanup to keep less code in OpenGLRenderer.
Change-Id: I954375143b2943829457ab470423729b60b844f5
Diffstat (limited to 'libs/hwui/Patch.cpp')
-rw-r--r-- | libs/hwui/Patch.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp new file mode 100644 index 0000000..4b6bb37 --- /dev/null +++ b/libs/hwui/Patch.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "OpenGLRenderer" + +#include <cstring> + +#include <utils/Log.h> + +#include "Patch.h" + +namespace android { +namespace uirenderer { + +/////////////////////////////////////////////////////////////////////////////// +// Constructors/destructor +/////////////////////////////////////////////////////////////////////////////// + +Patch::Patch(const uint32_t xCount, const uint32_t yCount): + xCount(xCount + 2), yCount(yCount + 2) { + verticesCount = (xCount + 2) * (yCount + 2); + vertices = new TextureVertex[verticesCount]; + + // 2 triangles per patch, 3 vertices per triangle + indicesCount = (xCount + 1) * (yCount + 1) * 2 * 3; + indices = new uint16_t[indicesCount]; + + const uint32_t xNum = xCount + 1; + const uint32_t yNum = yCount + 1; + + uint16_t* startIndices = indices; + uint32_t n = 0; + for (uint32_t y = 0; y < yNum; y++) { + for (uint32_t x = 0; x < xNum; x++) { + *startIndices++ = n; + *startIndices++ = n + 1; + *startIndices++ = n + xNum + 2; + + *startIndices++ = n; + *startIndices++ = n + xNum + 2; + *startIndices++ = n + xNum + 1; + + n += 1; + } + n += 1; + } +} + +Patch::~Patch() { + delete indices; + delete vertices; +} + +/////////////////////////////////////////////////////////////////////////////// +// Vertices management +/////////////////////////////////////////////////////////////////////////////// + +void Patch::updateVertices(const SkBitmap* bitmap, float left, float top, float right, + float bottom, const int32_t* xDivs, const int32_t* yDivs, const uint32_t width, + const uint32_t height) { + const uint32_t xStretchCount = (width + 1) >> 1; + const uint32_t yStretchCount = (height + 1) >> 1; + + float xStretch = 0; + float yStretch = 0; + float xStretchTex = 0; + float yStretchTex = 0; + + const float meshWidth = right - left; + + const float bitmapWidth = float(bitmap->width()); + const float bitmapHeight = float(bitmap->height()); + + if (xStretchCount > 0) { + uint32_t stretchSize = 0; + for (uint32_t i = 1; i < width; i += 2) { + stretchSize += xDivs[i] - xDivs[i - 1]; + } + xStretchTex = (stretchSize / bitmapWidth) / xStretchCount; + const float fixed = bitmapWidth - stretchSize; + xStretch = (right - left - fixed) / xStretchCount; + } + + if (yStretchCount > 0) { + uint32_t stretchSize = 0; + for (uint32_t i = 1; i < height; i += 2) { + stretchSize += yDivs[i] - yDivs[i - 1]; + } + yStretchTex = (stretchSize / bitmapHeight) / yStretchCount; + const float fixed = bitmapHeight - stretchSize; + yStretch = (bottom - top - fixed) / yStretchCount; + } + + float vy = 0.0f; + float ty = 0.0f; + TextureVertex* vertex = vertices; + + generateVertices(vertex, 0.0f, 0.0f, xDivs, width, xStretch, xStretchTex, + meshWidth, bitmapWidth); + vertex += width + 2; + + for (uint32_t y = 0; y < height; y++) { + if (y & 1) { + vy += yStretch; + ty += yStretchTex; + } else { + const float step = float(yDivs[y]); + vy += step; + ty += step / bitmapHeight; + } + generateVertices(vertex, vy, ty, xDivs, width, xStretch, xStretchTex, + meshWidth, bitmapWidth); + vertex += width + 2; + } + + generateVertices(vertex, bottom - top, 1.0f, xDivs, width, xStretch, xStretchTex, + meshWidth, bitmapWidth); +} + +inline void Patch::generateVertices(TextureVertex* vertex, float y, float v, + const int32_t xDivs[], uint32_t xCount, float xStretch, float xStretchTex, + float width, float widthTex) { + float vx = 0.0f; + float tx = 0.0f; + + TextureVertex::set(vertex, vx, y, tx, v); + vertex++; + + for (uint32_t x = 0; x < xCount; x++) { + if (x & 1) { + vx += xStretch; + tx += xStretchTex; + } else { + const float step = float(xDivs[x]); + vx += step; + tx += step / widthTex; + } + + TextureVertex::set(vertex, vx, y, tx, v); + vertex++; + } + + TextureVertex::set(vertex, width, y, 1.0f, v); + vertex++; +} + +/////////////////////////////////////////////////////////////////////////////// +// Debug tools +/////////////////////////////////////////////////////////////////////////////// + +void Patch::dump() { + LOGD("Vertices ["); + for (uint32_t y = 0; y < yCount; y++) { + char buffer[512]; + buffer[0] = '\0'; + uint32_t offset = 0; + for (uint32_t x = 0; x < xCount; x++) { + TextureVertex* v = &vertices[y * xCount + x]; + offset += sprintf(&buffer[offset], " (%.4f,%.4f)-(%.4f,%.4f)", + v->position[0], v->position[1], v->texture[0], v->texture[1]); + } + LOGD(" [%s ]", buffer); + } + LOGD("]\nIndices [ "); + char buffer[4096]; + buffer[0] = '\0'; + uint32_t offset = 0; + for (uint32_t i = 0; i < indicesCount; i++) { + offset += sprintf(&buffer[offset], "%d ", indices[i]); + } + LOGD(" %s\n]", buffer); +} + +}; // namespace uirenderer +}; // namespace android |