Merge "Do not exit the GLSurfaceView thread when detached from a window."
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index a4def0b..e0094d8 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -43,7 +43,7 @@
     glBindBuffer(GL_ARRAY_BUFFER, meshBuffer);
     glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW);
 
-    currentBuffer = meshBuffer;
+    mCurrentBuffer = meshBuffer;
 }
 
 /**
@@ -57,9 +57,9 @@
  * Binds the specified VBO.
  */
 void Caches::bindMeshBuffer(const GLuint buffer) {
-    if (currentBuffer != buffer) {
+    if (mCurrentBuffer != buffer) {
         glBindBuffer(GL_ARRAY_BUFFER, buffer);
-        currentBuffer = buffer;
+        mCurrentBuffer = buffer;
     }
 }
 
@@ -67,9 +67,9 @@
  * Unbinds the VBO used to render simple textured quads.
  */
 void Caches::unbindMeshBuffer() {
-    if (currentBuffer) {
+    if (mCurrentBuffer) {
         glBindBuffer(GL_ARRAY_BUFFER, 0);
-        currentBuffer = 0;
+        mCurrentBuffer = 0;
     }
 }
 
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 79644a5..aff5366 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -79,7 +79,9 @@
 
     friend class Singleton<Caches>;
 
-    CacheLogger logger;
+    CacheLogger mlogger;
+
+    GLuint mCurrentBuffer;
 
 public:
     void bindMeshBuffer();
@@ -92,7 +94,6 @@
     Program* currentProgram;
 
     GLuint meshBuffer;
-    GLuint currentBuffer;
 
     TextureCache textureCache;
     LayerCache layerCache;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 7495a06..8592511 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -644,7 +644,7 @@
     }
 
     glActiveTexture(GL_TEXTURE0);
-    const Texture* texture = mCaches.textureCache.get(bitmap);
+    Texture* texture = mCaches.textureCache.get(bitmap);
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
 
@@ -661,7 +661,7 @@
     }
 
     glActiveTexture(GL_TEXTURE0);
-    const Texture* texture = mCaches.textureCache.get(bitmap);
+    Texture* texture = mCaches.textureCache.get(bitmap);
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
 
@@ -677,9 +677,10 @@
     }
 
     glActiveTexture(GL_TEXTURE0);
-    const Texture* texture = mCaches.textureCache.get(bitmap);
+    Texture* texture = mCaches.textureCache.get(bitmap);
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
+    setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
 
     const float width = texture->width;
     const float height = texture->height;
@@ -711,9 +712,10 @@
     }
 
     glActiveTexture(GL_TEXTURE0);
-    const Texture* texture = mCaches.textureCache.get(bitmap);
+    Texture* texture = mCaches.textureCache.get(bitmap);
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
+    setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
 
     int alpha;
     SkXfermode::Mode mode;
@@ -1046,7 +1048,7 @@
      // Build and use the appropriate shader
      useProgram(mCaches.programCache.get(description));
 
-     bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit);
+     bindTexture(texture, textureUnit);
      glUniform1i(mCaches.currentProgram->getUniform("sampler"), textureUnit);
 
      int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords");
@@ -1220,11 +1222,13 @@
 }
 
 void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
-        const Texture* texture, SkPaint* paint) {
+        Texture* texture, SkPaint* paint) {
     int alpha;
     SkXfermode::Mode mode;
     getAlphaAndMode(paint, &alpha, &mode);
 
+    setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+
     drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode,
             texture->blend, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset,
             GL_TRIANGLE_STRIP, gMeshCount);
@@ -1263,7 +1267,7 @@
     }
 
     // Texture
-    bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, 0);
+    bindTexture(texture);
     glUniform1i(mCaches.currentProgram->getUniform("sampler"), 0);
 
     // Always premultiplied
@@ -1380,11 +1384,29 @@
     return mode->fMode;
 }
 
-void OpenGLRenderer::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) {
+void OpenGLRenderer::bindTexture(GLuint texture, GLuint textureUnit) {
     glActiveTexture(gTextureUnits[textureUnit]);
     glBindTexture(GL_TEXTURE_2D, texture);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
+}
+
+void OpenGLRenderer::setTextureWrapModes(Texture* texture, GLenum wrapS, GLenum wrapT,
+        GLuint textureUnit) {
+    bool bound = false;
+    if (wrapS != texture->wrapS) {
+        glActiveTexture(gTextureUnits[textureUnit]);
+        glBindTexture(GL_TEXTURE_2D, texture->id);
+        bound = true;
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
+        texture->wrapS = wrapS;
+    }
+    if (wrapT != texture->wrapT) {
+        if (!bound) {
+            glActiveTexture(gTextureUnits[textureUnit]);
+            glBindTexture(GL_TEXTURE_2D, texture->id);
+        }
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
+        texture->wrapT = wrapT;
+    }
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index b7615fe..07188d4 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -231,7 +231,7 @@
      * @param paint The paint containing the alpha, blending mode, etc.
      */
     void drawTextureRect(float left, float top, float right, float bottom,
-            const Texture* texture, SkPaint* paint);
+            Texture* texture, SkPaint* paint);
 
     /**
      * Draws a textured mesh with the specified texture. If the indices are omitted,
@@ -360,9 +360,11 @@
     inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode);
 
     /**
-     * Binds the specified texture with the specified wrap modes.
+     * Binds the specified texture to the specified texture unit.
      */
-    inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit = 0);
+    inline void bindTexture(GLuint texture, GLuint textureUnit = 0);
+    inline void setTextureWrapModes(Texture* texture, GLenum wrapS, GLenum wrapT,
+            GLuint textureUnit = 0);
 
     /**
      * Enable or disable blending as necessary. This function sets the appropriate
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 253a19b..3d21431 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -26,8 +26,6 @@
 namespace android {
 namespace uirenderer {
 
-class Caches;
-
 ///////////////////////////////////////////////////////////////////////////////
 // Constructors/destructor
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index fa85d20..e7e1187 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -63,11 +63,17 @@
         GLuint* textureUnit) {
 }
 
-void SkiaShader::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) {
+void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) {
     glActiveTexture(gTextureUnitsMap[textureUnit]);
-    glBindTexture(GL_TEXTURE_2D, texture);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
+    glBindTexture(GL_TEXTURE_2D, texture->id);
+    if (wrapS != texture->wrapS) {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
+        texture->wrapS = wrapS;
+    }
+    if (wrapT != texture->wrapT) {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
+        texture->wrapT = wrapT;
+    }
 }
 
 void SkiaShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) {
@@ -86,7 +92,7 @@
 }
 
 void SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) {
-    const Texture* texture = mTextureCache->get(mBitmap);
+    Texture* texture = mTextureCache->get(mBitmap);
     if (!texture) return;
     mTexture = texture;
 
@@ -114,7 +120,7 @@
     GLuint textureSlot = (*textureUnit)++;
     glActiveTexture(gTextureUnitsMap[textureSlot]);
 
-    const Texture* texture = mTexture;
+    Texture* texture = mTexture;
     mTexture = NULL;
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
@@ -126,7 +132,7 @@
     computeScreenSpaceMatrix(textureTransform, modelView);
 
     // Uniforms
-    bindTexture(texture->id, mWrapS, mWrapT, textureSlot);
+    bindTexture(texture, mWrapS, mWrapT, textureSlot);
     glUniform1i(program->getUniform("bitmapSampler"), textureSlot);
     glUniformMatrix4fv(program->getUniform("textureTransform"), 1,
             GL_FALSE, &textureTransform.data[0]);
@@ -198,7 +204,7 @@
     computeScreenSpaceMatrix(screenSpace, modelView);
 
     // Uniforms
-    bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
+    bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
     glUniform1i(program->getUniform("gradientSampler"), textureSlot);
     glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
 }
@@ -291,7 +297,7 @@
     computeScreenSpaceMatrix(screenSpace, modelView);
 
     // Uniforms
-    bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
+    bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
     glUniform1i(program->getUniform("gradientSampler"), textureSlot);
     glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
 }
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index 011991a..4cd1b8b 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -97,7 +97,7 @@
     void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
 
 protected:
-    inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit);
+    inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit);
 
     Type mType;
     SkShader* mKey;
@@ -138,7 +138,7 @@
     }
 
     SkBitmap* mBitmap;
-    const Texture* mTexture;
+    Texture* mTexture;
     GLenum mWrapS;
     GLenum mWrapT;
 }; // struct SkiaBitmapShader
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 817f143..755074d 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -29,6 +29,8 @@
     Texture() {
         cleanup = false;
         bitmapSize = 0;
+        wrapS = GL_CLAMP_TO_EDGE;
+        wrapT = GL_CLAMP_TO_EDGE;
     }
 
     /**
@@ -59,6 +61,12 @@
      * Optional, size of the original bitmap.
      */
     uint32_t bitmapSize;
+
+    /**
+     * Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE.
+     */
+    GLenum wrapS;
+    GLenum wrapT;
 }; // struct Texture
 
 class AutoTexture {
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 629234b..4c86ebe 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -1163,7 +1163,10 @@
 
         // If the pointer is not currently down, then ignore the event.
         if (! mTempTouchState.down) {
-            LOGI("Dropping event because the pointer is not down.");
+#if DEBUG_INPUT_DISPATCHER_POLICY
+            LOGD("Dropping event because the pointer is not down or we previously "
+                    "dropped the pointer down event.");
+#endif
             injectionResult = INPUT_EVENT_INJECTION_FAILED;
             goto Failed;
         }
@@ -2775,7 +2778,7 @@
         dump.append(INDENT "ActiveConnections:\n");
         for (size_t i = 0; i < mActiveConnections.size(); i++) {
             const Connection* connection = mActiveConnections[i];
-            dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
+            dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
                     "inputState.isNeutral=%s\n",
                     i, connection->getInputChannelName(), connection->getStatusLabel(),
                     connection->outboundQueue.count(),
diff --git a/media/java/android/media/videoeditor/VideoEditorTestImpl.java b/media/java/android/media/videoeditor/VideoEditorTestImpl.java
index f4842b5..505b93e 100644
--- a/media/java/android/media/videoeditor/VideoEditorTestImpl.java
+++ b/media/java/android/media/videoeditor/VideoEditorTestImpl.java
@@ -1155,12 +1155,18 @@
     private void removeAdjacentTransitions(MediaItem mediaItem) {
         final Transition beginTransition = mediaItem.getBeginTransition();
         if (beginTransition != null) {
+            if (beginTransition.getAfterMediaItem() != null) {
+                beginTransition.getAfterMediaItem().setEndTransition(null);
+            }
             beginTransition.invalidate();
             mTransitions.remove(beginTransition);
         }
 
         final Transition endTransition = mediaItem.getEndTransition();
         if (endTransition != null) {
+            if (endTransition.getBeforeMediaItem() != null) {
+                endTransition.getBeforeMediaItem().setBeginTransition(null);
+            }
             endTransition.invalidate();
             mTransitions.remove(endTransition);
         }
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java
index 2db1071..02eaa7c 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java
@@ -51,27 +51,28 @@
         private LinearGradient mHorGradient;
         private LinearGradient mDiagGradient;
         private LinearGradient mVertGradient;
+        private Bitmap mTexture;
 
         ShadersView(Context c) {
             super(c);
 
-            Bitmap texture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
-            mTexWidth = texture.getWidth();
-            mTexHeight = texture.getHeight();
+            mTexture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
+            mTexWidth = mTexture.getWidth();
+            mTexHeight = mTexture.getHeight();
             mDrawWidth = mTexWidth * 2.2f;
             mDrawHeight = mTexHeight * 1.2f;
 
-            mRepeatShader = new BitmapShader(texture, Shader.TileMode.REPEAT,
+            mRepeatShader = new BitmapShader(mTexture, Shader.TileMode.REPEAT,
                     Shader.TileMode.REPEAT);
 
-            mTranslatedShader = new BitmapShader(texture, Shader.TileMode.REPEAT,
+            mTranslatedShader = new BitmapShader(mTexture, Shader.TileMode.REPEAT,
                     Shader.TileMode.REPEAT);
             Matrix m1 = new Matrix();
             m1.setTranslate(mTexWidth / 2.0f, mTexHeight / 2.0f);
             m1.postRotate(45, 0, 0);
             mTranslatedShader.setLocalMatrix(m1);
             
-            mScaledShader = new BitmapShader(texture, Shader.TileMode.MIRROR,
+            mScaledShader = new BitmapShader(mTexture, Shader.TileMode.MIRROR,
                     Shader.TileMode.MIRROR);
             Matrix m2 = new Matrix();
             m2.setScale(0.5f, 0.5f);
@@ -98,6 +99,7 @@
         protected void onDraw(Canvas canvas) {
             super.onDraw(canvas);
             //canvas.drawRGB(255, 255, 255);
+            canvas.drawBitmap(mTexture, 0.0f, 0.0f, null);
 
             // Bitmap shaders
             canvas.save();