diff options
author | Romain Guy <romainguy@google.com> | 2010-09-10 19:20:06 -0700 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2010-09-12 12:24:12 -0700 |
commit | f607bdc167f66b3e7003acaa4736ae46d78c1492 (patch) | |
tree | b3b4fb761b25d08ba836ff822f6e72d85b5be695 /libs | |
parent | d14f0dfd58af653a2d41424d472fe97de6af0a78 (diff) | |
download | frameworks_base-f607bdc167f66b3e7003acaa4736ae46d78c1492.zip frameworks_base-f607bdc167f66b3e7003acaa4736ae46d78c1492.tar.gz frameworks_base-f607bdc167f66b3e7003acaa4736ae46d78c1492.tar.bz2 |
Correct implementation of saveLayer().
Change-Id: I5375126636913e0a84f2d6bbd0ebe40d2e4f2763
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/Layer.h | 13 | ||||
-rw-r--r-- | libs/hwui/LayerCache.cpp | 24 | ||||
-rw-r--r-- | libs/hwui/LayerCache.h | 4 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 148 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 16 | ||||
-rw-r--r-- | libs/hwui/ProgramCache.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/ProgramCache.h | 13 | ||||
-rw-r--r-- | libs/hwui/Snapshot.h | 69 |
8 files changed, 131 insertions, 161 deletions
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index d4db782..c527038 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -63,28 +63,19 @@ struct LayerSize { */ struct Layer { /** - * Coordinates of the layer corresponding to this snapshot. - * Only set when the flag kFlagIsLayer is set. + * Coordinates of the layer. */ Rect layer; /** * Name of the texture used to render the layer. - * Only set when the flag kFlagIsLayer is set. */ GLuint texture; /** - * Name of the FBO used to render the layer. - * Only set when the flag kFlagIsLayer is set. - */ - GLuint fbo; - /** * Opacity of the layer. - * Only set when the flag kFlagIsLayer is set. */ - float alpha; + int alpha; /** * Blending mode of the layer. - * Only set when the flag kFlagIsLayer is set. */ SkXfermode::Mode mode; /** diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp index a204778..1a18766 100644 --- a/libs/hwui/LayerCache.cpp +++ b/libs/hwui/LayerCache.cpp @@ -87,7 +87,6 @@ void LayerCache::deleteLayer(Layer* layer) { if (layer) { mSize -= layer->layer.getWidth() * layer->layer.getHeight() * 4; - glDeleteFramebuffers(1, &layer->fbo); glDeleteTextures(1, &layer->texture); delete layer; } @@ -99,7 +98,7 @@ void LayerCache::clear() { mCache.setOnEntryRemovedListener(NULL); } -Layer* LayerCache::get(LayerSize& size, GLuint previousFbo) { +Layer* LayerCache::get(LayerSize& size) { Layer* layer = mCache.remove(size); if (layer) { LAYER_LOGD("Reusing layer"); @@ -111,10 +110,6 @@ Layer* LayerCache::get(LayerSize& size, GLuint previousFbo) { layer = new Layer; layer->blend = true; - // Generate the FBO and attach the texture - glGenFramebuffers(1, &layer->fbo); - glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo); - // Generate the texture in which the FBO will draw glGenTextures(1, &layer->texture); glBindTexture(GL_TEXTURE_2D, layer->texture); @@ -128,23 +123,6 @@ Layer* LayerCache::get(LayerSize& size, GLuint previousFbo) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width, size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - - // Bind texture to FBO - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - layer->texture, 0); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - LOGE("Framebuffer incomplete (GL error code 0x%x)", status); - - glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); - - glDeleteFramebuffers(1, &layer->fbo); - glDeleteTextures(1, &layer->texture); - delete layer; - - return NULL; - } } return layer; diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h index 9860994..c0c7542 100644 --- a/libs/hwui/LayerCache.h +++ b/libs/hwui/LayerCache.h @@ -62,10 +62,8 @@ public: * size of the cache goes down. * * @param size The dimensions of the desired layer - * @param previousFbo The name of the FBO to bind to if creating a new - * layer fails */ - Layer* get(LayerSize& size, GLuint previousFbo); + Layer* get(LayerSize& size); /** * Adds the layer to the cache. The layer will not be added if there is * not enough space available. diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 6c90704..7cf70f7 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -80,6 +80,21 @@ static const Blender gBlends[] = { { SkXfermode::kXor_Mode, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA } }; +static const Blender gBlendsSwap[] = { + { SkXfermode::kClear_Mode, GL_ZERO, GL_ZERO }, + { SkXfermode::kSrc_Mode, GL_ZERO, GL_ONE }, + { SkXfermode::kDst_Mode, GL_ONE, GL_ZERO }, + { SkXfermode::kSrcOver_Mode, GL_ONE_MINUS_DST_ALPHA, GL_ONE }, + { SkXfermode::kDstOver_Mode, GL_ONE, GL_ONE_MINUS_SRC_ALPHA }, + { SkXfermode::kSrcIn_Mode, GL_ZERO, GL_SRC_ALPHA }, + { SkXfermode::kDstIn_Mode, GL_DST_ALPHA, GL_ZERO }, + { SkXfermode::kSrcOut_Mode, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA }, + { SkXfermode::kDstOut_Mode, GL_ONE_MINUS_DST_ALPHA, GL_ZERO }, + { SkXfermode::kSrcATop_Mode, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA }, + { SkXfermode::kDstATop_Mode, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, + { SkXfermode::kXor_Mode, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA } +}; + static const GLenum gTextureUnits[] = { GL_TEXTURE0, GL_TEXTURE1, @@ -122,8 +137,6 @@ void OpenGLRenderer::setViewport(int width, int height) { mWidth = width; mHeight = height; - mFirstSnapshot->height = height; - mFirstSnapshot->viewport.set(0, 0, width, height); } void OpenGLRenderer::prepare() { @@ -155,14 +168,19 @@ void OpenGLRenderer::acquireContext() { } void OpenGLRenderer::releaseContext() { - glViewport(0, 0, mSnapshot->viewport.getWidth(), mSnapshot->viewport.getHeight()); + glViewport(0, 0, mWidth, mHeight); glEnable(GL_SCISSOR_TEST); setScissorFromClip(); + glDisable(GL_DITHER); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + if (mCaches.blend) { glEnable(GL_BLEND); glBlendFunc(mCaches.lastSrcMode, mCaches.lastDstMode); + glBlendEquation(GL_FUNC_ADD); } else { glDisable(GL_BLEND); } @@ -202,17 +220,10 @@ int OpenGLRenderer::saveSnapshot(int flags) { bool OpenGLRenderer::restoreSnapshot() { bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet; bool restoreLayer = mSnapshot->flags & Snapshot::kFlagIsLayer; - bool restoreOrtho = mSnapshot->flags & Snapshot::kFlagDirtyOrtho; sp<Snapshot> current = mSnapshot; sp<Snapshot> previous = mSnapshot->previous; - if (restoreOrtho) { - Rect& r = previous->viewport; - glViewport(r.left, r.top, r.right, r.bottom); - mOrthoMatrix.load(current->orthoMatrix); - } - mSaveCount--; mSnapshot = previous; @@ -253,11 +264,7 @@ int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom, mode = SkXfermode::kSrcOver_Mode; } - if (alpha > 0 && !mSnapshot->invisible) { - createLayer(mSnapshot, left, top, right, bottom, alpha, mode, flags); - } else { - mSnapshot->invisible = true; - } + createLayer(mSnapshot, left, top, right, bottom, alpha, mode, flags); return count; } @@ -278,48 +285,41 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top, LAYER_LOGD("Requesting layer %fx%f", right - left, bottom - top); LAYER_LOGD("Layer cache size = %d", mCaches.layerCache.getSize()); + // Window coordinates of the layer Rect bounds(left, top, right, bottom); - // TODO: Apply transformations and treat layers in screen coordinates - // mSnapshot->transform->mapRect(bounds); + mSnapshot->transform->mapRect(bounds); - GLuint previousFbo = snapshot->previous.get() ? snapshot->previous->fbo : 0; LayerSize size(bounds.getWidth(), bounds.getHeight()); - Layer* layer = mCaches.layerCache.get(size, previousFbo); + Layer* layer = mCaches.layerCache.get(size); if (!layer) { return false; } - glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo); - - // Clear the FBO - glDisable(GL_SCISSOR_TEST); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_SCISSOR_TEST); - layer->mode = mode; - layer->alpha = alpha / 255.0f; + layer->alpha = alpha; layer->layer.set(bounds); // Save the layer in the snapshot snapshot->flags |= Snapshot::kFlagIsLayer; snapshot->layer = layer; - snapshot->fbo = layer->fbo; - // TODO: Temporary until real layer support is implemented - snapshot->resetTransform(-bounds.left, -bounds.top, 0.0f); - // TODO: Temporary until real layer support is implemented - snapshot->resetClip(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight()); - snapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight()); - snapshot->height = bounds.getHeight(); - snapshot->flags |= Snapshot::kFlagDirtyOrtho; - snapshot->orthoMatrix.load(mOrthoMatrix); - setScissorFromClip(); + // Copy the framebuffer into the layer + glBindTexture(GL_TEXTURE_2D, layer->texture); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left, mHeight - bounds.bottom, + bounds.getWidth(), bounds.getHeight(), 0); + + // Clear the framebuffer where the layer will draw + glScissor(bounds.left, mHeight - bounds.bottom, bounds.getWidth(), bounds.getHeight()); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); - // Change the ortho projection - glViewport(0, 0, bounds.getWidth(), bounds.getHeight()); - mOrthoMatrix.loadOrtho(0.0f, bounds.getWidth(), bounds.getHeight(), 0.0f, -1.0f, 1.0f); + if (flags & SkCanvas::kClipToLayer_SaveFlag) { + mSnapshot->clipTransformed(bounds); + } + + // Restore the initial clip + setScissorFromClip(); return true; } @@ -330,22 +330,32 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { return; } - // 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); - // Restore the clip from the previous snapshot const Rect& clip = *previous->clipRect; - glScissor(clip.left, previous->height - clip.bottom, clip.getWidth(), clip.getHeight()); + glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight()); Layer* layer = current->layer; const Rect& rect = layer->layer; - // FBOs are already drawn with a top-left origin, don't flip the texture + if (layer->alpha < 255) { + glEnable(GL_BLEND); + glBlendFuncSeparate(GL_ZERO, GL_SRC_ALPHA, GL_DST_ALPHA, GL_ZERO); + + drawColorRect(rect.left, rect.top, rect.right, rect.bottom, + layer->alpha << 24, SkXfermode::kSrcOver_Mode, true, true); + + glBlendFunc(mCaches.lastSrcMode, mCaches.lastDstMode); + if (!mCaches.blend) { + glDisable(GL_BLEND); + } + } + + // Layers are already drawn with a top-left origin, don't flip the texture resetDrawTextureTexCoords(0.0f, 1.0f, 1.0f, 0.0f); - drawTextureRect(rect.left, rect.top, rect.right, rect.bottom, - layer->texture, layer->alpha, layer->mode, layer->blend); + drawTextureMesh(rect.left, rect.top, rect.right, rect.bottom, layer->texture, + 1.0f, layer->mode, layer->blend, &mMeshVertices[0].position[0], + &mMeshVertices[0].texture[0], NULL, 0, true, true); resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); @@ -355,7 +365,6 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { if (!mCaches.layerCache.put(size, layer)) { LAYER_LOGD("Deleting layer"); - glDeleteFramebuffers(1, &layer->fbo); glDeleteTextures(1, &layer->texture); delete layer; @@ -397,7 +406,7 @@ void OpenGLRenderer::concatMatrix(SkMatrix* matrix) { void OpenGLRenderer::setScissorFromClip() { const Rect& clip = *mSnapshot->clipRect; - glScissor(clip.left, mSnapshot->height - clip.bottom, clip.getWidth(), clip.getHeight()); + glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight()); } const Rect& OpenGLRenderer::getClipBounds() { @@ -405,8 +414,6 @@ const Rect& OpenGLRenderer::getClipBounds() { } bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) { - if (mSnapshot->invisible) return true; - Rect r(left, top, right, bottom); mSnapshot->transform->mapRect(r); return !mSnapshot->clipRect->intersects(r); @@ -512,7 +519,6 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch, } void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { - if (mSnapshot->invisible) return; const Rect& clip = *mSnapshot->clipRect; drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true); } @@ -545,10 +551,10 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint) { - if (mSnapshot->invisible || text == NULL || count == 0 || - (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) { + if (text == NULL || count == 0 || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) { return; } + paint->setAntiAlias(true); float scaleX = paint->getTextScaleX(); bool applyScaleX = scaleX < 0.9999f || scaleX > 1.0001f; @@ -619,8 +625,6 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, } void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { - if (mSnapshot->invisible) return; - GLuint textureUnit = 0; glActiveTexture(gTextureUnits[textureUnit]); @@ -778,6 +782,7 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t } } +// Same values used by Skia #define kStdStrikeThru_Offset (-6.0f / 21.0f) #define kStdUnderline_Offset (1.0f / 9.0f) #define kStdUnderline_Thickness (1.0f / 18.0f) @@ -830,7 +835,7 @@ void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float } void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, - int color, SkXfermode::Mode mode, bool ignoreTransform) { + int color, SkXfermode::Mode mode, bool ignoreTransform, bool ignoreBlending) { // If a shader is set, preserve only the alpha if (mShader) { color |= 0x00ffffff; @@ -854,8 +859,10 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot mColorFilter->describe(description, mExtensions); } - // Setup the blending mode - chooseBlending(alpha < 255 || (mShader && mShader->blend()), mode, description); + if (!ignoreBlending) { + // Setup the blending mode + chooseBlending(alpha < 255 || (mShader && mShader->blend()), mode, description); + } // Build and use the appropriate shader useProgram(mCaches.programCache.get(description)); @@ -905,7 +912,8 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float bottom, GLuint texture, float alpha, SkXfermode::Mode mode, bool blend, - GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount) { + GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount, + bool swapSrcDst, bool ignoreTransform) { ProgramDescription description; description.hasTexture = true; if (mColorFilter) { @@ -915,10 +923,15 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b mModelView.loadTranslate(left, top, 0.0f); mModelView.scale(right - left, bottom - top, 1.0f); - chooseBlending(blend || alpha < 1.0f, mode, description); + chooseBlending(blend || alpha < 1.0f, mode, description, swapSrcDst); useProgram(mCaches.programCache.get(description)); - mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform); + if (!ignoreTransform) { + mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform); + } else { + mat4 m; + mCaches.currentProgram->set(mOrthoMatrix, mModelView, m); + } // Texture bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, 0); @@ -948,7 +961,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b } void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, - ProgramDescription& description) { + ProgramDescription& description, bool swapSrcDst) { blend = blend || mode != SkXfermode::kSrcOver_Mode; if (blend) { if (mode < SkXfermode::kPlus_Mode) { @@ -956,8 +969,8 @@ void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, glEnable(GL_BLEND); } - GLenum sourceMode = gBlends[mode].src; - GLenum destMode = gBlends[mode].dst; + GLenum sourceMode = swapSrcDst ? gBlendsSwap[mode].src : gBlends[mode].src; + GLenum destMode = swapSrcDst ? gBlendsSwap[mode].dst : gBlends[mode].dst; if (sourceMode != mCaches.lastSrcMode || destMode != mCaches.lastDstMode) { glBlendFunc(sourceMode, destMode); @@ -970,6 +983,7 @@ void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, // the blending, turn blending off here if (mExtensions.hasFramebufferFetch()) { description.framebufferMode = mode; + description.swapSrcDst = swapSrcDst; } if (mCaches.blend) { diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 50f42c2..e7f933f 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -166,9 +166,11 @@ private: * @param color The rectangle's ARGB color, defined as a packed 32 bits word * @param mode The Skia xfermode to use * @param ignoreTransform True if the current transform should be ignored + * @paran ignoreBlending True if the blending is set by the caller */ void drawColorRect(float left, float top, float right, float bottom, - int color, SkXfermode::Mode mode, bool ignoreTransform = false); + int color, SkXfermode::Mode mode, bool ignoreTransform = false, + bool ignoreBlending = false); /** * Draws a textured rectangle with the specified texture. The specified coordinates @@ -216,10 +218,13 @@ private: * @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 */ void drawTextureMesh(float left, float top, float right, float bottom, GLuint texture, float alpha, SkXfermode::Mode mode, bool blend, - GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount = 0); + GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount = 0, + bool swapSrcDst = false, bool ignoreTransform = false); /** * Prepares the renderer to draw the specified shadow. @@ -322,8 +327,13 @@ private: * Enable or disable blending as necessary. This function sets the appropriate * blend function based on the specified xfermode. */ - inline void chooseBlending(bool blend, SkXfermode::Mode mode, ProgramDescription& description); + inline void chooseBlending(bool blend, SkXfermode::Mode mode, ProgramDescription& description, + bool swapSrcDst = false); + /** + * Safely retrieves the mode from the specified xfermode. If the specified + * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode. + */ inline SkXfermode::Mode getXfermode(SkXfermode* mode); /** diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index ff65c1b..becbc22 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -119,6 +119,8 @@ const char* gFS_Main_FragColor = " gl_FragColor = fragColor;\n"; const char* gFS_Main_FragColor_Blend = " gl_FragColor = blendFramebuffer(fragColor, gl_LastFragColor);\n"; +const char* gFS_Main_FragColor_Blend_Swap = + " gl_FragColor = blendFramebuffer(gl_LastFragColor, fragColor);\n"; const char* gFS_Main_ApplyColorOp[4] = { // None "", @@ -376,7 +378,8 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti if (!blendFramebuffer) { shader.append(gFS_Main_FragColor); } else { - shader.append(gFS_Main_FragColor_Blend); + shader.append(!description.swapSrcDst ? + gFS_Main_FragColor_Blend : gFS_Main_FragColor_Blend_Swap); } } // End the shader diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h index 8f5304d..0a17052 100644 --- a/libs/hwui/ProgramCache.h +++ b/libs/hwui/ProgramCache.h @@ -35,7 +35,7 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// // Debug -#define DEBUG_PROGRAM_CACHE 1 +#define DEBUG_PROGRAM_CACHE 0 // Debug #if DEBUG_PROGRAM_CACHE @@ -44,6 +44,9 @@ namespace uirenderer { #define PROGRAM_LOGD(...) #endif +/* + * IMPORTANT: All 32 bits are used, switch to a long. + */ #define PROGRAM_KEY_TEXTURE 0x1 #define PROGRAM_KEY_A8_TEXTURE 0x2 #define PROGRAM_KEY_BITMAP 0x4 @@ -53,6 +56,7 @@ namespace uirenderer { #define PROGRAM_KEY_COLOR_LIGHTING 0x40 #define PROGRAM_KEY_COLOR_BLEND 0x80 #define PROGRAM_KEY_BITMAP_NPOT 0x100 +#define PROGRAM_KEY_SWAP_SRC_DST 0x2000 #define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600 #define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800 @@ -70,6 +74,9 @@ namespace uirenderer { // Types /////////////////////////////////////////////////////////////////////////////// +/* + * IMPORTANT: All 32 bits are used, switch to a long. + */ typedef uint32_t programid; /////////////////////////////////////////////////////////////////////////////// @@ -95,7 +102,7 @@ struct ProgramDescription { shadersMode(SkXfermode::kClear_Mode), isBitmapFirst(false), bitmapWrapS(GL_CLAMP_TO_EDGE), bitmapWrapT(GL_CLAMP_TO_EDGE), colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode), - framebufferMode(SkXfermode::kClear_Mode) { + framebufferMode(SkXfermode::kClear_Mode), swapSrcDst(false) { } // Texturing @@ -118,6 +125,7 @@ struct ProgramDescription { // Framebuffer blending (requires Extensions.hasFramebufferFetch()) // Ignored for all values < SkXfermode::kPlus_Mode SkXfermode::Mode framebufferMode; + bool swapSrcDst; inline uint32_t getEnumForWrap(GLenum wrap) const { switch (wrap) { @@ -163,6 +171,7 @@ struct ProgramDescription { break; } key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT; + if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST; return key; } }; // struct ProgramDescription diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h index da48243..ebedf53 100644 --- a/libs/hwui/Snapshot.h +++ b/libs/hwui/Snapshot.h @@ -43,7 +43,7 @@ namespace uirenderer { */ class Snapshot: public LightRefBase<Snapshot> { public: - Snapshot(): invisible(false), flags(0), previous(NULL), layer(NULL), fbo(0) { + Snapshot(): flags(0), previous(NULL), layer(NULL) { transform = &mTransformRoot; clipRect = &mClipRectRoot; } @@ -53,13 +53,7 @@ public: * the previous snapshot. */ Snapshot(const sp<Snapshot>& s, int saveFlags): - height(s->height), - invisible(s->invisible), - flags(0), - previous(s), - layer(NULL), - fbo(s->fbo), - viewport(s->viewport) { + flags(0), previous(s), layer(NULL) { if (saveFlags & SkCanvas::kMatrix_SaveFlag) { mTransformRoot.load(*s->transform); transform = &mTransformRoot; @@ -97,23 +91,30 @@ public: */ kFlagIsLayer = 0x2, /** - * Indicates that this snapshot has changed the ortho matrix. - */ - kFlagDirtyOrtho = 0x4, - /** * Indicates that the local clip should be recomputed. */ - kFlagDirtyLocalClip = 0x8, + kFlagDirtyLocalClip = 0x4, }; /** - * Intersects the current clip with the new clip rectangle. + * Modifies the current clip with the new clip rectangle and + * the specified operation. The specified rectangle is transformed + * by this snapshot's trasnformation. */ - bool clip(float left, float top, float right, float bottom, SkRegion::Op op) { - bool clipped = false; - + bool clip(float left, float top, float right, float bottom, + SkRegion::Op op = SkRegion::kIntersect_Op) { Rect r(left, top, right, bottom); transform->mapRect(r); + return clipTransformed(r, op); + } + + /** + * Modifies the current clip with the new clip rectangle and + * the specified operation. The specified rectangle is considered + * already transformed. + */ + bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op) { + bool clipped = false; switch (op) { case SkRegion::kDifference_Op: @@ -162,29 +163,6 @@ public: return mLocalClip; } - // TODO: Temporary - void resetTransform(float x, float y, float z) { - transform = &mTransformRoot; - transform->loadTranslate(x, y, z); - } - - // TODO: Temporary - void resetClip(float left, float top, float right, float bottom) { - clipRect = &mClipRectRoot; - clipRect->set(left, top, right, bottom); - flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; - } - - /** - * Height of the framebuffer the snapshot is rendering into. - */ - int height; - - /** - * If true, the layer won't be rendered. - */ - bool invisible; - /** * Dirty flags. */ @@ -199,17 +177,6 @@ public: * Only set when the flag kFlagIsLayer is set. */ Layer* layer; - GLuint fbo; - - /** - * Current viewport. - */ - Rect viewport; - - /** - * Contains the previous ortho matrix. - */ - mat4 orthoMatrix; /** * Local transformation. Holds the current translation, scale and |