OSDN Git Service

libgui: remove setPostTransformCrop
[android-x86/frameworks-native.git] / libs / gui / SurfaceTextureClient.cpp
index 99c025f..36a81a6 100644 (file)
@@ -83,6 +83,7 @@ void SurfaceTextureClient::init() {
     mUserWidth = 0;
     mUserHeight = 0;
     mTransformHint = 0;
+    mConsumerRunningBehind = false;
     mConnectedToCpu = false;
 }
 
@@ -171,7 +172,7 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
              result);
         return result;
     }
-    sp<GraphicBuffer>& gbuf(mSlots[buf]);
+    sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
     if (result & ISurfaceTexture::RELEASE_ALL_BUFFERS) {
         freeAllBuffers();
     }
@@ -204,7 +205,8 @@ int SurfaceTextureClient::getSlotFromBufferLocked(
         android_native_buffer_t* buffer) const {
     bool dumpedState = false;
     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
-        if (mSlots[i] != NULL && mSlots[i]->handle == buffer->handle) {
+        if (mSlots[i].buffer != NULL &&
+                mSlots[i].buffer->handle == buffer->handle) {
             return i;
         }
     }
@@ -235,14 +237,23 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
         return i;
     }
 
+    // Make sure the crop rectangle is entirely inside the buffer.
+    Rect crop;
+    mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
+
     ISurfaceTexture::QueueBufferOutput output;
-    ISurfaceTexture::QueueBufferInput input(timestamp,
-            mCrop, mScalingMode, mTransform);
+    ISurfaceTexture::QueueBufferInput input(timestamp, crop, mScalingMode,
+            mTransform);
     status_t err = mSurfaceTexture->queueBuffer(i, input, &output);
     if (err != OK)  {
         ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
     }
-    output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint);
+    uint32_t numPendingBuffers = 0;
+    output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
+            &numPendingBuffers);
+
+    mConsumerRunningBehind = (numPendingBuffers >= 2);
+
     return err;
 }
 
@@ -258,17 +269,16 @@ int SurfaceTextureClient::query(int what, int* value) const {
                     return NO_ERROR;
                 }
                 break;
-            case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
-                {
-                    sp<ISurfaceComposer> composer(
-                            ComposerService::getComposerService());
-                    if (composer->authenticateSurfaceTexture(mSurfaceTexture)) {
-                        *value = 1;
-                    } else {
-                        *value = 0;
-                    }
+            case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
+                sp<ISurfaceComposer> composer(
+                        ComposerService::getComposerService());
+                if (composer->authenticateSurfaceTexture(mSurfaceTexture)) {
+                    *value = 1;
+                } else {
+                    *value = 0;
                 }
                 return NO_ERROR;
+            }
             case NATIVE_WINDOW_CONCRETE_TYPE:
                 *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
                 return NO_ERROR;
@@ -281,6 +291,18 @@ int SurfaceTextureClient::query(int what, int* value) const {
             case NATIVE_WINDOW_TRANSFORM_HINT:
                 *value = mTransformHint;
                 return NO_ERROR;
+            case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
+                status_t err = NO_ERROR;
+                if (!mConsumerRunningBehind) {
+                    *value = 0;
+                } else {
+                    err = mSurfaceTexture->query(what, value);
+                    if (err == NO_ERROR) {
+                        mConsumerRunningBehind = *value;
+                    }
+                }
+                return err;
+            }
         }
     }
     return mSurfaceTexture->query(what, value);
@@ -428,8 +450,14 @@ int SurfaceTextureClient::connect(int api) {
     ATRACE_CALL();
     ALOGV("SurfaceTextureClient::connect");
     Mutex::Autolock lock(mMutex);
-    int err = mSurfaceTexture->connect(api,
-            &mDefaultWidth, &mDefaultHeight, &mTransformHint);
+    ISurfaceTexture::QueueBufferOutput output;
+    int err = mSurfaceTexture->connect(api, &output);
+    if (err == NO_ERROR) {
+        uint32_t numPendingBuffers = 0;
+        output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
+                &numPendingBuffers);
+        mConsumerRunningBehind = (numPendingBuffers >= 2);
+    }
     if (!err && api == NATIVE_WINDOW_API_CPU) {
         mConnectedToCpu = true;
     }
@@ -468,7 +496,6 @@ int SurfaceTextureClient::setUsage(uint32_t reqUsage)
 int SurfaceTextureClient::setCrop(Rect const* rect)
 {
     ATRACE_CALL();
-    ALOGV("SurfaceTextureClient::setCrop");
 
     Rect realRect;
     if (rect == NULL || rect->isEmpty()) {
@@ -477,8 +504,11 @@ int SurfaceTextureClient::setCrop(Rect const* rect)
         realRect = *rect;
     }
 
+    ALOGV("SurfaceTextureClient::setCrop rect=[%d %d %d %d]",
+            realRect.left, realRect.top, realRect.right, realRect.bottom);
+
     Mutex::Autolock lock(mMutex);
-    mCrop = *rect;
+    mCrop = realRect;
     return NO_ERROR;
 }
 
@@ -513,7 +543,6 @@ int SurfaceTextureClient::setBuffersDimensions(int w, int h)
     Mutex::Autolock lock(mMutex);
     mReqWidth = w;
     mReqHeight = h;
-    mCrop.clear();
     return NO_ERROR;
 }
 
@@ -531,7 +560,6 @@ int SurfaceTextureClient::setBuffersUserDimensions(int w, int h)
     Mutex::Autolock lock(mMutex);
     mUserWidth = w;
     mUserHeight = h;
-    mCrop.clear();
     return NO_ERROR;
 }
 
@@ -586,7 +614,7 @@ int SurfaceTextureClient::setBuffersTimestamp(int64_t timestamp)
 
 void SurfaceTextureClient::freeAllBuffers() {
     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
-        mSlots[i] = 0;
+        mSlots[i].buffer = 0;
     }
 }
 
@@ -691,19 +719,32 @@ status_t SurfaceTextureClient::lock(
 
             if (canCopyBack) {
                 // copy the area that is invalid and not repainted this round
-                const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
+                const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
                 if (!copyback.isEmpty())
                     copyBlt(backBuffer, frontBuffer, copyback);
             } else {
                 // if we can't copy-back anything, modify the user's dirty
                 // region to make sure they redraw the whole buffer
                 newDirtyRegion.set(bounds);
+                mDirtyRegion.clear();
+                Mutex::Autolock lock(mMutex);
+                for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
+                    mSlots[i].dirtyRegion.clear();
+                }
             }
 
-            // keep track of the are of the buffer that is "clean"
-            // (ie: that will be redrawn)
-            mOldDirtyRegion = newDirtyRegion;
 
+            { // scope for the lock
+                Mutex::Autolock lock(mMutex);
+                int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
+                if (backBufferSlot >= 0) {
+                    Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
+                    mDirtyRegion.subtract(dirtyRegion);
+                    dirtyRegion = newDirtyRegion;
+                }
+            }
+
+            mDirtyRegion.orSelf(newDirtyRegion);
             if (inOutDirtyBounds) {
                 *inOutDirtyBounds = newDirtyRegion.getBounds();
             }