resolved conflicts for merge of d67bb501 to master

Change-Id: I40698ce1e382cb41eec7af5ea49ac0e2f997d555
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index fa7635e..fb5147b 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -37,39 +37,37 @@
     ATRACE_NAME("AssetAtlas::init");
 
     mImage = new Image(buffer);
-
     if (mImage->getTexture()) {
-        Caches& caches = Caches::getInstance();
-
-        mTexture = new Texture(caches);
-        mTexture->id = mImage->getTexture();
-        mTexture->width = buffer->getWidth();
-        mTexture->height = buffer->getHeight();
-
-        createEntries(caches, map, count);
+        if (!mTexture) {
+            Caches& caches = Caches::getInstance();
+            mTexture = new Texture(caches);
+            mTexture->width = buffer->getWidth();
+            mTexture->height = buffer->getHeight();
+            createEntries(caches, map, count);
+        }
     } else {
         ALOGW("Could not create atlas image");
-
         delete mImage;
         mImage = NULL;
-        mTexture = NULL;
     }
 
-    mGenerationId++;
+    updateTextureId();
 }
 
 void AssetAtlas::terminate() {
     if (mImage) {
         delete mImage;
         mImage = NULL;
+        updateTextureId();
+    }
+}
 
-        delete mTexture;
-        mTexture = NULL;
 
-        for (size_t i = 0; i < mEntries.size(); i++) {
-            delete mEntries.valueAt(i);
-        }
-        mEntries.clear();
+void AssetAtlas::updateTextureId() {
+    mTexture->id = mImage ? mImage->getTexture() : 0;
+    for (size_t i = 0; i < mEntries.size(); i++) {
+        AssetAtlas::Entry* entry = mEntries.valueAt(i);
+        entry->texture->id = mTexture->id;
     }
 }
 
@@ -134,7 +132,6 @@
                 y / height, (y + bitmap->height()) / height);
 
         Texture* texture = new DelegateTexture(caches, mTexture);
-        texture->id = mTexture->id;
         texture->blend = !bitmap->isOpaque();
         texture->width = bitmap->width();
         texture->height = bitmap->height();
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 6f72793..dba9e62 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -106,7 +106,7 @@
         friend class AssetAtlas;
     };
 
-    AssetAtlas(): mTexture(NULL), mImage(NULL), mGenerationId(0),
+    AssetAtlas(): mTexture(NULL), mImage(NULL),
             mBlendKey(true), mOpaqueKey(false) { }
     ~AssetAtlas() { terminate(); }
 
@@ -130,7 +130,7 @@
      * After calling this method, the width, height
      * and texture are set to 0.
      */
-    ANDROID_API void terminate();
+    void terminate();
 
     /**
      * Returns the width of this atlas in pixels.
@@ -168,21 +168,13 @@
      */
     Texture* getEntryTexture(const SkBitmap* bitmap) const;
 
-    /**
-     * Returns the current generation id of the atlas.
-     */
-    uint32_t getGenerationId() const {
-        return mGenerationId;
-    }
-
 private:
     void createEntries(Caches& caches, int64_t* map, int count);
+    void updateTextureId();
 
     Texture* mTexture;
     Image* mImage;
 
-    uint32_t mGenerationId;
-
     const bool mBlendKey;
     const bool mOpaqueKey;
 
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 8727154..674102b 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -238,8 +238,6 @@
     programCache.clear();
     currentProgram = NULL;
 
-    assetAtlas.terminate();
-
     patchCache.clear();
 
     clearGarbage();
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 4b8b626..fef01fa 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -350,8 +350,6 @@
     Dither dither;
     Stencil stencil;
 
-    AssetAtlas assetAtlas;
-
     bool gpuPixelBuffersEnabled;
 
     // Debug methods
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 8e341d9..e4e5dfa 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -35,6 +35,7 @@
 #include "GammaFontRenderer.h"
 #include "Patch.h"
 #include "RenderNode.h"
+#include "RenderState.h"
 #include "UvMapper.h"
 #include "utils/LinearAllocator.h"
 
@@ -611,24 +612,17 @@
     DrawBitmapOp(const SkBitmap* bitmap, const SkPaint* paint)
             : DrawBoundedOp(0, 0, bitmap->width(), bitmap->height(), paint)
             , mBitmap(bitmap)
-            , mAtlas(Caches::getInstance().assetAtlas) {
-        mEntry = mAtlas.getEntry(bitmap);
-        if (mEntry) {
-            mEntryGenerationId = mAtlas.getGenerationId();
-            mUvMapper = mEntry->uvMapper;
-        }
+            , mEntryValid(false), mEntry(NULL) {
     }
 
     virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
         renderer.drawBitmap(mBitmap, mPaint);
     }
 
-    AssetAtlas::Entry* getAtlasEntry() {
-        // The atlas entry is stale, let's get a new one
-        if (mEntry && mEntryGenerationId != mAtlas.getGenerationId()) {
-            mEntryGenerationId = mAtlas.getGenerationId();
-            mEntry = mAtlas.getEntry(mBitmap);
-            mUvMapper = mEntry->uvMapper;
+    AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) {
+        if (!mEntryValid) {
+            mEntryValid = true;
+            mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap);
         }
         return mEntry;
     }
@@ -664,7 +658,7 @@
             pureTranslate &= state.mMatrix.isPureTranslate();
 
             Rect texCoords(0, 0, 1, 1);
-            ((DrawBitmapOp*) ops[i].op)->mUvMapper.map(texCoords);
+            ((DrawBitmapOp*) ops[i].op)->uvMap(renderer, texCoords);
 
             SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, top);
             SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top);
@@ -693,7 +687,7 @@
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
         deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
-        deferInfo.mergeId = getAtlasEntry() ?
+        deferInfo.mergeId = getAtlasEntry(renderer) ?
                 (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
 
         // Don't merge non-simply transformed or neg scale ops, SET_TEXTURE doesn't handle rotation
@@ -706,13 +700,17 @@
                 (mBitmap->colorType() != kAlpha_8_SkColorType);
     }
 
+    void uvMap(OpenGLRenderer& renderer, Rect& texCoords) {
+        if (getAtlasEntry(renderer)) {
+            mEntry->uvMapper.map(texCoords);
+        }
+    }
+
     const SkBitmap* bitmap() { return mBitmap; }
 protected:
     const SkBitmap* mBitmap;
-    const AssetAtlas& mAtlas;
-    uint32_t mEntryGenerationId;
+    bool mEntryValid;
     AssetAtlas::Entry* mEntry;
-    UvMapper mUvMapper;
 };
 
 class DrawBitmapRectOp : public DrawBoundedOp {
@@ -805,18 +803,13 @@
             float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawBoundedOp(left, top, right, bottom, paint),
             mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(NULL),
-            mAtlas(Caches::getInstance().assetAtlas) {
-        mEntry = mAtlas.getEntry(bitmap);
-        if (mEntry) {
-            mEntryGenerationId = mAtlas.getGenerationId();
-        }
+            mEntryValid(false), mEntry(NULL) {
     };
 
-    AssetAtlas::Entry* getAtlasEntry() {
-        // The atlas entry is stale, let's get a new one
-        if (mEntry && mEntryGenerationId != mAtlas.getGenerationId()) {
-            mEntryGenerationId = mAtlas.getGenerationId();
-            mEntry = mAtlas.getEntry(mBitmap);
+    AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) {
+        if (!mEntryValid) {
+            mEntryValid = true;
+            mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap);
         }
         return mEntry;
     }
@@ -824,7 +817,7 @@
     const Patch* getMesh(OpenGLRenderer& renderer) {
         if (!mMesh || renderer.getCaches().patchCache.getGenerationId() != mGenerationId) {
             PatchCache& cache = renderer.getCaches().patchCache;
-            mMesh = cache.get(getAtlasEntry(), mBitmap->width(), mBitmap->height(),
+            mMesh = cache.get(getAtlasEntry(renderer), mBitmap->width(), mBitmap->height(),
                     mLocalBounds.getWidth(), mLocalBounds.getHeight(), mPatch);
             mGenerationId = cache.getGenerationId();
         }
@@ -906,14 +899,14 @@
             indexCount += opMesh->indexCount;
         }
 
-        renderer.drawPatches(mBitmap, getAtlasEntry(),
+        renderer.drawPatches(mBitmap, getAtlasEntry(renderer),
                 &vertices[0], indexCount, mPaint);
     }
 
     virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
         // We're not calling the public variant of drawPatch() here
         // This method won't perform the quickReject() since we've already done it at this point
-        renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(),
+        renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(renderer),
                 mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
                 mPaint);
     }
@@ -928,7 +921,7 @@
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
         deferInfo.batchId = DeferredDisplayList::kOpBatch_Patch;
-        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
+        deferInfo.mergeId = getAtlasEntry(renderer) ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
         deferInfo.mergeable = state.mMatrix.isPureTranslate() &&
                 OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
         deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) && mBitmap->isOpaque();
@@ -941,8 +934,7 @@
     uint32_t mGenerationId;
     const Patch* mMesh;
 
-    const AssetAtlas& mAtlas;
-    uint32_t mEntryGenerationId;
+    bool mEntryValid;
     AssetAtlas::Entry* mEntry;
 };
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 3304b2b..0150ac0 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2059,7 +2059,7 @@
     }
 
     mCaches.activeTexture(0);
-    Texture* texture = mCaches.assetAtlas.getEntryTexture(bitmap);
+    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
     const UvMapper& mapper(getMapper(texture));
 
     for (int32_t y = 0; y < meshHeight; y++) {
@@ -2242,7 +2242,7 @@
         return;
     }
 
-    AssetAtlas::Entry* entry = mCaches.assetAtlas.getEntry(bitmap);
+    AssetAtlas::Entry* entry = mRenderState.assetAtlas().getEntry(bitmap);
     const Patch* mesh = mCaches.patchCache.get(entry, bitmap->width(), bitmap->height(),
             right - left, bottom - top, patch);
 
@@ -3066,7 +3066,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Texture* OpenGLRenderer::getTexture(const SkBitmap* bitmap) {
-    Texture* texture = mCaches.assetAtlas.getEntryTexture(bitmap);
+    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
     if (!texture) {
         return mCaches.textureCache.get(bitmap);
     }
diff --git a/libs/hwui/RenderState.cpp b/libs/hwui/RenderState.cpp
index a8cf26f..d1f5f4e 100644
--- a/libs/hwui/RenderState.cpp
+++ b/libs/hwui/RenderState.cpp
@@ -38,6 +38,7 @@
     mCaches = &Caches::getInstance();
     mCaches->init();
     mCaches->setRenderState(this);
+    mCaches->textureCache.setAssetAtlas(&mAssetAtlas);
 }
 
 void RenderState::onGLContextDestroyed() {
@@ -72,6 +73,7 @@
         LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size);
     }
 */
+    mAssetAtlas.terminate();
 }
 
 void RenderState::setViewport(GLsizei width, GLsizei height) {
diff --git a/libs/hwui/RenderState.h b/libs/hwui/RenderState.h
index aa39a3a..629fe0d 100644
--- a/libs/hwui/RenderState.h
+++ b/libs/hwui/RenderState.h
@@ -25,6 +25,8 @@
 
 #include <private/hwui/DrawGlInfo.h>
 
+#include "AssetAtlas.h"
+#include "Caches.h"
 #include "utils/Macros.h"
 
 namespace android {
@@ -77,6 +79,8 @@
     // more thinking...
     void postDecStrong(VirtualLightRefBase* object);
 
+    AssetAtlas& assetAtlas() { return mAssetAtlas; }
+
 private:
     friend class renderthread::RenderThread;
     friend class Caches;
@@ -90,6 +94,7 @@
 
     renderthread::RenderThread& mRenderThread;
     Caches* mCaches;
+    AssetAtlas mAssetAtlas;
     std::set<const Layer*> mActiveLayers;
     std::set<renderthread::CanvasContext*> mRegisteredContexts;
 
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 3677fac..8109433 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -24,6 +24,7 @@
 
 #include <utils/Mutex.h>
 
+#include "AssetAtlas.h"
 #include "Caches.h"
 #include "Texture.h"
 #include "TextureCache.h"
@@ -40,7 +41,7 @@
 TextureCache::TextureCache():
         mCache(LruCache<uint32_t, Texture*>::kUnlimitedCapacity),
         mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)),
-        mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE) {
+        mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE), mAssetAtlas(0) {
     char property[PROPERTY_VALUE_MAX];
     if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, NULL) > 0) {
         INIT_LOGD("  Setting texture cache size to %sMB", property);
@@ -63,7 +64,7 @@
 
 TextureCache::TextureCache(uint32_t maxByteSize):
         mCache(LruCache<uint32_t, Texture*>::kUnlimitedCapacity),
-        mSize(0), mMaxSize(maxByteSize) {
+        mSize(0), mMaxSize(maxByteSize), mAssetAtlas(0) {
     init();
 }
 
@@ -125,6 +126,10 @@
 // Caching
 ///////////////////////////////////////////////////////////////////////////////
 
+void TextureCache::setAssetAtlas(AssetAtlas* assetAtlas) {
+    mAssetAtlas = assetAtlas;
+}
+
 void TextureCache::resetMarkInUse() {
     LruCache<uint32_t, Texture*>::Iterator iter(mCache);
     while (iter.next()) {
@@ -144,6 +149,13 @@
 // Returns a prepared Texture* that either is already in the cache or can fit
 // in the cache (and is thus added to the cache)
 Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap) {
+    if (CC_LIKELY(mAssetAtlas)) {
+        AssetAtlas::Entry* entry = mAssetAtlas->getEntry(bitmap);
+        if (CC_UNLIKELY(entry)) {
+            return entry->texture;
+        }
+    }
+
     Texture* texture = mCache.get(bitmap->pixelRef()->getStableID());
 
     if (!texture) {
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 1e2d741..d7d51a1 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -45,6 +45,8 @@
 // Classes
 ///////////////////////////////////////////////////////////////////////////////
 
+class AssetAtlas;
+
 /**
  * A simple LRU texture cache. The cache has a maximum size expressed in bytes.
  * Any texture added to the cache causing the cache to grow beyond the maximum
@@ -124,6 +126,8 @@
      */
     void setFlushRate(float flushRate);
 
+    void setAssetAtlas(AssetAtlas* assetAtlas);
+
 private:
 
     bool canMakeTextureFromBitmap(const SkBitmap* bitmap);
@@ -156,6 +160,8 @@
 
     Vector<uint32_t> mGarbage;
     mutable Mutex mLock;
+
+    AssetAtlas* mAssetAtlas;
 }; // class TextureCache
 
 }; // namespace uirenderer
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index f93da69..9b8bc6c 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -176,7 +176,8 @@
 
 void EglManager::initAtlas() {
     if (mAtlasBuffer.get()) {
-        Caches::getInstance().assetAtlas.init(mAtlasBuffer, mAtlasMap, mAtlasMapSize);
+        mRenderThread.renderState().assetAtlas().init(mAtlasBuffer,
+                mAtlasMap, mAtlasMapSize);
     }
 }