Use VBOs to render most geometries.
Change-Id: I4360dc4fe5693ab425450c107282b2c22db4dca7
This commit is contained in:
@ -6,10 +6,10 @@ include $(CLEAR_VARS)
|
||||
ifeq ($(USE_OPENGL_RENDERER),true)
|
||||
LOCAL_SRC_FILES:= \
|
||||
utils/SortedListImpl.cpp \
|
||||
DisplayListRenderer.cpp \
|
||||
FboCache.cpp \
|
||||
FontRenderer.cpp \
|
||||
GammaFontRenderer.cpp \
|
||||
DisplayListRenderer.cpp \
|
||||
FboCache.cpp \
|
||||
GradientCache.cpp \
|
||||
LayerCache.cpp \
|
||||
Matrix.cpp \
|
||||
|
@ -23,11 +23,12 @@
|
||||
|
||||
#include <utils/Singleton.h>
|
||||
|
||||
#include "FontRenderer.h"
|
||||
#include "GammaFontRenderer.h"
|
||||
#include "TextureCache.h"
|
||||
#include "LayerCache.h"
|
||||
#include "GradientCache.h"
|
||||
#include "PatchCache.h"
|
||||
#include "GammaFontRenderer.h"
|
||||
#include "ProgramCache.h"
|
||||
#include "PathCache.h"
|
||||
#include "TextDropShadowCache.h"
|
||||
@ -37,15 +38,55 @@
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Globals
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define REQUIRED_TEXTURE_UNITS_COUNT 3
|
||||
|
||||
// Generates simple and textured vertices
|
||||
#define FV(x, y, u, v) { { x, y }, { u, v } }
|
||||
|
||||
// This array is never used directly but used as a memcpy source in the
|
||||
// OpenGLRenderer constructor
|
||||
static const TextureVertex gMeshVertices[] = {
|
||||
FV(0.0f, 0.0f, 0.0f, 0.0f),
|
||||
FV(1.0f, 0.0f, 1.0f, 0.0f),
|
||||
FV(0.0f, 1.0f, 0.0f, 1.0f),
|
||||
FV(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
};
|
||||
static const GLsizei gMeshStride = sizeof(TextureVertex);
|
||||
static const GLsizei gMeshTextureOffset = 2 * sizeof(float);
|
||||
static const GLsizei gMeshCount = 4;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Debug
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct CacheLogger {
|
||||
CacheLogger() {
|
||||
LOGD("Creating caches");
|
||||
}
|
||||
}; // struct CacheLogger
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Caches
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Caches: public Singleton<Caches> {
|
||||
Caches(): Singleton<Caches>(), blend(false), lastSrcMode(GL_ZERO),
|
||||
lastDstMode(GL_ZERO), currentProgram(NULL) {
|
||||
GLint maxTextureUnits;
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
|
||||
if (maxTextureUnits < REQUIRED_TEXTURE_UNITS_COUNT) {
|
||||
LOGW("At least %d texture units are required!", REQUIRED_TEXTURE_UNITS_COUNT);
|
||||
}
|
||||
|
||||
glGenBuffers(1, &meshBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, meshBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW);
|
||||
|
||||
currentBuffer = meshBuffer;
|
||||
}
|
||||
|
||||
friend class Singleton<Caches>;
|
||||
@ -53,11 +94,41 @@ class Caches: public Singleton<Caches> {
|
||||
CacheLogger logger;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Binds the VBO used to render simple textured quads.
|
||||
*/
|
||||
inline void bindMeshBuffer() {
|
||||
bindMeshBuffer(meshBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the specified VBO.
|
||||
*/
|
||||
inline void bindMeshBuffer(const GLuint buffer) {
|
||||
if (currentBuffer != buffer) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
currentBuffer = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbinds the VBO used to render simple textured quads.
|
||||
*/
|
||||
inline void unbindMeshBuffer() {
|
||||
if (currentBuffer) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
currentBuffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool blend;
|
||||
GLenum lastSrcMode;
|
||||
GLenum lastDstMode;
|
||||
Program* currentProgram;
|
||||
|
||||
GLuint meshBuffer;
|
||||
GLuint currentBuffer;
|
||||
|
||||
TextureCache textureCache;
|
||||
LayerCache layerCache;
|
||||
GradientCache gradientCache;
|
||||
|
@ -96,12 +96,8 @@ public:
|
||||
ty = lineWidth <= 1.0f ? -gLineAABias : -half - gLineAABias;
|
||||
}
|
||||
|
||||
inline GLvoid* getVertices() const {
|
||||
return &mPatch->vertices[0].position[0];
|
||||
}
|
||||
|
||||
inline GLvoid* getTexCoords() const {
|
||||
return &mPatch->vertices[0].texture[0];
|
||||
inline GLuint getMeshBuffer() const {
|
||||
return mPatch->meshBuffer;
|
||||
}
|
||||
|
||||
inline GLsizei getElementsCount() const {
|
||||
|
@ -55,9 +55,11 @@ void Matrix4::loadIdentity() {
|
||||
}
|
||||
|
||||
bool Matrix4::changesBounds() {
|
||||
return !(almost(data[0], 1.0f) && almost(data[1], 0.0f) && almost(data[2], 0.0f) &&
|
||||
almost(data[4], 0.0f) && almost(data[5], 1.0f) && almost(data[6], 0.0f) &&
|
||||
almost(data[8], 0.0f) && almost(data[9], 0.0f) && almost(data[10], 1.0f));
|
||||
return !(ALMOST_EQUAL(data[0], 1.0f) && ALMOST_EQUAL(data[1], 0.0f) &&
|
||||
ALMOST_EQUAL(data[2], 0.0f) && ALMOST_EQUAL(data[4], 0.0f) &&
|
||||
ALMOST_EQUAL(data[5], 1.0f) && ALMOST_EQUAL(data[6], 0.0f) &&
|
||||
ALMOST_EQUAL(data[8], 0.0f) && ALMOST_EQUAL(data[9], 0.0f) &&
|
||||
ALMOST_EQUAL(data[10], 1.0f));
|
||||
}
|
||||
|
||||
void Matrix4::load(const float* v) {
|
||||
|
@ -35,11 +35,6 @@ namespace uirenderer {
|
||||
// Defines
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define REQUIRED_TEXTURE_UNITS_COUNT 3
|
||||
|
||||
// Generates simple and textured vertices
|
||||
#define FV(x, y, u, v) { { x, y }, { u, v } }
|
||||
|
||||
#define RAD_TO_DEG (180.0f / 3.14159265f)
|
||||
#define MIN_ANGLE 0.001f
|
||||
|
||||
@ -50,17 +45,6 @@ namespace uirenderer {
|
||||
// Globals
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This array is never used directly but used as a memcpy source in the
|
||||
// OpenGLRenderer constructor
|
||||
static const TextureVertex gMeshVertices[] = {
|
||||
FV(0.0f, 0.0f, 0.0f, 0.0f),
|
||||
FV(1.0f, 0.0f, 1.0f, 0.0f),
|
||||
FV(0.0f, 1.0f, 0.0f, 1.0f),
|
||||
FV(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
};
|
||||
static const GLsizei gMeshStride = sizeof(TextureVertex);
|
||||
static const GLsizei gMeshCount = 4;
|
||||
|
||||
/**
|
||||
* Structure mapping Skia xfermodes to OpenGL blending factors.
|
||||
*/
|
||||
@ -124,12 +108,6 @@ OpenGLRenderer::OpenGLRenderer(): mCaches(Caches::getInstance()) {
|
||||
|
||||
mFirstSnapshot = new Snapshot;
|
||||
|
||||
GLint maxTextureUnits;
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
|
||||
if (maxTextureUnits < REQUIRED_TEXTURE_UNITS_COUNT) {
|
||||
LOGW("At least %d texture units are required!", REQUIRED_TEXTURE_UNITS_COUNT);
|
||||
}
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
|
||||
}
|
||||
|
||||
@ -201,6 +179,8 @@ void OpenGLRenderer::releaseContext() {
|
||||
glDisable(GL_DITHER);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
mCaches.bindMeshBuffer();
|
||||
|
||||
if (mCaches.blend) {
|
||||
glEnable(GL_BLEND);
|
||||
@ -514,11 +494,13 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
|
||||
}
|
||||
|
||||
const Rect& texCoords = layer->texCoords;
|
||||
mCaches.unbindMeshBuffer();
|
||||
resetDrawTextureTexCoords(texCoords.left, texCoords.top, texCoords.right, texCoords.bottom);
|
||||
|
||||
if (fboLayer) {
|
||||
drawTextureRect(rect.left, rect.top, rect.right, rect.bottom,
|
||||
layer->texture, layer->alpha / 255.0f, layer->mode, layer->blend);
|
||||
drawTextureMesh(rect.left, rect.top, rect.right, rect.bottom, layer->texture,
|
||||
layer->alpha / 255.0f, layer->mode, layer->blend, &mMeshVertices[0].position[0],
|
||||
&mMeshVertices[0].texture[0], GL_TRIANGLE_STRIP, gMeshCount);
|
||||
} else {
|
||||
drawTextureMesh(rect.left, rect.top, rect.right, rect.bottom, layer->texture,
|
||||
1.0f, layer->mode, layer->blend, &mMeshVertices[0].position[0],
|
||||
@ -698,9 +680,16 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
|
||||
const float u2 = srcRight / width;
|
||||
const float v2 = srcBottom / height;
|
||||
|
||||
mCaches.unbindMeshBuffer();
|
||||
resetDrawTextureTexCoords(u1, v1, u2, v2);
|
||||
|
||||
drawTextureRect(dstLeft, dstTop, dstRight, dstBottom, texture, paint);
|
||||
int alpha;
|
||||
SkXfermode::Mode mode;
|
||||
getAlphaAndMode(paint, &alpha, &mode);
|
||||
|
||||
drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom, texture->id, alpha / 255.0f,
|
||||
mode, texture->blend, &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
|
||||
GL_TRIANGLE_STRIP, gMeshCount);
|
||||
|
||||
resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
}
|
||||
@ -728,8 +717,8 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
|
||||
// Specify right and bottom as +1.0f from left/top to prevent scaling since the
|
||||
// patch mesh already defines the final size
|
||||
drawTextureMesh(left, top, left + 1.0f, top + 1.0f, texture->id, alpha / 255.0f,
|
||||
mode, texture->blend, &mesh->vertices[0].position[0],
|
||||
&mesh->vertices[0].texture[0], GL_TRIANGLES, mesh->verticesCount);
|
||||
mode, texture->blend, (GLvoid*) 0, (GLvoid*) gMeshTextureOffset,
|
||||
GL_TRIANGLES, mesh->verticesCount, false, false, mesh->meshBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -750,7 +739,8 @@ void OpenGLRenderer::drawLines(float* points, int count, const SkPaint* paint) {
|
||||
if (isAA) {
|
||||
GLuint textureUnit = 0;
|
||||
setupTextureAlpha8(mCaches.line.getTexture(), 0, 0, textureUnit, 0.0f, 0.0f, r, g, b, a,
|
||||
mode, false, true, mCaches.line.getVertices(), mCaches.line.getTexCoords());
|
||||
mode, false, true, (GLvoid*) 0, (GLvoid*) gMeshTextureOffset,
|
||||
mCaches.line.getMeshBuffer());
|
||||
} else {
|
||||
setupColorRect(0.0f, 0.0f, 1.0f, 1.0f, r, g, b, a, mode, false);
|
||||
}
|
||||
@ -891,11 +881,12 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
|
||||
// Assume that the modelView matrix does not force scales, rotates, etc.
|
||||
const bool linearFilter = mSnapshot->transform->changesBounds();
|
||||
setupTextureAlpha8(fontRenderer.getTexture(linearFilter), 0, 0, textureUnit,
|
||||
x, y, r, g, b, a, mode, false, true);
|
||||
x, y, r, g, b, a, mode, false, true, NULL, NULL);
|
||||
|
||||
const Rect& clip = mSnapshot->getLocalClip();
|
||||
clearLayerRegions();
|
||||
|
||||
mCaches.unbindMeshBuffer();
|
||||
fontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
@ -1009,21 +1000,20 @@ void OpenGLRenderer::setupTextureAlpha8(const Texture* texture, GLuint& textureU
|
||||
bool transforms, bool applyFilters) {
|
||||
setupTextureAlpha8(texture->id, texture->width, texture->height, textureUnit,
|
||||
x, y, r, g, b, a, mode, transforms, applyFilters,
|
||||
&mMeshVertices[0].position[0], &mMeshVertices[0].texture[0]);
|
||||
(GLvoid*) 0, (GLvoid*) gMeshTextureOffset);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t height,
|
||||
GLuint& textureUnit, float x, float y, float r, float g, float b, float a,
|
||||
SkXfermode::Mode mode, bool transforms, bool applyFilters) {
|
||||
setupTextureAlpha8(texture, width, height, textureUnit,
|
||||
x, y, r, g, b, a, mode, transforms, applyFilters,
|
||||
&mMeshVertices[0].position[0], &mMeshVertices[0].texture[0]);
|
||||
setupTextureAlpha8(texture, width, height, textureUnit, x, y, r, g, b, a, mode,
|
||||
transforms, applyFilters, (GLvoid*) 0, (GLvoid*) gMeshTextureOffset);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t height,
|
||||
GLuint& textureUnit, float x, float y, float r, float g, float b, float a,
|
||||
SkXfermode::Mode mode, bool transforms, bool applyFilters,
|
||||
GLvoid* vertices, GLvoid* texCoords) {
|
||||
GLvoid* vertices, GLvoid* texCoords, GLuint vbo) {
|
||||
// Describe the required shaders
|
||||
ProgramDescription description;
|
||||
description.hasTexture = true;
|
||||
@ -1051,11 +1041,17 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t
|
||||
int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords");
|
||||
glEnableVertexAttribArray(texCoordsSlot);
|
||||
|
||||
// Setup attributes
|
||||
glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
|
||||
gMeshStride, vertices);
|
||||
glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE,
|
||||
gMeshStride, texCoords);
|
||||
if (texCoords) {
|
||||
// Setup attributes
|
||||
if (!vertices) {
|
||||
mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo);
|
||||
} else {
|
||||
mCaches.unbindMeshBuffer();
|
||||
}
|
||||
glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
|
||||
gMeshStride, vertices);
|
||||
glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE, gMeshStride, texCoords);
|
||||
}
|
||||
|
||||
// Setup uniforms
|
||||
if (transforms) {
|
||||
@ -1188,8 +1184,9 @@ void OpenGLRenderer::setupColorRect(float left, float top, float right, float bo
|
||||
useProgram(mCaches.programCache.get(description));
|
||||
|
||||
// Setup attributes
|
||||
mCaches.bindMeshBuffer();
|
||||
glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
|
||||
gMeshStride, &mMeshVertices[0].position[0]);
|
||||
gMeshStride, 0);
|
||||
|
||||
// Setup uniforms
|
||||
mModelView.loadTranslate(left, top, 0.0f);
|
||||
@ -1218,21 +1215,20 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b
|
||||
getAlphaAndMode(paint, &alpha, &mode);
|
||||
|
||||
drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode,
|
||||
texture->blend, &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
|
||||
texture->blend, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset,
|
||||
GL_TRIANGLE_STRIP, gMeshCount);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
|
||||
GLuint texture, float alpha, SkXfermode::Mode mode, bool blend) {
|
||||
drawTextureMesh(left, top, right, bottom, texture, alpha, mode, blend,
|
||||
&mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
|
||||
GL_TRIANGLE_STRIP, gMeshCount);
|
||||
(GLvoid*) NULL, (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float bottom,
|
||||
GLuint texture, float alpha, SkXfermode::Mode mode, bool blend,
|
||||
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
|
||||
bool swapSrcDst, bool ignoreTransform) {
|
||||
bool swapSrcDst, bool ignoreTransform, GLuint vbo) {
|
||||
clearLayerRegions();
|
||||
|
||||
ProgramDescription description;
|
||||
@ -1267,6 +1263,12 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b
|
||||
// Mesh
|
||||
int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords");
|
||||
glEnableVertexAttribArray(texCoordsSlot);
|
||||
|
||||
if (!vertices) {
|
||||
mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo);
|
||||
} else {
|
||||
mCaches.unbindMeshBuffer();
|
||||
}
|
||||
glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
|
||||
gMeshStride, vertices);
|
||||
glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE, gMeshStride, texCoords);
|
||||
|
@ -234,8 +234,9 @@ private:
|
||||
const Texture* texture, const SkPaint* paint);
|
||||
|
||||
/**
|
||||
* Draws a textured mesh with the specified texture. If the indices are omitted, the
|
||||
* mesh is drawn as a simple quad.
|
||||
* Draws a textured mesh with the specified texture. If the indices are omitted,
|
||||
* the mesh is drawn as a simple quad. The mesh pointers become offsets when a
|
||||
* VBO is bound.
|
||||
*
|
||||
* @param left The left coordinate of the rectangle
|
||||
* @param top The top coordinate of the rectangle
|
||||
@ -247,15 +248,15 @@ private:
|
||||
* @param blend True if the texture contains an alpha channel
|
||||
* @param vertices The vertices that define the mesh
|
||||
* @param texCoords The texture coordinates of each vertex
|
||||
* @param indices The indices of the vertices, can be NULL
|
||||
* @param elementsCount The number of elements in the mesh, required by indices
|
||||
* @param swapSrcDst Whether or not the src and dst blending operations should be swapped
|
||||
* @param ignoreTransform True if the current transform should be ignored
|
||||
* @param vbo The VBO used to draw the mesh
|
||||
*/
|
||||
void drawTextureMesh(float left, float top, float right, float bottom, GLuint texture,
|
||||
float alpha, SkXfermode::Mode mode, bool blend,
|
||||
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
|
||||
bool swapSrcDst = false, bool ignoreTransform = false);
|
||||
bool swapSrcDst = false, bool ignoreTransform = false, GLuint vbo = 0);
|
||||
|
||||
/**
|
||||
* Prepares the renderer to draw the specified shadow.
|
||||
@ -315,12 +316,12 @@ private:
|
||||
|
||||
/**
|
||||
* Same as above setupTextureAlpha8() but specifies the mesh's vertices
|
||||
* and texCoords pointers.
|
||||
* and texCoords pointers. The pointers become offsets when a VBO is bound.
|
||||
*/
|
||||
void setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t height,
|
||||
GLuint& textureUnit, float x, float y, float r, float g, float b, float a,
|
||||
SkXfermode::Mode mode, bool transforms, bool applyFilters,
|
||||
GLvoid* vertices, GLvoid* texCoords);
|
||||
GLvoid* vertices, GLvoid* texCoords, GLuint vbo = 0);
|
||||
|
||||
/**
|
||||
* Draws text underline and strike-through if needed.
|
||||
|
@ -19,12 +19,16 @@
|
||||
#include <cmath>
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
#include "Patch.h"
|
||||
#include "Caches.h"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
class Caches;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Constructors/destructor
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -32,11 +36,14 @@ namespace uirenderer {
|
||||
Patch::Patch(const uint32_t xCount, const uint32_t yCount, const int8_t emptyQuads) {
|
||||
// 2 triangles per patch, 3 vertices per triangle
|
||||
verticesCount = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
|
||||
vertices = new TextureVertex[verticesCount];
|
||||
mVertices = new TextureVertex[verticesCount];
|
||||
|
||||
glGenBuffers(1, &meshBuffer);
|
||||
}
|
||||
|
||||
Patch::~Patch() {
|
||||
delete[] vertices;
|
||||
delete[] mVertices;
|
||||
glDeleteBuffers(1, &meshBuffer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -77,7 +84,7 @@ void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
|
||||
stretchY = yStretch / yStretchTex;
|
||||
}
|
||||
|
||||
TextureVertex* vertex = vertices;
|
||||
TextureVertex* vertex = mVertices;
|
||||
uint32_t quadCount = 0;
|
||||
|
||||
float previousStepY = 0.0f;
|
||||
@ -108,6 +115,10 @@ void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
|
||||
|
||||
generateRow(vertex, y1, bottom - top, v1, 1.0f, xDivs, width, stretchX,
|
||||
right - left, bitmapWidth, quadCount, colorKey);
|
||||
|
||||
Caches::getInstance().bindMeshBuffer(meshBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(TextureVertex) * verticesCount,
|
||||
mVertices, GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
inline void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "Vertex.h"
|
||||
#include "utils/Compare.h"
|
||||
|
||||
@ -59,14 +61,14 @@ struct PatchDescription {
|
||||
uint32_t colorKey;
|
||||
|
||||
bool operator<(const PatchDescription& rhs) const {
|
||||
compare(bitmapWidth) {
|
||||
compare(bitmapHeight) {
|
||||
compare(pixelWidth) {
|
||||
compare(pixelHeight) {
|
||||
compareI(xCount) {
|
||||
compareI(yCount) {
|
||||
compareI(emptyCount) {
|
||||
compareI(colorKey) return false;
|
||||
FLOAT_COMPARE(bitmapWidth) {
|
||||
FLOAT_COMPARE(bitmapHeight) {
|
||||
FLOAT_COMPARE(pixelWidth) {
|
||||
FLOAT_COMPARE(pixelHeight) {
|
||||
INT_COMPARE(xCount) {
|
||||
INT_COMPARE(yCount) {
|
||||
INT_COMPARE(emptyCount) {
|
||||
INT_COMPARE(colorKey) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -92,10 +94,12 @@ struct Patch {
|
||||
const uint32_t width, const uint32_t height,
|
||||
const uint32_t colorKey = 0);
|
||||
|
||||
TextureVertex* vertices;
|
||||
GLuint meshBuffer;
|
||||
uint32_t verticesCount;
|
||||
|
||||
private:
|
||||
TextureVertex* mVertices;
|
||||
|
||||
static inline void generateRow(TextureVertex*& vertex, float y1, float y2,
|
||||
float v1, float v2, const int32_t xDivs[], uint32_t xCount,
|
||||
float stretchX, float width, float bitmapWidth,
|
||||
|
@ -68,7 +68,7 @@ Patch* PatchCache::get(const float bitmapWidth, const float bitmapHeight,
|
||||
}
|
||||
|
||||
// If the 9patch is made of only transparent quads
|
||||
if (transparentQuads == (width + 1) * (height + 1)) {
|
||||
if (transparentQuads == int8_t((width + 1) * (height + 1))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -64,12 +64,12 @@ struct PathCacheEntry {
|
||||
float strokeWidth;
|
||||
|
||||
bool operator<(const PathCacheEntry& rhs) const {
|
||||
compareI(path) {
|
||||
compareI(join) {
|
||||
compareI(cap) {
|
||||
compareI(style) {
|
||||
compare(miter) {
|
||||
compare(strokeWidth) return false;
|
||||
INT_COMPARE(path) {
|
||||
INT_COMPARE(join) {
|
||||
INT_COMPARE(cap) {
|
||||
INT_COMPARE(style) {
|
||||
FLOAT_COMPARE(miter) {
|
||||
FLOAT_COMPARE(strokeWidth) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,19 +21,19 @@
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
|
||||
#define almost(u, v) (fabs((u) - (v)) < EPSILON)
|
||||
#define ALMOST_EQUAL(u, v) (fabs((u) - (v)) < EPSILON)
|
||||
|
||||
/**
|
||||
* Compare floats.
|
||||
*/
|
||||
#define compare(a) \
|
||||
#define FLOAT_COMPARE(a) \
|
||||
if (a < rhs.a) return true; \
|
||||
if (almost(a, rhs.a))
|
||||
if (ALMOST_EQUAL(a, rhs.a))
|
||||
|
||||
/**
|
||||
* Compare integers.
|
||||
*/
|
||||
#define compareI(a) \
|
||||
#define INT_COMPARE(a) \
|
||||
if (a < rhs.a) return true; \
|
||||
if (a == rhs.a)
|
||||
|
||||
|
Reference in New Issue
Block a user