Merge change I6fc56997 into eclair

* changes:
  fix [2187212] add support for GLESv2 dispatch based on TLS
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index b63e97f..6880144 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -309,7 +309,7 @@
             oldClient = mCameraClient;
 
             // did the client actually change?
-            if (client->asBinder() == mCameraClient->asBinder()) {
+            if ((mCameraClient != NULL) && (client->asBinder() == mCameraClient->asBinder())) {
                 LOGD("Connect to the same client");
                 return NO_ERROR;
             }
@@ -878,7 +878,10 @@
         mSurface->unregisterBuffers();
     }
 
-    mCameraClient->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
+    sp<ICameraClient> c = mCameraClient;
+    if (c != NULL) {
+        c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
+    }
     mHardware->disableMsgType(CAMERA_MSG_SHUTTER);
 
     // It takes some time before yuvPicture callback to be called.
@@ -932,31 +935,38 @@
         }
     }
 
-    // Is the callback enabled or not?
-    if (!(mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
+    // local copy of the callback flags
+    int flags = mPreviewCallbackFlag;
+
+    // is callback enabled?
+    if (!(flags & FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
         // If the enable bit is off, the copy-out and one-shot bits are ignored
         LOGV("frame callback is diabled");
         return;
     }
 
-    // Is the received frame copied out or not?
-    if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
-        LOGV("frame is copied out");
-        copyFrameAndPostCopiedFrame(heap, offset, size);
-    } else {
-        LOGV("frame is directly sent out without copying");
-        mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem);
-    }
+    // hold a strong pointer to the client
+    sp<ICameraClient> c = mCameraClient;
 
-    // Is this is one-shot only?
-    if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
-        LOGV("One-shot only, thus clear the bits and disable frame callback");
+    // clear callback flags if no client or one-shot mode
+    if ((c == NULL) || (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
+        LOGV("Disable preview callback");
         mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
                                 FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
                                 FRAME_CALLBACK_FLAG_ENABLE_MASK);
+        // TODO: Shouldn't we use this API for non-overlay hardware as well?
         if (mUseOverlay)
             mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
     }
+
+    // Is the received frame copied out or not?
+    if (flags & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
+        LOGV("frame is copied");
+        copyFrameAndPostCopiedFrame(c, heap, offset, size);
+    } else {
+        LOGV("frame is forwarded");
+        c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem);
+    }
 }
 
 // picture callback - postview image ready
@@ -972,7 +982,10 @@
     }
 #endif
 
-    mCameraClient->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem);
+    sp<ICameraClient> c = mCameraClient;
+    if (c != NULL) {
+        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem);
+    }
     mHardware->disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
 }
 
@@ -997,7 +1010,10 @@
         mSurface->postBuffer(offset);
     }
 
-    mCameraClient->dataCallback(CAMERA_MSG_RAW_IMAGE, mem);
+    sp<ICameraClient> c = mCameraClient;
+    if (c != NULL) {
+        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem);
+    }
     mHardware->disableMsgType(CAMERA_MSG_RAW_IMAGE);
 }
 
@@ -1014,7 +1030,10 @@
     }
 #endif
 
-    mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem);
+    sp<ICameraClient> c = mCameraClient;
+    if (c != NULL) {
+        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem);
+    }
     mHardware->disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
 }
 
@@ -1032,7 +1051,10 @@
             client->handleShutter();
             break;
         default:
-            client->mCameraClient->notifyCallback(msgType, ext1, ext2);
+            sp<ICameraClient> c = client->mCameraClient;
+            if (c != NULL) {
+                c->notifyCallback(msgType, ext1, ext2);
+            }
             break;
     }
 
@@ -1053,10 +1075,13 @@
         return;
     }
 
+    sp<ICameraClient> c = client->mCameraClient;
     if (dataPtr == NULL) {
         LOGE("Null data returned in data callback");
-        client->mCameraClient->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
-        client->mCameraClient->dataCallback(msgType, NULL);
+        if (c != NULL) {
+            c->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
+            c->dataCallback(msgType, NULL);
+        }
         return;
     }
 
@@ -1074,7 +1099,9 @@
             client->handleCompressedPicture(dataPtr);
             break;
         default:
-            client->mCameraClient->dataCallback(msgType, dataPtr);
+            if (c != NULL) {
+                c->dataCallback(msgType, dataPtr);
+            }
             break;
     }
 
@@ -1095,15 +1122,20 @@
     if (client == 0) {
         return;
     }
+    sp<ICameraClient> c = client->mCameraClient;
 
     if (dataPtr == NULL) {
         LOGE("Null data returned in data with timestamp callback");
-        client->mCameraClient->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
-        client->mCameraClient->dataCallbackTimestamp(0, msgType, NULL);
+        if (c != NULL) {
+            c->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
+            c->dataCallbackTimestamp(0, msgType, NULL);
+        }
         return;
     }
 
-    client->mCameraClient->dataCallbackTimestamp(timestamp, msgType, dataPtr);
+    if (c != NULL) {
+        c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
+    }
 
 #if DEBUG_CLIENT_REFERENCES
     if (client->getStrongCount() == 1) {
@@ -1161,7 +1193,8 @@
     return mHardware->sendCommand(cmd, arg1, arg2);
 }
 
-void CameraService::Client::copyFrameAndPostCopiedFrame(sp<IMemoryHeap> heap, size_t offset, size_t size)
+void CameraService::Client::copyFrameAndPostCopiedFrame(const sp<ICameraClient>& client,
+        const sp<IMemoryHeap>& heap, size_t offset, size_t size)
 {
     LOGV("copyFrameAndPostCopiedFrame");
     // It is necessary to copy out of pmem before sending this to
@@ -1186,7 +1219,7 @@
         LOGE("failed to allocate space for frame callback");
         return;
     }
-    mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
+    client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
 }
 
 status_t CameraService::dump(int fd, const Vector<String16>& args)
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index 2e3597f..2fcf839 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -23,10 +23,9 @@
 #include <ui/CameraHardwareInterface.h>
 #include <ui/Camera.h>
 
-class android::MemoryHeapBase;
-
 namespace android {
 
+class MemoryHeapBase;
 class MediaPlayer;
 
 // ----------------------------------------------------------------------------
@@ -151,7 +150,8 @@
                     void        handleRawPicture(const sp<IMemory>&);
                     void        handleCompressedPicture(const sp<IMemory>&);
 
-                    void        copyFrameAndPostCopiedFrame(sp<IMemoryHeap> heap, size_t offset, size_t size);
+                    void        copyFrameAndPostCopiedFrame(const sp<ICameraClient>& client,
+                                    const sp<IMemoryHeap>& heap, size_t offset, size_t size);
 
         // camera operation mode
         enum camera_mode {
diff --git a/include/private/ui/RegionHelper.h b/include/private/ui/RegionHelper.h
index 926fddb..8d76533 100644
--- a/include/private/ui/RegionHelper.h
+++ b/include/private/ui/RegionHelper.h
@@ -86,7 +86,7 @@
                         rasterizer(current);
                     }
                 }
-            } while(!spannerInner.isDone());            
+            } while(!spannerInner.isDone());
         } while(!spanner.isDone());
     }
 
@@ -220,18 +220,21 @@
         }
 
         inline void prepare(int inside) {
-            SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
-            SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
-            SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
-            SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
             if (inside == SpannerBase::lhs_before_rhs) {
+                SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
+                SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
                 SpannerBase::rhs_head = max_value;
                 SpannerBase::rhs_tail = max_value;
             } else if (inside == SpannerBase::lhs_after_rhs) {
                 SpannerBase::lhs_head = max_value;
                 SpannerBase::lhs_tail = max_value;
+                SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
+                SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
             } else {
-                // use both spans
+                SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
+                SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
+                SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
+                SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
             }
         }
 
diff --git a/libs/ui/tests/region.cpp b/libs/ui/tests/region.cpp
index 0deb2ba..ef15de9 100644
--- a/libs/ui/tests/region.cpp
+++ b/libs/ui/tests/region.cpp
@@ -25,9 +25,16 @@
 
 int main()
 {
+    Region empty;
     Region reg0( Rect(  0, 0,  100, 100 ) );
     Region reg1 = reg0;
     Region reg2, reg3;
+
+    Region reg4 = empty | reg1;
+    Region reg5 = reg1 | empty;
+
+    reg4.dump("reg4");
+    reg5.dump("reg5");
     
     reg0.dump("reg0");
     reg1.dump("reg1");