diff options
-rw-r--r-- | libs/hwui/Caches.cpp | 21 | ||||
-rw-r--r-- | libs/hwui/Caches.h | 16 | ||||
-rw-r--r-- | libs/hwui/Dither.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/Dither.h | 2 | ||||
-rw-r--r-- | libs/hwui/FontRenderer.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/GammaFontRenderer.cpp | 15 | ||||
-rw-r--r-- | libs/hwui/GammaFontRenderer.h | 8 | ||||
-rw-r--r-- | libs/hwui/Glop.h | 108 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 75 | ||||
-rwxr-xr-x | libs/hwui/OpenGLRenderer.h | 12 | ||||
-rw-r--r-- | libs/hwui/Program.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/Program.h | 7 | ||||
-rw-r--r-- | libs/hwui/SkiaShader.cpp | 26 | ||||
-rw-r--r-- | libs/hwui/renderstate/MeshState.cpp | 15 | ||||
-rw-r--r-- | libs/hwui/renderstate/MeshState.h | 8 | ||||
-rw-r--r-- | libs/hwui/renderstate/RenderState.cpp | 85 | ||||
-rw-r--r-- | libs/hwui/renderstate/RenderState.h | 8 |
17 files changed, 293 insertions, 124 deletions
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index cef2c84..03b8283 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -72,9 +72,8 @@ bool Caches::init() { ATRACE_NAME("Caches::init"); - mRegionMesh = nullptr; - currentProgram = nullptr; + mProgram = nullptr; mFunctorsCount = 0; @@ -200,7 +199,7 @@ void Caches::terminate() { fboCache.clear(); programCache.clear(); - currentProgram = nullptr; + setProgram(nullptr); patchCache.clear(); @@ -213,6 +212,22 @@ void Caches::terminate() { mInitialized = false; } +void Caches::setProgram(const ProgramDescription& description) { + setProgram(programCache.get(description)); +} + +void Caches::setProgram(Program* program) { + if (!program || !program->isInUse()) { + if (mProgram) { + mProgram->remove(); + } + if (program) { + program->use(); + } + mProgram = program; + } +} + /////////////////////////////////////////////////////////////////////////////// // Debug /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index f6d3476..16e2058 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -162,8 +162,6 @@ public: void registerFunctors(uint32_t functorCount); void unregisterFunctors(uint32_t functorCount); - Program* currentProgram; - bool drawDeferDisabled; bool drawReorderDisabled; @@ -219,6 +217,10 @@ public: int propertyAmbientShadowStrength; int propertySpotShadowStrength; + void setProgram(const ProgramDescription& description); + void setProgram(Program* program); + + Program& program() { return *mProgram; } PixelBufferState& pixelBufferState() { return *mPixelBufferState; } TextureState& textureState() { return *mTextureState; } @@ -246,10 +248,6 @@ private: } RenderState* mRenderState; - - PixelBufferState* mPixelBufferState = nullptr; // TODO: move to RenderState - TextureState* mTextureState = nullptr; // TODO: move to RenderState - Extensions& mExtensions; // Used to render layers @@ -264,6 +262,12 @@ private: uint32_t mFunctorsCount; OverdrawColorSet mOverdrawDebugColorSet; + + // TODO: move below to RenderState + PixelBufferState* mPixelBufferState = nullptr; + TextureState* mTextureState = nullptr; + Program* mProgram = nullptr; // note: object owned by ProgramCache + }; // class Caches }; // namespace uirenderer diff --git a/libs/hwui/Dither.cpp b/libs/hwui/Dither.cpp index d637ec1..359c193 100644 --- a/libs/hwui/Dither.cpp +++ b/libs/hwui/Dither.cpp @@ -89,13 +89,13 @@ void Dither::clear() { // Program management /////////////////////////////////////////////////////////////////////////////// -void Dither::setupProgram(Program* program, GLuint* textureUnit) { +void Dither::setupProgram(Program& program, GLuint* textureUnit) { GLuint textureSlot = (*textureUnit)++; mCaches.textureState().activateTexture(textureSlot); bindDitherTexture(); - glUniform1i(program->getUniform("ditherSampler"), textureSlot); + glUniform1i(program.getUniform("ditherSampler"), textureSlot); } }; // namespace uirenderer diff --git a/libs/hwui/Dither.h b/libs/hwui/Dither.h index 38633af..facd1ea 100644 --- a/libs/hwui/Dither.h +++ b/libs/hwui/Dither.h @@ -39,7 +39,7 @@ public: Dither(Caches& caches); void clear(); - void setupProgram(Program* program, GLuint* textureUnit); + void setupProgram(Program& program, GLuint* textureUnit); private: void bindDitherTexture(); diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index 6dcd3e1..55b2d19 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -516,9 +516,8 @@ void FontRenderer::issueDrawCommand(Vector<CacheTexture*>& cacheTextures) { TextureVertex* mesh = texture->mesh(); MeshState& meshState = renderState.meshState(); - Program* program = caches.currentProgram; - meshState.bindPositionVertexPointer(program, forceRebind, &mesh[0].x); - meshState.bindTexCoordsVertexPointer(program, forceRebind, &mesh[0].u); + meshState.bindPositionVertexPointer(forceRebind, &mesh[0].x); + meshState.bindTexCoordsVertexPointer(forceRebind, &mesh[0].u); glDrawElements(GL_TRIANGLES, texture->meshElementCount(), GL_UNSIGNED_SHORT, texture->indices()); diff --git a/libs/hwui/GammaFontRenderer.cpp b/libs/hwui/GammaFontRenderer.cpp index e97a477..0bcd83a 100644 --- a/libs/hwui/GammaFontRenderer.cpp +++ b/libs/hwui/GammaFontRenderer.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include "Debug.h" #include "GammaFontRenderer.h" #include "Properties.h" @@ -96,7 +94,8 @@ GammaFontRenderer::~GammaFontRenderer() { // Shader-based renderer /////////////////////////////////////////////////////////////////////////////// -ShaderGammaFontRenderer::ShaderGammaFontRenderer(bool multiGamma): GammaFontRenderer() { +ShaderGammaFontRenderer::ShaderGammaFontRenderer(bool multiGamma) + : GammaFontRenderer() { INIT_LOGD("Creating shader gamma font renderer"); mRenderer = nullptr; mMultiGamma = multiGamma; @@ -123,9 +122,9 @@ void ShaderGammaFontRenderer::describe(ProgramDescription& description, } void ShaderGammaFontRenderer::setupProgram(ProgramDescription& description, - Program* program) const { + Program& program) const { if (description.hasGammaCorrection) { - glUniform1f(program->getUniform("gamma"), description.gamma); + glUniform1f(program.getUniform("gamma"), description.gamma); } } @@ -139,7 +138,8 @@ void ShaderGammaFontRenderer::endPrecaching() { // Lookup-based renderer /////////////////////////////////////////////////////////////////////////////// -LookupGammaFontRenderer::LookupGammaFontRenderer(): GammaFontRenderer() { +LookupGammaFontRenderer::LookupGammaFontRenderer() + : GammaFontRenderer() { INIT_LOGD("Creating lookup gamma font renderer"); // Compute the gamma tables @@ -162,7 +162,8 @@ void LookupGammaFontRenderer::endPrecaching() { // Lookup-based renderer, using 3 different correction tables /////////////////////////////////////////////////////////////////////////////// -Lookup3GammaFontRenderer::Lookup3GammaFontRenderer(): GammaFontRenderer() { +Lookup3GammaFontRenderer::Lookup3GammaFontRenderer() + : GammaFontRenderer() { INIT_LOGD("Creating lookup3 gamma font renderer"); // Compute the gamma tables diff --git a/libs/hwui/GammaFontRenderer.h b/libs/hwui/GammaFontRenderer.h index 19352d7..ca55bf1 100644 --- a/libs/hwui/GammaFontRenderer.h +++ b/libs/hwui/GammaFontRenderer.h @@ -38,7 +38,7 @@ public: virtual uint32_t getFontRendererSize(uint32_t fontRenderer, GLenum format) const = 0; virtual void describe(ProgramDescription& description, const SkPaint* paint) const = 0; - virtual void setupProgram(ProgramDescription& description, Program* program) const = 0; + virtual void setupProgram(ProgramDescription& description, Program& program) const = 0; virtual void endPrecaching() = 0; @@ -86,7 +86,7 @@ public: } void describe(ProgramDescription& description, const SkPaint* paint) const override; - void setupProgram(ProgramDescription& description, Program* program) const override; + void setupProgram(ProgramDescription& description, Program& program) const override; void endPrecaching() override; @@ -135,7 +135,7 @@ public: void describe(ProgramDescription& description, const SkPaint* paint) const override { } - void setupProgram(ProgramDescription& description, Program* program) const override { + void setupProgram(ProgramDescription& description, Program& program) const override { } void endPrecaching() override; @@ -171,7 +171,7 @@ public: void describe(ProgramDescription& description, const SkPaint* paint) const override { } - void setupProgram(ProgramDescription& description, Program* program) const override { + void setupProgram(ProgramDescription& description, Program& program) const override { } void endPrecaching() override; diff --git a/libs/hwui/Glop.h b/libs/hwui/Glop.h new file mode 100644 index 0000000..730d9df --- /dev/null +++ b/libs/hwui/Glop.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2015 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. + */ + +#ifndef ANDROID_HWUI_GLOP_H +#define ANDROID_HWUI_GLOP_H + +#include "Matrix.h" +#include "Rect.h" +#include "utils/Macros.h" + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +namespace android { +namespace uirenderer { + +/* + * Enumerates optional vertex attributes + * + * Position is always enabled by MeshState, these other attributes + * are enabled/disabled dynamically based on mesh content. + */ +enum VertexAttribFlags { + // NOTE: position attribute always enabled + kTextureCoord_Attrib = 1 << 0, + kColor_Attrib = 1 << 1, + kAlpha_Attrib = 1 << 2, +}; + +/** + * Structure containing all data required to issue a single OpenGL draw + * + * Includes all of the mesh, fill, and GL state required to perform + * the operation. Pieces of data are either directly copied into the + * structure, or stored as a pointer or GL object reference to data + * managed + */ +// TODO: PREVENT_COPY_AND_ASSIGN(...) or similar +struct Glop { + Rect bounds; + + struct Mesh { + VertexAttribFlags vertexFlags = static_cast<VertexAttribFlags>(0); + GLuint primitiveMode; // GL_TRIANGLES and GL_TRIANGLE_STRIP supported + GLuint vertexBufferObject = 0; + GLuint indexBufferObject = 0; + int vertexCount; + GLsizei stride; + } mesh; + + struct Fill { + Program* program; + GLuint shaderId; + GLuint textureId; + + struct Color { + float a, r, g, b; + } color; + + /* TODO + union shader { + //... + }; TODO + union filter { + //color + //matrix + vector + }; + */ + } fill; + + struct Transform { + Matrix4 ortho; // TODO: out of op, since this is static per FBO + Matrix4 modelView; + Matrix4 canvas; + bool offset; + } transform; + + struct Blend { + static const SkXfermode::Mode kDisable = + static_cast<SkXfermode::Mode>(SkXfermode::kLastMode + 1); + SkXfermode::Mode mode; + bool swapSrcDst; + } blend; + + /** + * Additional render state to enumerate: + * - scissor + (bits for whether each of LTRB needed?) + * - stencil mode (draw into, mask, count, etc) + */ +}; + +} /* namespace uirenderer */ +} /* namespace android */ + +#endif // ANDROID_HWUI_GLOP_H diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 2378337..ab6f0ce 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include "OpenGLRenderer.h" #include "DeferredDisplayList.h" @@ -137,8 +135,6 @@ void OpenGLRenderer::initLight(const Vector3& lightCenter, float lightRadius, void OpenGLRenderer::onViewportInitialized() { glDisable(GL_DITHER); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - glEnableVertexAttribArray(Program::kBindingPosition); mFirstFrameAfterResize = true; } @@ -1715,20 +1711,20 @@ void OpenGLRenderer::setupDrawBlending(const SkPaint* paint, bool blend, bool sw } void OpenGLRenderer::setupDrawProgram() { - useProgram(mCaches.programCache.get(mDescription)); + mCaches.setProgram(mDescription); if (mDescription.hasRoundRectClip) { // TODO: avoid doing this repeatedly, stashing state pointer in program const RoundRectClipState* state = writableSnapshot()->roundRectClipState; const Rect& innerRect = state->innerRect; - glUniform4f(mCaches.currentProgram->getUniform("roundRectInnerRectLTRB"), + glUniform4f(mCaches.program().getUniform("roundRectInnerRectLTRB"), innerRect.left, innerRect.top, innerRect.right, innerRect.bottom); - glUniformMatrix4fv(mCaches.currentProgram->getUniform("roundRectInvTransform"), + glUniformMatrix4fv(mCaches.program().getUniform("roundRectInvTransform"), 1, GL_FALSE, &state->matrix.data[0]); // add half pixel to round out integer rect space to cover pixel centers float roundedOutRadius = state->radius + 0.5f; - glUniform1f(mCaches.currentProgram->getUniform("roundRectRadius"), + glUniform1f(mCaches.program().getUniform("roundRectRadius"), roundedOutRadius); } } @@ -1746,7 +1742,8 @@ void OpenGLRenderer::setupDrawModelView(ModelViewMode mode, bool offset, bool dirty = right - left > 0.0f && bottom - top > 0.0f; const Matrix4& transformMatrix = ignoreTransform ? Matrix4::identity() : *currentTransform(); - mCaches.currentProgram->set(writableSnapshot()->getOrthoMatrix(), + + mCaches.program().set(currentSnapshot()->getOrthoMatrix(), mModelViewMatrix, transformMatrix, offset); if (dirty && mTrackDirtyRegions) { if (!ignoreTransform) { @@ -1759,13 +1756,13 @@ void OpenGLRenderer::setupDrawModelView(ModelViewMode mode, bool offset, void OpenGLRenderer::setupDrawColorUniforms(bool hasShader) { if ((mColorSet && !hasShader) || (hasShader && mSetShaderColor)) { - mCaches.currentProgram->setColor(mColorR, mColorG, mColorB, mColorA); + mCaches.program().setColor(mColorR, mColorG, mColorB, mColorA); } } void OpenGLRenderer::setupDrawPureColorUniforms() { if (mSetShaderColor) { - mCaches.currentProgram->setColor(mColorR, mColorG, mColorB, mColorA); + mCaches.program().setColor(mColorR, mColorG, mColorB, mColorA); } } @@ -1800,7 +1797,7 @@ void OpenGLRenderer::setupDrawColorFilterUniforms(const SkColorFilter* filter) { const GLfloat r = a * SkColorGetR(color) / 255.0f; const GLfloat g = a * SkColorGetG(color) / 255.0f; const GLfloat b = a * SkColorGetB(color) / 255.0f; - glUniform4f(mCaches.currentProgram->getUniform("colorBlend"), r, g, b, a); + glUniform4f(mCaches.program().getUniform("colorBlend"), r, g, b, a); return; } @@ -1821,9 +1818,9 @@ void OpenGLRenderer::setupDrawColorFilterUniforms(const SkColorFilter* filter) { colorVector[2] = srcColorMatrix[14] / 255.0f; colorVector[3] = srcColorMatrix[19] / 255.0f; - glUniformMatrix4fv(mCaches.currentProgram->getUniform("colorMatrix"), 1, + glUniformMatrix4fv(mCaches.program().getUniform("colorMatrix"), 1, GL_FALSE, colorMatrix); - glUniform4fv(mCaches.currentProgram->getUniform("colorMatrixVector"), 1, colorVector); + glUniform4fv(mCaches.program().getUniform("colorMatrixVector"), 1, colorVector); return; } @@ -1831,12 +1828,12 @@ void OpenGLRenderer::setupDrawColorFilterUniforms(const SkColorFilter* filter) { } void OpenGLRenderer::setupDrawTextGammaUniforms() { - mCaches.fontRenderer->setupProgram(mDescription, mCaches.currentProgram); + mCaches.fontRenderer->setupProgram(mDescription, mCaches.program()); } void OpenGLRenderer::setupDrawSimpleMesh() { bool force = mRenderState.meshState().bindMeshBuffer(); - mRenderState.meshState().bindPositionVertexPointer(mCaches.currentProgram, force, nullptr); + mRenderState.meshState().bindPositionVertexPointer(force, nullptr); mRenderState.meshState().unbindIndicesBuffer(); } @@ -1857,7 +1854,7 @@ void OpenGLRenderer::setupDrawTextureTransform() { } void OpenGLRenderer::setupDrawTextureTransformUniforms(mat4& transform) { - glUniformMatrix4fv(mCaches.currentProgram->getUniform("mainTextureTransform"), 1, + glUniformMatrix4fv(mCaches.program().getUniform("mainTextureTransform"), 1, GL_FALSE, &transform.data[0]); } @@ -1870,9 +1867,9 @@ void OpenGLRenderer::setupDrawMesh(const GLvoid* vertices, force = mRenderState.meshState().unbindMeshBuffer(); } - mRenderState.meshState().bindPositionVertexPointer(mCaches.currentProgram, force, vertices); - if (mCaches.currentProgram->texCoords >= 0) { - mRenderState.meshState().bindTexCoordsVertexPointer(mCaches.currentProgram, force, texCoords); + mRenderState.meshState().bindPositionVertexPointer(force, vertices); + if (mCaches.program().texCoords >= 0) { + mRenderState.meshState().bindTexCoordsVertexPointer(force, texCoords); } mRenderState.meshState().unbindIndicesBuffer(); @@ -1883,13 +1880,11 @@ void OpenGLRenderer::setupDrawMesh(const GLvoid* vertices, bool force = mRenderState.meshState().unbindMeshBuffer(); GLsizei stride = sizeof(ColorTextureVertex); - mRenderState.meshState().bindPositionVertexPointer(mCaches.currentProgram, force, - vertices, stride); - if (mCaches.currentProgram->texCoords >= 0) { - mRenderState.meshState().bindTexCoordsVertexPointer(mCaches.currentProgram, force, - texCoords, stride); + mRenderState.meshState().bindPositionVertexPointer(force, vertices, stride); + if (mCaches.program().texCoords >= 0) { + mRenderState.meshState().bindTexCoordsVertexPointer(force, texCoords, stride); } - int slot = mCaches.currentProgram->getAttrib("colors"); + int slot = mCaches.program().getAttrib("colors"); if (slot >= 0) { glEnableVertexAttribArray(slot); glVertexAttribPointer(slot, 4, GL_FLOAT, GL_FALSE, stride, colors); @@ -1911,18 +1906,16 @@ void OpenGLRenderer::setupDrawMeshIndices(const GLvoid* vertices, } mRenderState.meshState().bindQuadIndicesBuffer(); - mRenderState.meshState().bindPositionVertexPointer(mCaches.currentProgram, force, vertices); - if (mCaches.currentProgram->texCoords >= 0) { - mRenderState.meshState().bindTexCoordsVertexPointer(mCaches.currentProgram, - force, texCoords); + mRenderState.meshState().bindPositionVertexPointer(force, vertices); + if (mCaches.program().texCoords >= 0) { + mRenderState.meshState().bindTexCoordsVertexPointer(force, texCoords); } } void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) { bool force = mRenderState.meshState().unbindMeshBuffer(); mRenderState.meshState().bindQuadIndicesBuffer(); - mRenderState.meshState().bindPositionVertexPointer(mCaches.currentProgram, force, - vertices, kVertexStride); + mRenderState.meshState().bindPositionVertexPointer(force, vertices, kVertexStride); } /////////////////////////////////////////////////////////////////////////////// @@ -2144,7 +2137,7 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m glDrawArrays(GL_TRIANGLES, 0, count); - int slot = mCaches.currentProgram->getAttrib("colors"); + int slot = mCaches.program().getAttrib("colors"); if (slot >= 0) { glDisableVertexAttribArray(slot); } @@ -2360,14 +2353,14 @@ void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, const void* vertices = vertexBuffer.getBuffer(); mRenderState.meshState().unbindMeshBuffer(); - mRenderState.meshState().bindPositionVertexPointer(mCaches.currentProgram, - true, vertices, isAA ? kAlphaVertexStride : kVertexStride); + mRenderState.meshState().bindPositionVertexPointer(true, vertices, + isAA ? kAlphaVertexStride : kVertexStride); mRenderState.meshState().resetTexCoordsVertexPointer(); int alphaSlot = -1; if (isAA) { void* alphaCoords = ((GLbyte*) vertices) + kVertexAlphaOffset; - alphaSlot = mCaches.currentProgram->getAttrib("vtxAlpha"); + alphaSlot = mCaches.program().getAttrib("vtxAlpha"); // TODO: avoid enable/disable in back to back uses of the alpha attribute glEnableVertexAttribArray(alphaSlot); glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, kAlphaVertexStride, alphaCoords); @@ -3440,16 +3433,6 @@ void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, } } -bool OpenGLRenderer::useProgram(Program* program) { - if (!program->isInUse()) { - if (mCaches.currentProgram != nullptr) mCaches.currentProgram->remove(); - program->use(); - mCaches.currentProgram = program; - return false; - } - return true; -} - void OpenGLRenderer::resetDrawTextureTexCoords(float u1, float v1, float u2, float v2) { TextureVertex* v = &mMeshVertices[0]; TextureVertex::setUV(v++, u1, v1); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index cf6f0c8..f0de089 100755 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -853,18 +853,6 @@ private: bool swapSrcDst = false); /** - * Use the specified program with the current GL context. If the program is already - * in use, it will not be bound again. If it is not in use, the current program is - * marked unused and the specified program becomes used and becomes the new - * current program. - * - * @param program The program to use - * - * @return true If the specified program was already in use, false otherwise. - */ - inline bool useProgram(Program* program); - - /** * Invoked before any drawing operation. This sets required state. */ void setupDraw(bool clear = true); diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp index fb07dfa..5f34b34 100644 --- a/libs/hwui/Program.cpp +++ b/libs/hwui/Program.cpp @@ -46,7 +46,7 @@ Program::Program(const ProgramDescription& description, const char* vertex, cons glAttachShader(mProgramId, mVertexShader); glAttachShader(mProgramId, mFragmentShader); - position = bindAttrib("position", kBindingPosition); + bindAttrib("position", kBindingPosition); if (description.hasTexture || description.hasExternalTexture) { texCoords = bindAttrib("texCoords", kBindingTexCoords); } else { diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index d05b331..b637450 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -366,12 +366,7 @@ public: void setColor(const float r, const float g, const float b, const float a); /** - * Name of the position attribute. - */ - int position; - - /** - * Name of the texCoords attribute if it exists, -1 otherwise. + * Name of the texCoords attribute if it exists (kBindingTexCoords), -1 otherwise. */ int texCoords; diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index e13c861..9c929da 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -191,11 +191,11 @@ void SkiaLayerShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, layer->setWrap(GL_CLAMP_TO_EDGE); layer->setFilter(GL_LINEAR); - Program* program = caches->currentProgram; - glUniform1i(program->getUniform("bitmapSampler"), textureSlot); - glUniformMatrix4fv(program->getUniform("textureTransform"), 1, + Program& program = caches->program(); + glUniform1i(program.getUniform("bitmapSampler"), textureSlot); + glUniformMatrix4fv(program.getUniform("textureTransform"), 1, GL_FALSE, &textureTransform.data[0]); - glUniform2f(program->getUniform("textureDimension"), 1.0f / width, 1.0f / height); + glUniform2f(program.getUniform("textureDimension"), 1.0f / width, 1.0f / height); } /////////////////////////////////////////////////////////////////////////////// @@ -277,7 +277,7 @@ void SkiaBitmapShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, return; } - Program* program = caches->currentProgram; + Program& program = caches->program(); Texture* texture = shaderInfo.texture; const AutoTexture autoCleanup(texture); @@ -290,10 +290,10 @@ void SkiaBitmapShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, bindTexture(caches, texture, shaderInfo.wrapS, shaderInfo.wrapT); texture->setFilter(GL_LINEAR); - glUniform1i(program->getUniform("bitmapSampler"), textureSlot); - glUniformMatrix4fv(program->getUniform("textureTransform"), 1, + glUniform1i(program.getUniform("bitmapSampler"), textureSlot); + glUniformMatrix4fv(program.getUniform("textureTransform"), 1, GL_FALSE, &textureTransform.data[0]); - glUniform2f(program->getUniform("textureDimension"), 1.0f / shaderInfo.width, + glUniform2f(program.getUniform("textureDimension"), 1.0f / shaderInfo.width, 1.0f / shaderInfo.height); } @@ -381,7 +381,7 @@ void SkiaGradientShader::setupProgram(Caches* caches, const mat4& modelViewMatri SkShader::GradientType gradType = shader.asAGradient(&gradInfo); - Program* program = caches->currentProgram; + Program& program = caches->program(); if (CC_UNLIKELY(!isSimpleGradient(gradInfo))) { if (gradInfo.fColorCount > COLOR_COUNT) { // There was not enough room in our arrays for all the colors and offsets. Try again, @@ -402,10 +402,10 @@ void SkiaGradientShader::setupProgram(Caches* caches, const mat4& modelViewMatri // Uniforms bindTexture(caches, texture, gTileModes[gradInfo.fTileMode], gTileModes[gradInfo.fTileMode]); - glUniform1i(program->getUniform("gradientSampler"), textureSlot); + glUniform1i(program.getUniform("gradientSampler"), textureSlot); } else { - bindUniformColor(program->getUniform("startColor"), gradInfo.fColors[0]); - bindUniformColor(program->getUniform("endColor"), gradInfo.fColors[1]); + bindUniformColor(program.getUniform("startColor"), gradInfo.fColors[0]); + bindUniformColor(program.getUniform("endColor"), gradInfo.fColors[1]); } caches->dither.setupProgram(program, textureUnit); @@ -428,7 +428,7 @@ void SkiaGradientShader::setupProgram(Caches* caches, const mat4& modelViewMatri mat4 screenSpace; computeScreenSpaceMatrix(screenSpace, unitMatrix, shader.getLocalMatrix(), modelViewMatrix); - glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); + glUniformMatrix4fv(program.getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/renderstate/MeshState.cpp b/libs/hwui/renderstate/MeshState.cpp index 7820a66..022faf7 100644 --- a/libs/hwui/renderstate/MeshState.cpp +++ b/libs/hwui/renderstate/MeshState.cpp @@ -39,6 +39,9 @@ MeshState::MeshState() mQuadListIndices = 0; mShadowStripsIndices = 0; + + // position attribute always enabled + glEnableVertexAttribArray(Program::kBindingPosition); } MeshState::~MeshState() { @@ -83,21 +86,17 @@ bool MeshState::unbindMeshBuffer() { // Vertices /////////////////////////////////////////////////////////////////////////////// -void MeshState::bindPositionVertexPointer(const Program* currentProgram, bool force, - const GLvoid* vertices, GLsizei stride) { +void MeshState::bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) { if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) { - GLuint slot = currentProgram->position; - glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices); + glVertexAttribPointer(Program::kBindingPosition, 2, GL_FLOAT, GL_FALSE, stride, vertices); mCurrentPositionPointer = vertices; mCurrentPositionStride = stride; } } -void MeshState::bindTexCoordsVertexPointer(const Program* currentProgram, bool force, - const GLvoid* vertices, GLsizei stride) { +void MeshState::bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) { if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) { - GLuint slot = currentProgram->texCoords; - glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices); + glVertexAttribPointer(Program::kBindingTexCoords, 2, GL_FLOAT, GL_FALSE, stride, vertices); mCurrentTexCoordsPointer = vertices; mCurrentTexCoordsStride = stride; } diff --git a/libs/hwui/renderstate/MeshState.h b/libs/hwui/renderstate/MeshState.h index 76f73d4..9b1021d 100644 --- a/libs/hwui/renderstate/MeshState.h +++ b/libs/hwui/renderstate/MeshState.h @@ -80,15 +80,15 @@ public: * Binds an attrib to the specified float vertex pointer. * Assumes a stride of gTextureVertexStride and a size of 2. */ - void bindPositionVertexPointer(const Program* currentProgram, bool force, - const GLvoid* vertices, GLsizei stride = kTextureVertexStride); + void bindPositionVertexPointer(bool force, const GLvoid* vertices, + GLsizei stride = kTextureVertexStride); /** * Binds an attrib to the specified float vertex pointer. * Assumes a stride of gTextureVertexStride and a size of 2. */ - void bindTexCoordsVertexPointer(const Program* currentProgram, bool force, - const GLvoid* vertices, GLsizei stride = kTextureVertexStride); + void bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, + GLsizei stride = kTextureVertexStride); /** * Resets the vertex pointers. diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp index f913cd9..8eda7c9 100644 --- a/libs/hwui/renderstate/RenderState.cpp +++ b/libs/hwui/renderstate/RenderState.cpp @@ -127,12 +127,7 @@ void RenderState::invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlI } void RenderState::interruptForFunctorInvoke() { - if (mCaches->currentProgram) { - if (mCaches->currentProgram->isInUse()) { - mCaches->currentProgram->remove(); - mCaches->currentProgram = nullptr; - } - } + mCaches->setProgram(nullptr); mCaches->textureState().resetActiveTexture(); meshState().unbindMeshBuffer(); meshState().unbindIndicesBuffer(); @@ -179,7 +174,6 @@ void RenderState::assertOnGLThread() { LOG_ALWAYS_FATAL_IF(!pthread_equal(mThreadId, curr), "Wrong thread!"); } - class DecStrongTask : public renderthread::RenderTask { public: DecStrongTask(VirtualLightRefBase* object) : mObject(object) {} @@ -198,5 +192,82 @@ void RenderState::postDecStrong(VirtualLightRefBase* object) { mRenderThread.queue(new DecStrongTask(object)); } +/////////////////////////////////////////////////////////////////////////////// +// Render +/////////////////////////////////////////////////////////////////////////////// + +/* + * Not yet supported: + * + * Textures + coordinates + * SkiaShader + * ColorFilter + * + // TODO: texture coord + // TODO: texture support + // TODO: skiashader support + // TODO: color filter support + */ + +void RenderState::render(const Glop& glop) { + const Glop::Mesh& mesh = glop.mesh; + const Glop::Fill& shader = glop.fill; + + // ---------- Shader + uniform setup ---------- + mCaches->setProgram(shader.program); + + Glop::Fill::Color color = shader.color; + shader.program->setColor(color.a, color.r, color.g, color.b); + + shader.program->set(glop.transform.ortho, + glop.transform.modelView, + glop.transform.canvas, + glop.transform.offset); + + // ---------- Mesh setup ---------- + if (glop.mesh.vertexFlags & kTextureCoord_Attrib) { + // TODO: support textures + LOG_ALWAYS_FATAL("textures not yet supported"); + } else { + meshState().disableTexCoordsVertexArray(); + } + if (glop.mesh.vertexFlags & kColor_Attrib) { + LOG_ALWAYS_FATAL("color attribute not yet supported"); + // TODO: enable color, disable when done + } + if (glop.mesh.vertexFlags & kAlpha_Attrib) { + LOG_ALWAYS_FATAL("alpha attribute not yet supported"); + // TODO: enable alpha attribute, disable when done + } + + /** + * Hard-coded vertex assumptions: + * - required + * - xy floats + * - 0 offset + * - in VBO + */ + bool force = meshState().bindMeshBuffer(mesh.vertexBufferObject); + meshState().bindPositionVertexPointer(force, nullptr, mesh.stride); + + /** + * Hard-coded index assumptions: + * - optional + * - 0 offset + * - in IBO + */ + meshState().bindIndicesBufferInternal(mesh.indexBufferObject); + + // ---------- GL state setup ---------- + + if (glop.blend.mode != Glop::Blend::kDisable) { + blend().enable(glop.blend.mode, glop.blend.swapSrcDst); + } else { + blend().disable(); + } + + glDrawElements(glop.mesh.primitiveMode, glop.mesh.vertexCount, GL_UNSIGNED_BYTE, nullptr); +} + } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h index 4180f44..2e28ff6 100644 --- a/libs/hwui/renderstate/RenderState.h +++ b/libs/hwui/renderstate/RenderState.h @@ -22,11 +22,12 @@ #include <utils/Mutex.h> #include <utils/Functor.h> #include <utils/RefBase.h> - #include <private/hwui/DrawGlInfo.h> #include <renderstate/Blend.h> + #include "AssetAtlas.h" #include "Caches.h" +#include "Glop.h" #include "renderstate/MeshState.h" #include "renderstate/PixelBufferState.h" #include "renderstate/Scissor.h" @@ -83,6 +84,8 @@ public: // more thinking... void postDecStrong(VirtualLightRefBase* object); + void render(const Glop& glop); + AssetAtlas& assetAtlas() { return mAssetAtlas; } Blend& blend() { return *mBlend; } MeshState& meshState() { return *mMeshState; } @@ -96,6 +99,9 @@ private: void resumeFromFunctorInvoke(); void assertOnGLThread(); + void setupVertexAttributes(const Glop& glop); + void tearDownVertexAttributes(const Glop& glop); + RenderState(renderthread::RenderThread& thread); ~RenderState(); |