donut snapshot
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index eec645e..ab02fa0 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -197,6 +197,9 @@
             LOGW("ro.sf.lcd_density not defined, using 160 dpi by default.");
             strcpy(property, "160");
         }
+    } else {
+        /* for the emulator case, reset the dpi values too */
+        mDpiX = mDpiY = atoi(property);
     }
     mDensity = atoi(property) * (1.0f/160.0f);
 
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index fb25663..97dfecc 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -691,9 +691,14 @@
 
         // some layers might have been removed, so
         // we need to update the regions they're exposing.
-        size_t c = mRemovedLayers.size();
+        const SortedVector<LayerBase*>& removedLayers(mRemovedLayers);
+        size_t c = removedLayers.size();
         if (c) {
             mVisibleRegionsDirty = true;
+            while (c--) {
+                mDirtyRegionRemovedLayer.orSelf(
+                        removedLayers[c]->visibleRegionScreen);
+            }
         }
 
         const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
@@ -733,17 +738,15 @@
         layer->validateVisibility(planeTransform);
 
         // start with the whole surface at its current location
-        const Layer::State& s = layer->drawingState();
-        const Rect bounds(layer->visibleBounds());
+        const Layer::State& s(layer->drawingState());
 
         // handle hidden surfaces by setting the visible region to empty
         Region opaqueRegion;
         Region visibleRegion;
         Region coveredRegion;
-        if (UNLIKELY((s.flags & ISurfaceComposer::eLayerHidden) || !s.alpha)) {
-            visibleRegion.clear();
-        } else {
+        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
             const bool translucent = layer->needsBlending();
+            const Rect bounds(layer->visibleBounds());
             visibleRegion.set(bounds);
             coveredRegion = visibleRegion;
 
@@ -790,12 +793,16 @@
         layer->setVisibleRegion(visibleRegion);
         layer->setCoveredRegion(coveredRegion);
 
-        // If a secure layer is partially visible, lockdown the screen!
+        // If a secure layer is partially visible, lock-down the screen!
         if (layer->isSecure() && !visibleRegion.isEmpty()) {
             secureFrameBuffer = true;
         }
     }
 
+    // invalidate the areas where a layer was removed
+    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
+    mDirtyRegionRemovedLayer.clear();
+
     mSecureFrameBuffer = secureFrameBuffer;
     opaqueRegion = aboveOpaqueLayers;
 }
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index 15913f2..0d63e1d 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -351,6 +351,7 @@
                 // Can only accessed from the main thread, these members
                 // don't need synchronization
                 Region                      mDirtyRegion;
+                Region                      mDirtyRegionRemovedLayer;
                 Region                      mInvalidRegion;
                 Region                      mWormholeRegion;
                 Client*                     mLastScheduledBroadcast;
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 4dca8bd..0831f4a 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -1486,7 +1486,7 @@
 
 ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,
         ssize_t blockIndex, uint32_t* outLastRef,
-        uint32_t* inoutTypeSpecFlags) const
+        uint32_t* inoutTypeSpecFlags, ResTable_config* inoutConfig) const
 {
     //printf("Resolving type=0x%x\n", inOutValue->dataType);
     if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
@@ -1498,7 +1498,8 @@
             return blockIndex;
         }
     }
-    return mTable.resolveReference(inOutValue, blockIndex, outLastRef);
+    return mTable.resolveReference(inOutValue, blockIndex, outLastRef,
+            inoutTypeSpecFlags, inoutConfig);
 }
 
 void ResTable::Theme::dumpToLog() const
@@ -1891,7 +1892,8 @@
 }
 
 ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
-        uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags) const
+        uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags,
+        ResTable_config* outConfig) const
 {
     int count=0;
     while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE
@@ -1899,7 +1901,8 @@
         if (outLastRef) *outLastRef = value->data;
         uint32_t lastRef = value->data;
         uint32_t newFlags = 0;
-        const ssize_t newIndex = getResource(value->data, value, true, &newFlags);
+        const ssize_t newIndex = getResource(value->data, value, true, &newFlags,
+                outConfig);
         //LOGI("Resolving reference d=%p: newIndex=%d, t=0x%02x, d=%p\n",
         //     (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data);
         //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);