Loading core/java/android/view/GLES20Canvas.java +12 −8 Original line number Diff line number Diff line Loading @@ -278,30 +278,34 @@ class GLES20Canvas extends Canvas { @Override public int saveLayer(RectF bounds, Paint paint, int saveFlags) { // TODO: Implement return 0; return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags); } @Override public int saveLayer(float left, float top, float right, float bottom, Paint paint, int saveFlags) { // TODO: Implement return 0; int nativePaint = paint == null ? 0 : paint.mNativePaint; return nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags); } private native int nSaveLayer(int renderer, float left, float top, float right, float bottom, int paint, int saveFlags); @Override public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) { // TODO: Implement return 0; return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, alpha, saveFlags); } @Override public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, int saveFlags) { // TODO: Implement return 0; return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags); } private native int nSaveLayerAlpha(int renderer, float left, float top, float right, float bottom, int alpha, int saveFlags); @Override public void restore() { nRestore(mRenderer); Loading core/jni/android_view_GLES20Canvas.cpp +43 −24 Original line number Diff line number Diff line Loading @@ -91,6 +91,22 @@ static void android_view_GLES20Renderer_restoreToCount(JNIEnv* env, jobject canv renderer->restoreToCount(saveCount); } // ---------------------------------------------------------------------------- // Layers // ---------------------------------------------------------------------------- static jint android_view_GLES20Renderer_saveLayer(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, SkPaint* paint, jint saveFlags) { return renderer->saveLayer(left, top, right, bottom, paint, saveFlags); } static jint android_view_GLES20Renderer_saveLayerAlpha(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, jint alpha, jint saveFlags) { return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags); } // ---------------------------------------------------------------------------- // Clipping // ---------------------------------------------------------------------------- Loading Loading @@ -188,6 +204,9 @@ static JNINativeMethod gMethods[] = { { "nRestoreToCount", "(II)V", (void*) android_view_GLES20Renderer_restoreToCount }, { "nGetSaveCount", "(I)I", (void*) android_view_GLES20Renderer_getSaveCount }, { "nSaveLayer", "(IFFFFII)I", (void*) android_view_GLES20Renderer_saveLayer }, { "nSaveLayerAlpha", "(IFFFFII)I", (void*) android_view_GLES20Renderer_saveLayerAlpha }, { "nQuickReject", "(IFFFFI)Z", (void*) android_view_GLES20Renderer_quickReject }, { "nClipRect", "(IFFFF)Z", (void*) android_view_GLES20Renderer_clipRectF }, { "nClipRect", "(IIIII)Z", (void*) android_view_GLES20Renderer_clipRect }, Loading libs/hwui/Matrix.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,14 @@ void Matrix4::copyTo(float* v) const { memcpy(v, data, sizeof(data)); } float Matrix4::getTranslateX() { return data[12]; } float Matrix4::getTranslateY() { return data[13]; } void Matrix4::loadTranslate(float x, float y, float z) { loadIdentity(); data[12] = x; Loading libs/hwui/Matrix.h +3 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,9 @@ public: void mapRect(Rect& r) const; float getTranslateX(); float getTranslateY(); void dump() const; private: Loading libs/hwui/OpenGLRenderer.cpp +151 −10 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> #include <SkCanvas.h> #include <SkPaint.h> #include <SkXfermode.h> Loading @@ -40,21 +41,31 @@ namespace uirenderer { // Defines /////////////////////////////////////////////////////////////////////////////// #define V(x, y) { { x, y } } #define SV(x, y) { { x, y } } #define FV(x, y, u, v) { { x, y }, { u, v } } /////////////////////////////////////////////////////////////////////////////// // Globals /////////////////////////////////////////////////////////////////////////////// const SimpleVertex gDrawColorVertices[] = { V(0.0f, 0.0f), V(1.0f, 0.0f), V(0.0f, 1.0f), V(1.0f, 1.0f) SV(0.0f, 0.0f), SV(1.0f, 0.0f), SV(0.0f, 1.0f), SV(1.0f, 1.0f) }; const GLsizei gDrawColorVertexStride = sizeof(SimpleVertex); const GLsizei gDrawColorVertexCount = 4; const TextureVertex gDrawTextureVertices[] = { FV(0.0f, 0.0f, 0.0f, 1.0f), FV(1.0f, 0.0f, 1.0f, 1.0f), FV(0.0f, 1.0f, 0.0f, 0.0f), FV(1.0f, 1.0f, 1.0f, 0.0f) }; const GLsizei gDrawTextureVertexStride = sizeof(TextureVertex); const GLsizei gDrawTextureVertexCount = 4; /////////////////////////////////////////////////////////////////////////////// // Shaders /////////////////////////////////////////////////////////////////////////////// Loading @@ -64,6 +75,9 @@ const GLsizei gDrawColorVertexCount = 4; #include "shaders/drawColor.vert" #include "shaders/drawColor.frag" #include "shaders/drawTexture.vert" #include "shaders/drawTexture.frag" Program::Program(const char* vertex, const char* fragment) { vertexShader = buildShader(vertex, GL_VERTEX_SHADER); fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); Loading Loading @@ -139,6 +153,15 @@ GLuint Program::buildShader(const char* source, GLenum type) { DrawColorProgram::DrawColorProgram(): Program(gDrawColorVertexShader, gDrawColorFragmentShader) { getAttribsAndUniforms(); } DrawColorProgram::DrawColorProgram(const char* vertex, const char* fragment): Program(vertex, fragment) { getAttribsAndUniforms(); } void DrawColorProgram::getAttribsAndUniforms() { position = addAttrib("position"); color = addAttrib("color"); projection = addUniform("projection"); Loading @@ -154,6 +177,12 @@ void DrawColorProgram::use(const GLfloat* projectionMatrix, const GLfloat* model glUniformMatrix4fv(transform, 1, GL_FALSE, transformMatrix); } DrawTextureProgram::DrawTextureProgram(): DrawColorProgram(gDrawTextureVertexShader, gDrawTextureFragmentShader) { texCoords = addAttrib("texCoords"); sampler = addUniform("sampler"); } /////////////////////////////////////////////////////////////////////////////// // Support /////////////////////////////////////////////////////////////////////////////// Loading @@ -175,6 +204,7 @@ OpenGLRenderer::OpenGLRenderer() { LOGD("Create OpenGLRenderer"); mDrawColorShader = new DrawColorProgram; mDrawTextureShader = new DrawTextureProgram; } OpenGLRenderer::~OpenGLRenderer() { Loading Loading @@ -252,16 +282,89 @@ int OpenGLRenderer::saveSnapshot() { bool OpenGLRenderer::restoreSnapshot() { bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet; bool restoreLayer = mSnapshot->flags & Snapshot::kFlagIsLayer; mSaveCount--; // Do not merge these two lines! sp<Snapshot> current = mSnapshot; sp<Snapshot> previous = mSnapshot->previous; if (restoreLayer) { // Unbind current FBO and restore previous one // Most of the time, previous->fbo will be 0 to bind the default buffer glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo); const Rect& layer = current->layer; clipRect(layer.left, layer.top, layer.right, layer.bottom); mSnapshot->transform.loadIdentity(); drawTextureRect(0.0f, 0.0f, mWidth, mHeight, current->texture, current->alpha); glDeleteFramebuffers(1, ¤t->fbo); glDeleteTextures(1, ¤t->texture); } mSnapshot = previous; mSaveCount--; return restoreClip; } /////////////////////////////////////////////////////////////////////////////// // Layers /////////////////////////////////////////////////////////////////////////////// int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom, const SkPaint* p, int flags) { // TODO Implement return saveSnapshot(); } int OpenGLRenderer::saveLayerAlpha(float left, float top, float right, float bottom, int alpha, int flags) { int count = saveSnapshot(); mSnapshot->flags |= Snapshot::kFlagIsLayer; mSnapshot->alpha = alpha / 255.0f; mSnapshot->layer.set(left, top, right, bottom); // Generate the FBO and attach the texture glGenFramebuffers(1, &mSnapshot->fbo); glBindFramebuffer(GL_FRAMEBUFFER, mSnapshot->fbo); // Generate the texture in which the FBO will draw glGenTextures(1, &mSnapshot->texture); glBindTexture(GL_TEXTURE_2D, mSnapshot->texture); // The FBO will not be scaled, so we can use lower quality filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // TODO ***** IMPORTANT ***** // Creating a texture-backed FBO works only if the texture is the same size // as the original rendering buffer (in this case, mWidth and mHeight.) // This is expensive and wasteful and must be fixed. const GLsizei width = mWidth; //right - left; const GLsizei height = mHeight; //bottom - right; const GLint format = (flags & SkCanvas::kHasAlphaLayer_SaveFlag) ? GL_RGBA : GL_RGB; glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, 0); // Bind texture to FBO glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mSnapshot->texture, 0); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { LOGD("Framebuffer incomplete %d", status); glDeleteFramebuffers(1, &mSnapshot->fbo); glDeleteTextures(1, &mSnapshot->texture); } return count; } /////////////////////////////////////////////////////////////////////////////// // Transforms /////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -346,10 +449,10 @@ void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color); } void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* paint) { void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) { // TODO Support more than just color // TODO: Set the transfer mode drawColorRect(left, top, right, bottom, paint->getColor()); drawColorRect(left, top, right, bottom, p->getColor()); } void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, int color) { Loading @@ -375,5 +478,43 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot glDisableVertexAttribArray(mDrawColorShader->position); } void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, GLuint texture, float alpha) { mModelView.loadTranslate(left, top, 0.0f); mModelView.scale(right - left, bottom - top, 1.0f); mDrawTextureShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]); // TODO Correctly set the blend function glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glBindTexture(GL_TEXTURE_2D, texture); glActiveTexture(GL_TEXTURE0); glUniform1i(mDrawTextureShader->sampler, 0); const GLvoid* p = &gDrawTextureVertices[0].position[0]; const GLvoid* t = &gDrawTextureVertices[0].texture[0]; glEnableVertexAttribArray(mDrawTextureShader->position); glVertexAttribPointer(mDrawTextureShader->position, 2, GL_FLOAT, GL_FALSE, gDrawTextureVertexStride, p); glEnableVertexAttribArray(mDrawTextureShader->texCoords); glVertexAttribPointer(mDrawTextureShader->texCoords, 2, GL_FLOAT, GL_FALSE, gDrawTextureVertexStride, t); glVertexAttrib4f(mDrawTextureShader->color, 1.0f, 1.0f, 1.0f, alpha); glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawTextureVertexCount); glDisableVertexAttribArray(mDrawTextureShader->position); glDisableVertexAttribArray(mDrawTextureShader->texCoords); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_BLEND); } }; // namespace uirenderer }; // namespace android Loading
core/java/android/view/GLES20Canvas.java +12 −8 Original line number Diff line number Diff line Loading @@ -278,30 +278,34 @@ class GLES20Canvas extends Canvas { @Override public int saveLayer(RectF bounds, Paint paint, int saveFlags) { // TODO: Implement return 0; return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags); } @Override public int saveLayer(float left, float top, float right, float bottom, Paint paint, int saveFlags) { // TODO: Implement return 0; int nativePaint = paint == null ? 0 : paint.mNativePaint; return nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags); } private native int nSaveLayer(int renderer, float left, float top, float right, float bottom, int paint, int saveFlags); @Override public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) { // TODO: Implement return 0; return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, alpha, saveFlags); } @Override public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, int saveFlags) { // TODO: Implement return 0; return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags); } private native int nSaveLayerAlpha(int renderer, float left, float top, float right, float bottom, int alpha, int saveFlags); @Override public void restore() { nRestore(mRenderer); Loading
core/jni/android_view_GLES20Canvas.cpp +43 −24 Original line number Diff line number Diff line Loading @@ -91,6 +91,22 @@ static void android_view_GLES20Renderer_restoreToCount(JNIEnv* env, jobject canv renderer->restoreToCount(saveCount); } // ---------------------------------------------------------------------------- // Layers // ---------------------------------------------------------------------------- static jint android_view_GLES20Renderer_saveLayer(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, SkPaint* paint, jint saveFlags) { return renderer->saveLayer(left, top, right, bottom, paint, saveFlags); } static jint android_view_GLES20Renderer_saveLayerAlpha(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, jint alpha, jint saveFlags) { return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags); } // ---------------------------------------------------------------------------- // Clipping // ---------------------------------------------------------------------------- Loading Loading @@ -188,6 +204,9 @@ static JNINativeMethod gMethods[] = { { "nRestoreToCount", "(II)V", (void*) android_view_GLES20Renderer_restoreToCount }, { "nGetSaveCount", "(I)I", (void*) android_view_GLES20Renderer_getSaveCount }, { "nSaveLayer", "(IFFFFII)I", (void*) android_view_GLES20Renderer_saveLayer }, { "nSaveLayerAlpha", "(IFFFFII)I", (void*) android_view_GLES20Renderer_saveLayerAlpha }, { "nQuickReject", "(IFFFFI)Z", (void*) android_view_GLES20Renderer_quickReject }, { "nClipRect", "(IFFFF)Z", (void*) android_view_GLES20Renderer_clipRectF }, { "nClipRect", "(IIIII)Z", (void*) android_view_GLES20Renderer_clipRect }, Loading
libs/hwui/Matrix.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,14 @@ void Matrix4::copyTo(float* v) const { memcpy(v, data, sizeof(data)); } float Matrix4::getTranslateX() { return data[12]; } float Matrix4::getTranslateY() { return data[13]; } void Matrix4::loadTranslate(float x, float y, float z) { loadIdentity(); data[12] = x; Loading
libs/hwui/Matrix.h +3 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,9 @@ public: void mapRect(Rect& r) const; float getTranslateX(); float getTranslateY(); void dump() const; private: Loading
libs/hwui/OpenGLRenderer.cpp +151 −10 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> #include <SkCanvas.h> #include <SkPaint.h> #include <SkXfermode.h> Loading @@ -40,21 +41,31 @@ namespace uirenderer { // Defines /////////////////////////////////////////////////////////////////////////////// #define V(x, y) { { x, y } } #define SV(x, y) { { x, y } } #define FV(x, y, u, v) { { x, y }, { u, v } } /////////////////////////////////////////////////////////////////////////////// // Globals /////////////////////////////////////////////////////////////////////////////// const SimpleVertex gDrawColorVertices[] = { V(0.0f, 0.0f), V(1.0f, 0.0f), V(0.0f, 1.0f), V(1.0f, 1.0f) SV(0.0f, 0.0f), SV(1.0f, 0.0f), SV(0.0f, 1.0f), SV(1.0f, 1.0f) }; const GLsizei gDrawColorVertexStride = sizeof(SimpleVertex); const GLsizei gDrawColorVertexCount = 4; const TextureVertex gDrawTextureVertices[] = { FV(0.0f, 0.0f, 0.0f, 1.0f), FV(1.0f, 0.0f, 1.0f, 1.0f), FV(0.0f, 1.0f, 0.0f, 0.0f), FV(1.0f, 1.0f, 1.0f, 0.0f) }; const GLsizei gDrawTextureVertexStride = sizeof(TextureVertex); const GLsizei gDrawTextureVertexCount = 4; /////////////////////////////////////////////////////////////////////////////// // Shaders /////////////////////////////////////////////////////////////////////////////// Loading @@ -64,6 +75,9 @@ const GLsizei gDrawColorVertexCount = 4; #include "shaders/drawColor.vert" #include "shaders/drawColor.frag" #include "shaders/drawTexture.vert" #include "shaders/drawTexture.frag" Program::Program(const char* vertex, const char* fragment) { vertexShader = buildShader(vertex, GL_VERTEX_SHADER); fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); Loading Loading @@ -139,6 +153,15 @@ GLuint Program::buildShader(const char* source, GLenum type) { DrawColorProgram::DrawColorProgram(): Program(gDrawColorVertexShader, gDrawColorFragmentShader) { getAttribsAndUniforms(); } DrawColorProgram::DrawColorProgram(const char* vertex, const char* fragment): Program(vertex, fragment) { getAttribsAndUniforms(); } void DrawColorProgram::getAttribsAndUniforms() { position = addAttrib("position"); color = addAttrib("color"); projection = addUniform("projection"); Loading @@ -154,6 +177,12 @@ void DrawColorProgram::use(const GLfloat* projectionMatrix, const GLfloat* model glUniformMatrix4fv(transform, 1, GL_FALSE, transformMatrix); } DrawTextureProgram::DrawTextureProgram(): DrawColorProgram(gDrawTextureVertexShader, gDrawTextureFragmentShader) { texCoords = addAttrib("texCoords"); sampler = addUniform("sampler"); } /////////////////////////////////////////////////////////////////////////////// // Support /////////////////////////////////////////////////////////////////////////////// Loading @@ -175,6 +204,7 @@ OpenGLRenderer::OpenGLRenderer() { LOGD("Create OpenGLRenderer"); mDrawColorShader = new DrawColorProgram; mDrawTextureShader = new DrawTextureProgram; } OpenGLRenderer::~OpenGLRenderer() { Loading Loading @@ -252,16 +282,89 @@ int OpenGLRenderer::saveSnapshot() { bool OpenGLRenderer::restoreSnapshot() { bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet; bool restoreLayer = mSnapshot->flags & Snapshot::kFlagIsLayer; mSaveCount--; // Do not merge these two lines! sp<Snapshot> current = mSnapshot; sp<Snapshot> previous = mSnapshot->previous; if (restoreLayer) { // Unbind current FBO and restore previous one // Most of the time, previous->fbo will be 0 to bind the default buffer glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo); const Rect& layer = current->layer; clipRect(layer.left, layer.top, layer.right, layer.bottom); mSnapshot->transform.loadIdentity(); drawTextureRect(0.0f, 0.0f, mWidth, mHeight, current->texture, current->alpha); glDeleteFramebuffers(1, ¤t->fbo); glDeleteTextures(1, ¤t->texture); } mSnapshot = previous; mSaveCount--; return restoreClip; } /////////////////////////////////////////////////////////////////////////////// // Layers /////////////////////////////////////////////////////////////////////////////// int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom, const SkPaint* p, int flags) { // TODO Implement return saveSnapshot(); } int OpenGLRenderer::saveLayerAlpha(float left, float top, float right, float bottom, int alpha, int flags) { int count = saveSnapshot(); mSnapshot->flags |= Snapshot::kFlagIsLayer; mSnapshot->alpha = alpha / 255.0f; mSnapshot->layer.set(left, top, right, bottom); // Generate the FBO and attach the texture glGenFramebuffers(1, &mSnapshot->fbo); glBindFramebuffer(GL_FRAMEBUFFER, mSnapshot->fbo); // Generate the texture in which the FBO will draw glGenTextures(1, &mSnapshot->texture); glBindTexture(GL_TEXTURE_2D, mSnapshot->texture); // The FBO will not be scaled, so we can use lower quality filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // TODO ***** IMPORTANT ***** // Creating a texture-backed FBO works only if the texture is the same size // as the original rendering buffer (in this case, mWidth and mHeight.) // This is expensive and wasteful and must be fixed. const GLsizei width = mWidth; //right - left; const GLsizei height = mHeight; //bottom - right; const GLint format = (flags & SkCanvas::kHasAlphaLayer_SaveFlag) ? GL_RGBA : GL_RGB; glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, 0); // Bind texture to FBO glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mSnapshot->texture, 0); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { LOGD("Framebuffer incomplete %d", status); glDeleteFramebuffers(1, &mSnapshot->fbo); glDeleteTextures(1, &mSnapshot->texture); } return count; } /////////////////////////////////////////////////////////////////////////////// // Transforms /////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -346,10 +449,10 @@ void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color); } void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* paint) { void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) { // TODO Support more than just color // TODO: Set the transfer mode drawColorRect(left, top, right, bottom, paint->getColor()); drawColorRect(left, top, right, bottom, p->getColor()); } void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, int color) { Loading @@ -375,5 +478,43 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot glDisableVertexAttribArray(mDrawColorShader->position); } void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, GLuint texture, float alpha) { mModelView.loadTranslate(left, top, 0.0f); mModelView.scale(right - left, bottom - top, 1.0f); mDrawTextureShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]); // TODO Correctly set the blend function glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glBindTexture(GL_TEXTURE_2D, texture); glActiveTexture(GL_TEXTURE0); glUniform1i(mDrawTextureShader->sampler, 0); const GLvoid* p = &gDrawTextureVertices[0].position[0]; const GLvoid* t = &gDrawTextureVertices[0].texture[0]; glEnableVertexAttribArray(mDrawTextureShader->position); glVertexAttribPointer(mDrawTextureShader->position, 2, GL_FLOAT, GL_FALSE, gDrawTextureVertexStride, p); glEnableVertexAttribArray(mDrawTextureShader->texCoords); glVertexAttribPointer(mDrawTextureShader->texCoords, 2, GL_FLOAT, GL_FALSE, gDrawTextureVertexStride, t); glVertexAttrib4f(mDrawTextureShader->color, 1.0f, 1.0f, 1.0f, alpha); glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawTextureVertexCount); glDisableVertexAttribArray(mDrawTextureShader->position); glDisableVertexAttribArray(mDrawTextureShader->texCoords); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_BLEND); } }; // namespace uirenderer }; // namespace android