• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "Surface"
18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
19 //#define LOG_NDEBUG 0
20 
21 #include <android/native_window.h>
22 
23 #include <binder/Parcel.h>
24 
25 #include <utils/Log.h>
26 #include <utils/Trace.h>
27 #include <utils/NativeHandle.h>
28 
29 #include <ui/Fence.h>
30 #include <ui/Region.h>
31 
32 #include <gui/IProducerListener.h>
33 #include <gui/ISurfaceComposer.h>
34 #include <gui/SurfaceComposerClient.h>
35 #include <gui/GLConsumer.h>
36 #include <gui/Surface.h>
37 
38 #include <private/gui/ComposerService.h>
39 
40 namespace android {
41 
Surface(const sp<IGraphicBufferProducer> & bufferProducer,bool controlledByApp)42 Surface::Surface(
43         const sp<IGraphicBufferProducer>& bufferProducer,
44         bool controlledByApp)
45     : mGraphicBufferProducer(bufferProducer),
46       mCrop(Rect::EMPTY_RECT),
47       mGenerationNumber(0),
48       mSharedBufferMode(false),
49       mAutoRefresh(false),
50       mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
51       mSharedBufferHasBeenQueued(false),
52       mNextFrameNumber(1)
53 {
54     // Initialize the ANativeWindow function pointers.
55     ANativeWindow::setSwapInterval  = hook_setSwapInterval;
56     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
57     ANativeWindow::cancelBuffer     = hook_cancelBuffer;
58     ANativeWindow::queueBuffer      = hook_queueBuffer;
59     ANativeWindow::query            = hook_query;
60     ANativeWindow::perform          = hook_perform;
61 
62     ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
63     ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;
64     ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;
65     ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;
66 
67     const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
68     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
69 
70     mReqWidth = 0;
71     mReqHeight = 0;
72     mReqFormat = 0;
73     mReqUsage = 0;
74     mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
75     mDataSpace = HAL_DATASPACE_UNKNOWN;
76     mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
77     mTransform = 0;
78     mStickyTransform = 0;
79     mDefaultWidth = 0;
80     mDefaultHeight = 0;
81     mUserWidth = 0;
82     mUserHeight = 0;
83     mTransformHint = 0;
84     mConsumerRunningBehind = false;
85     mConnectedToCpu = false;
86     mProducerControlledByApp = controlledByApp;
87     mSwapIntervalZero = false;
88 }
89 
~Surface()90 Surface::~Surface() {
91     if (mConnectedToCpu) {
92         Surface::disconnect(NATIVE_WINDOW_API_CPU);
93     }
94 }
95 
getIGraphicBufferProducer() const96 sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const {
97     return mGraphicBufferProducer;
98 }
99 
setSidebandStream(const sp<NativeHandle> & stream)100 void Surface::setSidebandStream(const sp<NativeHandle>& stream) {
101     mGraphicBufferProducer->setSidebandStream(stream);
102 }
103 
allocateBuffers()104 void Surface::allocateBuffers() {
105     uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth;
106     uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight;
107     mGraphicBufferProducer->allocateBuffers(reqWidth, reqHeight,
108             mReqFormat, mReqUsage);
109 }
110 
setGenerationNumber(uint32_t generation)111 status_t Surface::setGenerationNumber(uint32_t generation) {
112     status_t result = mGraphicBufferProducer->setGenerationNumber(generation);
113     if (result == NO_ERROR) {
114         mGenerationNumber = generation;
115     }
116     return result;
117 }
118 
getNextFrameNumber() const119 uint64_t Surface::getNextFrameNumber() const {
120     Mutex::Autolock lock(mMutex);
121     return mNextFrameNumber;
122 }
123 
getConsumerName() const124 String8 Surface::getConsumerName() const {
125     return mGraphicBufferProducer->getConsumerName();
126 }
127 
setDequeueTimeout(nsecs_t timeout)128 status_t Surface::setDequeueTimeout(nsecs_t timeout) {
129     return mGraphicBufferProducer->setDequeueTimeout(timeout);
130 }
131 
getLastQueuedBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence,float outTransformMatrix[16])132 status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
133         sp<Fence>* outFence, float outTransformMatrix[16]) {
134     return mGraphicBufferProducer->getLastQueuedBuffer(outBuffer, outFence,
135             outTransformMatrix);
136 }
137 
getFrameTimestamps(uint64_t frameNumber,nsecs_t * outPostedTime,nsecs_t * outAcquireTime,nsecs_t * outRefreshStartTime,nsecs_t * outGlCompositionDoneTime,nsecs_t * outDisplayRetireTime,nsecs_t * outReleaseTime)138 bool Surface::getFrameTimestamps(uint64_t frameNumber, nsecs_t* outPostedTime,
139         nsecs_t* outAcquireTime, nsecs_t* outRefreshStartTime,
140         nsecs_t* outGlCompositionDoneTime, nsecs_t* outDisplayRetireTime,
141         nsecs_t* outReleaseTime) {
142     ATRACE_CALL();
143 
144     FrameTimestamps timestamps;
145     bool found = mGraphicBufferProducer->getFrameTimestamps(frameNumber,
146             &timestamps);
147     if (found) {
148         if (outPostedTime) {
149             *outPostedTime = timestamps.postedTime;
150         }
151         if (outAcquireTime) {
152             *outAcquireTime = timestamps.acquireTime;
153         }
154         if (outRefreshStartTime) {
155             *outRefreshStartTime = timestamps.refreshStartTime;
156         }
157         if (outGlCompositionDoneTime) {
158             *outGlCompositionDoneTime = timestamps.glCompositionDoneTime;
159         }
160         if (outDisplayRetireTime) {
161             *outDisplayRetireTime = timestamps.displayRetireTime;
162         }
163         if (outReleaseTime) {
164             *outReleaseTime = timestamps.releaseTime;
165         }
166         return true;
167     }
168     return false;
169 }
170 
hook_setSwapInterval(ANativeWindow * window,int interval)171 int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
172     Surface* c = getSelf(window);
173     return c->setSwapInterval(interval);
174 }
175 
hook_dequeueBuffer(ANativeWindow * window,ANativeWindowBuffer ** buffer,int * fenceFd)176 int Surface::hook_dequeueBuffer(ANativeWindow* window,
177         ANativeWindowBuffer** buffer, int* fenceFd) {
178     Surface* c = getSelf(window);
179     return c->dequeueBuffer(buffer, fenceFd);
180 }
181 
hook_cancelBuffer(ANativeWindow * window,ANativeWindowBuffer * buffer,int fenceFd)182 int Surface::hook_cancelBuffer(ANativeWindow* window,
183         ANativeWindowBuffer* buffer, int fenceFd) {
184     Surface* c = getSelf(window);
185     return c->cancelBuffer(buffer, fenceFd);
186 }
187 
hook_queueBuffer(ANativeWindow * window,ANativeWindowBuffer * buffer,int fenceFd)188 int Surface::hook_queueBuffer(ANativeWindow* window,
189         ANativeWindowBuffer* buffer, int fenceFd) {
190     Surface* c = getSelf(window);
191     return c->queueBuffer(buffer, fenceFd);
192 }
193 
hook_dequeueBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer ** buffer)194 int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
195         ANativeWindowBuffer** buffer) {
196     Surface* c = getSelf(window);
197     ANativeWindowBuffer* buf;
198     int fenceFd = -1;
199     int result = c->dequeueBuffer(&buf, &fenceFd);
200     if (result != OK) {
201         return result;
202     }
203     sp<Fence> fence(new Fence(fenceFd));
204     int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
205     if (waitResult != OK) {
206         ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d",
207                 waitResult);
208         c->cancelBuffer(buf, -1);
209         return waitResult;
210     }
211     *buffer = buf;
212     return result;
213 }
214 
hook_cancelBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer * buffer)215 int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
216         ANativeWindowBuffer* buffer) {
217     Surface* c = getSelf(window);
218     return c->cancelBuffer(buffer, -1);
219 }
220 
hook_lockBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer * buffer)221 int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
222         ANativeWindowBuffer* buffer) {
223     Surface* c = getSelf(window);
224     return c->lockBuffer_DEPRECATED(buffer);
225 }
226 
hook_queueBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer * buffer)227 int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
228         ANativeWindowBuffer* buffer) {
229     Surface* c = getSelf(window);
230     return c->queueBuffer(buffer, -1);
231 }
232 
hook_query(const ANativeWindow * window,int what,int * value)233 int Surface::hook_query(const ANativeWindow* window,
234                                 int what, int* value) {
235     const Surface* c = getSelf(window);
236     return c->query(what, value);
237 }
238 
hook_perform(ANativeWindow * window,int operation,...)239 int Surface::hook_perform(ANativeWindow* window, int operation, ...) {
240     va_list args;
241     va_start(args, operation);
242     Surface* c = getSelf(window);
243     int result = c->perform(operation, args);
244     va_end(args);
245     return result;
246 }
247 
setSwapInterval(int interval)248 int Surface::setSwapInterval(int interval) {
249     ATRACE_CALL();
250     // EGL specification states:
251     //  interval is silently clamped to minimum and maximum implementation
252     //  dependent values before being stored.
253 
254     if (interval < minSwapInterval)
255         interval = minSwapInterval;
256 
257     if (interval > maxSwapInterval)
258         interval = maxSwapInterval;
259 
260     mSwapIntervalZero = (interval == 0);
261     mGraphicBufferProducer->setAsyncMode(mSwapIntervalZero);
262 
263     return NO_ERROR;
264 }
265 
dequeueBuffer(android_native_buffer_t ** buffer,int * fenceFd)266 int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
267     ATRACE_CALL();
268     ALOGV("Surface::dequeueBuffer");
269 
270     uint32_t reqWidth;
271     uint32_t reqHeight;
272     PixelFormat reqFormat;
273     uint32_t reqUsage;
274 
275     {
276         Mutex::Autolock lock(mMutex);
277 
278         reqWidth = mReqWidth ? mReqWidth : mUserWidth;
279         reqHeight = mReqHeight ? mReqHeight : mUserHeight;
280 
281         reqFormat = mReqFormat;
282         reqUsage = mReqUsage;
283 
284         if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot !=
285                 BufferItem::INVALID_BUFFER_SLOT) {
286             sp<GraphicBuffer>& gbuf(mSlots[mSharedBufferSlot].buffer);
287             if (gbuf != NULL) {
288                 *buffer = gbuf.get();
289                 *fenceFd = -1;
290                 return OK;
291             }
292         }
293     } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer
294 
295     int buf = -1;
296     sp<Fence> fence;
297     nsecs_t now = systemTime();
298     status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
299             reqWidth, reqHeight, reqFormat, reqUsage);
300     mLastDequeueDuration = systemTime() - now;
301 
302     if (result < 0) {
303         ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer"
304                 "(%d, %d, %d, %d) failed: %d", reqWidth, reqHeight, reqFormat,
305                 reqUsage, result);
306         return result;
307     }
308 
309     Mutex::Autolock lock(mMutex);
310 
311     sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
312 
313     // this should never happen
314     ALOGE_IF(fence == NULL, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);
315 
316     if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
317         freeAllBuffers();
318     }
319 
320     if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
321         result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
322         if (result != NO_ERROR) {
323             ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
324             mGraphicBufferProducer->cancelBuffer(buf, fence);
325             return result;
326         }
327     }
328 
329     if (fence->isValid()) {
330         *fenceFd = fence->dup();
331         if (*fenceFd == -1) {
332             ALOGE("dequeueBuffer: error duping fence: %d", errno);
333             // dup() should never fail; something is badly wrong. Soldier on
334             // and hope for the best; the worst that should happen is some
335             // visible corruption that lasts until the next frame.
336         }
337     } else {
338         *fenceFd = -1;
339     }
340 
341     *buffer = gbuf.get();
342 
343     if (mSharedBufferMode && mAutoRefresh) {
344         mSharedBufferSlot = buf;
345         mSharedBufferHasBeenQueued = false;
346     } else if (mSharedBufferSlot == buf) {
347         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
348         mSharedBufferHasBeenQueued = false;
349     }
350 
351     return OK;
352 }
353 
cancelBuffer(android_native_buffer_t * buffer,int fenceFd)354 int Surface::cancelBuffer(android_native_buffer_t* buffer,
355         int fenceFd) {
356     ATRACE_CALL();
357     ALOGV("Surface::cancelBuffer");
358     Mutex::Autolock lock(mMutex);
359     int i = getSlotFromBufferLocked(buffer);
360     if (i < 0) {
361         if (fenceFd >= 0) {
362             close(fenceFd);
363         }
364         return i;
365     }
366     if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
367         if (fenceFd >= 0) {
368             close(fenceFd);
369         }
370         return OK;
371     }
372     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
373     mGraphicBufferProducer->cancelBuffer(i, fence);
374 
375     if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
376         mSharedBufferHasBeenQueued = true;
377     }
378 
379     return OK;
380 }
381 
getSlotFromBufferLocked(android_native_buffer_t * buffer) const382 int Surface::getSlotFromBufferLocked(
383         android_native_buffer_t* buffer) const {
384     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
385         if (mSlots[i].buffer != NULL &&
386                 mSlots[i].buffer->handle == buffer->handle) {
387             return i;
388         }
389     }
390     ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
391     return BAD_VALUE;
392 }
393 
lockBuffer_DEPRECATED(android_native_buffer_t * buffer)394 int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) {
395     ALOGV("Surface::lockBuffer");
396     Mutex::Autolock lock(mMutex);
397     return OK;
398 }
399 
queueBuffer(android_native_buffer_t * buffer,int fenceFd)400 int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
401     ATRACE_CALL();
402     ALOGV("Surface::queueBuffer");
403     Mutex::Autolock lock(mMutex);
404     int64_t timestamp;
405     bool isAutoTimestamp = false;
406 
407     if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
408         timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
409         isAutoTimestamp = true;
410         ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
411             timestamp / 1000000.f);
412     } else {
413         timestamp = mTimestamp;
414     }
415     int i = getSlotFromBufferLocked(buffer);
416     if (i < 0) {
417         if (fenceFd >= 0) {
418             close(fenceFd);
419         }
420         return i;
421     }
422     if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
423         if (fenceFd >= 0) {
424             close(fenceFd);
425         }
426         return OK;
427     }
428 
429 
430     // Make sure the crop rectangle is entirely inside the buffer.
431     Rect crop(Rect::EMPTY_RECT);
432     mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
433 
434     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
435     IGraphicBufferProducer::QueueBufferOutput output;
436     IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
437             mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform,
438             fence, mStickyTransform);
439 
440     if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) {
441         input.setSurfaceDamage(Region::INVALID_REGION);
442     } else {
443         // Here we do two things:
444         // 1) The surface damage was specified using the OpenGL ES convention of
445         //    the origin being in the bottom-left corner. Here we flip to the
446         //    convention that the rest of the system uses (top-left corner) by
447         //    subtracting all top/bottom coordinates from the buffer height.
448         // 2) If the buffer is coming in rotated (for example, because the EGL
449         //    implementation is reacting to the transform hint coming back from
450         //    SurfaceFlinger), the surface damage needs to be rotated the
451         //    opposite direction, since it was generated assuming an unrotated
452         //    buffer (the app doesn't know that the EGL implementation is
453         //    reacting to the transform hint behind its back). The
454         //    transformations in the switch statement below apply those
455         //    complementary rotations (e.g., if 90 degrees, rotate 270 degrees).
456 
457         int width = buffer->width;
458         int height = buffer->height;
459         bool rotated90 = (mTransform ^ mStickyTransform) &
460                 NATIVE_WINDOW_TRANSFORM_ROT_90;
461         if (rotated90) {
462             std::swap(width, height);
463         }
464 
465         Region flippedRegion;
466         for (auto rect : mDirtyRegion) {
467             int left = rect.left;
468             int right = rect.right;
469             int top = height - rect.bottom; // Flip from OpenGL convention
470             int bottom = height - rect.top; // Flip from OpenGL convention
471             switch (mTransform ^ mStickyTransform) {
472                 case NATIVE_WINDOW_TRANSFORM_ROT_90: {
473                     // Rotate 270 degrees
474                     Rect flippedRect{top, width - right, bottom, width - left};
475                     flippedRegion.orSelf(flippedRect);
476                     break;
477                 }
478                 case NATIVE_WINDOW_TRANSFORM_ROT_180: {
479                     // Rotate 180 degrees
480                     Rect flippedRect{width - right, height - bottom,
481                             width - left, height - top};
482                     flippedRegion.orSelf(flippedRect);
483                     break;
484                 }
485                 case NATIVE_WINDOW_TRANSFORM_ROT_270: {
486                     // Rotate 90 degrees
487                     Rect flippedRect{height - bottom, left,
488                             height - top, right};
489                     flippedRegion.orSelf(flippedRect);
490                     break;
491                 }
492                 default: {
493                     Rect flippedRect{left, top, right, bottom};
494                     flippedRegion.orSelf(flippedRect);
495                     break;
496                 }
497             }
498         }
499 
500         input.setSurfaceDamage(flippedRegion);
501     }
502 
503     nsecs_t now = systemTime();
504     status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
505     mLastQueueDuration = systemTime() - now;
506     if (err != OK)  {
507         ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
508     }
509 
510     uint32_t numPendingBuffers = 0;
511     uint32_t hint = 0;
512     output.deflate(&mDefaultWidth, &mDefaultHeight, &hint,
513             &numPendingBuffers, &mNextFrameNumber);
514 
515     // Disable transform hint if sticky transform is set.
516     if (mStickyTransform == 0) {
517         mTransformHint = hint;
518     }
519 
520     mConsumerRunningBehind = (numPendingBuffers >= 2);
521 
522     if (!mConnectedToCpu) {
523         // Clear surface damage back to full-buffer
524         mDirtyRegion = Region::INVALID_REGION;
525     }
526 
527     if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
528         mSharedBufferHasBeenQueued = true;
529     }
530 
531     mQueueBufferCondition.broadcast();
532 
533     return err;
534 }
535 
query(int what,int * value) const536 int Surface::query(int what, int* value) const {
537     ATRACE_CALL();
538     ALOGV("Surface::query");
539     { // scope for the lock
540         Mutex::Autolock lock(mMutex);
541         switch (what) {
542             case NATIVE_WINDOW_FORMAT:
543                 if (mReqFormat) {
544                     *value = static_cast<int>(mReqFormat);
545                     return NO_ERROR;
546                 }
547                 break;
548             case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
549                 sp<ISurfaceComposer> composer(
550                         ComposerService::getComposerService());
551                 if (composer->authenticateSurfaceTexture(mGraphicBufferProducer)) {
552                     *value = 1;
553                 } else {
554                     *value = 0;
555                 }
556                 return NO_ERROR;
557             }
558             case NATIVE_WINDOW_CONCRETE_TYPE:
559                 *value = NATIVE_WINDOW_SURFACE;
560                 return NO_ERROR;
561             case NATIVE_WINDOW_DEFAULT_WIDTH:
562                 *value = static_cast<int>(
563                         mUserWidth ? mUserWidth : mDefaultWidth);
564                 return NO_ERROR;
565             case NATIVE_WINDOW_DEFAULT_HEIGHT:
566                 *value = static_cast<int>(
567                         mUserHeight ? mUserHeight : mDefaultHeight);
568                 return NO_ERROR;
569             case NATIVE_WINDOW_TRANSFORM_HINT:
570                 *value = static_cast<int>(mTransformHint);
571                 return NO_ERROR;
572             case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
573                 status_t err = NO_ERROR;
574                 if (!mConsumerRunningBehind) {
575                     *value = 0;
576                 } else {
577                     err = mGraphicBufferProducer->query(what, value);
578                     if (err == NO_ERROR) {
579                         mConsumerRunningBehind = *value;
580                     }
581                 }
582                 return err;
583             }
584             case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: {
585                 int64_t durationUs = mLastDequeueDuration / 1000;
586                 *value = durationUs > std::numeric_limits<int>::max() ?
587                         std::numeric_limits<int>::max() :
588                         static_cast<int>(durationUs);
589                 return NO_ERROR;
590             }
591             case NATIVE_WINDOW_LAST_QUEUE_DURATION: {
592                 int64_t durationUs = mLastQueueDuration / 1000;
593                 *value = durationUs > std::numeric_limits<int>::max() ?
594                         std::numeric_limits<int>::max() :
595                         static_cast<int>(durationUs);
596                 return NO_ERROR;
597             }
598         }
599     }
600     return mGraphicBufferProducer->query(what, value);
601 }
602 
perform(int operation,va_list args)603 int Surface::perform(int operation, va_list args)
604 {
605     int res = NO_ERROR;
606     switch (operation) {
607     case NATIVE_WINDOW_CONNECT:
608         // deprecated. must return NO_ERROR.
609         break;
610     case NATIVE_WINDOW_DISCONNECT:
611         // deprecated. must return NO_ERROR.
612         break;
613     case NATIVE_WINDOW_SET_USAGE:
614         res = dispatchSetUsage(args);
615         break;
616     case NATIVE_WINDOW_SET_CROP:
617         res = dispatchSetCrop(args);
618         break;
619     case NATIVE_WINDOW_SET_BUFFER_COUNT:
620         res = dispatchSetBufferCount(args);
621         break;
622     case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
623         res = dispatchSetBuffersGeometry(args);
624         break;
625     case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
626         res = dispatchSetBuffersTransform(args);
627         break;
628     case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM:
629         res = dispatchSetBuffersStickyTransform(args);
630         break;
631     case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
632         res = dispatchSetBuffersTimestamp(args);
633         break;
634     case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
635         res = dispatchSetBuffersDimensions(args);
636         break;
637     case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
638         res = dispatchSetBuffersUserDimensions(args);
639         break;
640     case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
641         res = dispatchSetBuffersFormat(args);
642         break;
643     case NATIVE_WINDOW_LOCK:
644         res = dispatchLock(args);
645         break;
646     case NATIVE_WINDOW_UNLOCK_AND_POST:
647         res = dispatchUnlockAndPost(args);
648         break;
649     case NATIVE_WINDOW_SET_SCALING_MODE:
650         res = dispatchSetScalingMode(args);
651         break;
652     case NATIVE_WINDOW_API_CONNECT:
653         res = dispatchConnect(args);
654         break;
655     case NATIVE_WINDOW_API_DISCONNECT:
656         res = dispatchDisconnect(args);
657         break;
658     case NATIVE_WINDOW_SET_SIDEBAND_STREAM:
659         res = dispatchSetSidebandStream(args);
660         break;
661     case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
662         res = dispatchSetBuffersDataSpace(args);
663         break;
664     case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
665         res = dispatchSetSurfaceDamage(args);
666         break;
667     case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE:
668         res = dispatchSetSharedBufferMode(args);
669         break;
670     case NATIVE_WINDOW_SET_AUTO_REFRESH:
671         res = dispatchSetAutoRefresh(args);
672         break;
673     case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS:
674         res = dispatchGetFrameTimestamps(args);
675         break;
676     default:
677         res = NAME_NOT_FOUND;
678         break;
679     }
680     return res;
681 }
682 
dispatchConnect(va_list args)683 int Surface::dispatchConnect(va_list args) {
684     int api = va_arg(args, int);
685     return connect(api);
686 }
687 
dispatchDisconnect(va_list args)688 int Surface::dispatchDisconnect(va_list args) {
689     int api = va_arg(args, int);
690     return disconnect(api);
691 }
692 
dispatchSetUsage(va_list args)693 int Surface::dispatchSetUsage(va_list args) {
694     int usage = va_arg(args, int);
695     return setUsage(static_cast<uint32_t>(usage));
696 }
697 
dispatchSetCrop(va_list args)698 int Surface::dispatchSetCrop(va_list args) {
699     android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
700     return setCrop(reinterpret_cast<Rect const*>(rect));
701 }
702 
dispatchSetBufferCount(va_list args)703 int Surface::dispatchSetBufferCount(va_list args) {
704     size_t bufferCount = va_arg(args, size_t);
705     return setBufferCount(static_cast<int32_t>(bufferCount));
706 }
707 
dispatchSetBuffersGeometry(va_list args)708 int Surface::dispatchSetBuffersGeometry(va_list args) {
709     uint32_t width = va_arg(args, uint32_t);
710     uint32_t height = va_arg(args, uint32_t);
711     PixelFormat format = va_arg(args, PixelFormat);
712     int err = setBuffersDimensions(width, height);
713     if (err != 0) {
714         return err;
715     }
716     return setBuffersFormat(format);
717 }
718 
dispatchSetBuffersDimensions(va_list args)719 int Surface::dispatchSetBuffersDimensions(va_list args) {
720     uint32_t width = va_arg(args, uint32_t);
721     uint32_t height = va_arg(args, uint32_t);
722     return setBuffersDimensions(width, height);
723 }
724 
dispatchSetBuffersUserDimensions(va_list args)725 int Surface::dispatchSetBuffersUserDimensions(va_list args) {
726     uint32_t width = va_arg(args, uint32_t);
727     uint32_t height = va_arg(args, uint32_t);
728     return setBuffersUserDimensions(width, height);
729 }
730 
dispatchSetBuffersFormat(va_list args)731 int Surface::dispatchSetBuffersFormat(va_list args) {
732     PixelFormat format = va_arg(args, PixelFormat);
733     return setBuffersFormat(format);
734 }
735 
dispatchSetScalingMode(va_list args)736 int Surface::dispatchSetScalingMode(va_list args) {
737     int mode = va_arg(args, int);
738     return setScalingMode(mode);
739 }
740 
dispatchSetBuffersTransform(va_list args)741 int Surface::dispatchSetBuffersTransform(va_list args) {
742     uint32_t transform = va_arg(args, uint32_t);
743     return setBuffersTransform(transform);
744 }
745 
dispatchSetBuffersStickyTransform(va_list args)746 int Surface::dispatchSetBuffersStickyTransform(va_list args) {
747     uint32_t transform = va_arg(args, uint32_t);
748     return setBuffersStickyTransform(transform);
749 }
750 
dispatchSetBuffersTimestamp(va_list args)751 int Surface::dispatchSetBuffersTimestamp(va_list args) {
752     int64_t timestamp = va_arg(args, int64_t);
753     return setBuffersTimestamp(timestamp);
754 }
755 
dispatchLock(va_list args)756 int Surface::dispatchLock(va_list args) {
757     ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
758     ARect* inOutDirtyBounds = va_arg(args, ARect*);
759     return lock(outBuffer, inOutDirtyBounds);
760 }
761 
dispatchUnlockAndPost(va_list args)762 int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) {
763     return unlockAndPost();
764 }
765 
dispatchSetSidebandStream(va_list args)766 int Surface::dispatchSetSidebandStream(va_list args) {
767     native_handle_t* sH = va_arg(args, native_handle_t*);
768     sp<NativeHandle> sidebandHandle = NativeHandle::create(sH, false);
769     setSidebandStream(sidebandHandle);
770     return OK;
771 }
772 
dispatchSetBuffersDataSpace(va_list args)773 int Surface::dispatchSetBuffersDataSpace(va_list args) {
774     android_dataspace dataspace =
775             static_cast<android_dataspace>(va_arg(args, int));
776     return setBuffersDataSpace(dataspace);
777 }
778 
dispatchSetSurfaceDamage(va_list args)779 int Surface::dispatchSetSurfaceDamage(va_list args) {
780     android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
781     size_t numRects = va_arg(args, size_t);
782     setSurfaceDamage(rects, numRects);
783     return NO_ERROR;
784 }
785 
dispatchSetSharedBufferMode(va_list args)786 int Surface::dispatchSetSharedBufferMode(va_list args) {
787     bool sharedBufferMode = va_arg(args, int);
788     return setSharedBufferMode(sharedBufferMode);
789 }
790 
dispatchSetAutoRefresh(va_list args)791 int Surface::dispatchSetAutoRefresh(va_list args) {
792     bool autoRefresh = va_arg(args, int);
793     return setAutoRefresh(autoRefresh);
794 }
795 
dispatchGetFrameTimestamps(va_list args)796 int Surface::dispatchGetFrameTimestamps(va_list args) {
797     uint32_t framesAgo = va_arg(args, uint32_t);
798     nsecs_t* outPostedTime = va_arg(args, int64_t*);
799     nsecs_t* outAcquireTime = va_arg(args, int64_t*);
800     nsecs_t* outRefreshStartTime = va_arg(args, int64_t*);
801     nsecs_t* outGlCompositionDoneTime = va_arg(args, int64_t*);
802     nsecs_t* outDisplayRetireTime = va_arg(args, int64_t*);
803     nsecs_t* outReleaseTime = va_arg(args, int64_t*);
804     bool ret = getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo,
805             outPostedTime, outAcquireTime, outRefreshStartTime,
806             outGlCompositionDoneTime, outDisplayRetireTime, outReleaseTime);
807     return ret ? NO_ERROR : BAD_VALUE;
808 }
809 
connect(int api)810 int Surface::connect(int api) {
811     static sp<IProducerListener> listener = new DummyProducerListener();
812     return connect(api, listener);
813 }
814 
connect(int api,const sp<IProducerListener> & listener)815 int Surface::connect(int api, const sp<IProducerListener>& listener) {
816     ATRACE_CALL();
817     ALOGV("Surface::connect");
818     Mutex::Autolock lock(mMutex);
819     IGraphicBufferProducer::QueueBufferOutput output;
820     int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
821     if (err == NO_ERROR) {
822         uint32_t numPendingBuffers = 0;
823         uint32_t hint = 0;
824         output.deflate(&mDefaultWidth, &mDefaultHeight, &hint,
825                 &numPendingBuffers, &mNextFrameNumber);
826 
827         // Disable transform hint if sticky transform is set.
828         if (mStickyTransform == 0) {
829             mTransformHint = hint;
830         }
831 
832         mConsumerRunningBehind = (numPendingBuffers >= 2);
833     }
834     if (!err && api == NATIVE_WINDOW_API_CPU) {
835         mConnectedToCpu = true;
836         // Clear the dirty region in case we're switching from a non-CPU API
837         mDirtyRegion.clear();
838     } else if (!err) {
839         // Initialize the dirty region for tracking surface damage
840         mDirtyRegion = Region::INVALID_REGION;
841     }
842 
843     return err;
844 }
845 
846 
disconnect(int api)847 int Surface::disconnect(int api) {
848     ATRACE_CALL();
849     ALOGV("Surface::disconnect");
850     Mutex::Autolock lock(mMutex);
851     mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
852     mSharedBufferHasBeenQueued = false;
853     freeAllBuffers();
854     int err = mGraphicBufferProducer->disconnect(api);
855     if (!err) {
856         mReqFormat = 0;
857         mReqWidth = 0;
858         mReqHeight = 0;
859         mReqUsage = 0;
860         mCrop.clear();
861         mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
862         mTransform = 0;
863         mStickyTransform = 0;
864 
865         if (api == NATIVE_WINDOW_API_CPU) {
866             mConnectedToCpu = false;
867         }
868     }
869     return err;
870 }
871 
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)872 int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
873         sp<Fence>* outFence) {
874     ATRACE_CALL();
875     ALOGV("Surface::detachNextBuffer");
876 
877     if (outBuffer == NULL || outFence == NULL) {
878         return BAD_VALUE;
879     }
880 
881     Mutex::Autolock lock(mMutex);
882 
883     sp<GraphicBuffer> buffer(NULL);
884     sp<Fence> fence(NULL);
885     status_t result = mGraphicBufferProducer->detachNextBuffer(
886             &buffer, &fence);
887     if (result != NO_ERROR) {
888         return result;
889     }
890 
891     *outBuffer = buffer;
892     if (fence != NULL && fence->isValid()) {
893         *outFence = fence;
894     } else {
895         *outFence = Fence::NO_FENCE;
896     }
897 
898     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
899         if (mSlots[i].buffer != NULL &&
900                 mSlots[i].buffer->handle == buffer->handle) {
901             mSlots[i].buffer = NULL;
902         }
903     }
904 
905     return NO_ERROR;
906 }
907 
attachBuffer(ANativeWindowBuffer * buffer)908 int Surface::attachBuffer(ANativeWindowBuffer* buffer)
909 {
910     ATRACE_CALL();
911     ALOGV("Surface::attachBuffer");
912 
913     Mutex::Autolock lock(mMutex);
914 
915     sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
916     uint32_t priorGeneration = graphicBuffer->mGenerationNumber;
917     graphicBuffer->mGenerationNumber = mGenerationNumber;
918     int32_t attachedSlot = -1;
919     status_t result = mGraphicBufferProducer->attachBuffer(
920             &attachedSlot, graphicBuffer);
921     if (result != NO_ERROR) {
922         ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result);
923         graphicBuffer->mGenerationNumber = priorGeneration;
924         return result;
925     }
926     mSlots[attachedSlot].buffer = graphicBuffer;
927 
928     return NO_ERROR;
929 }
930 
setUsage(uint32_t reqUsage)931 int Surface::setUsage(uint32_t reqUsage)
932 {
933     ALOGV("Surface::setUsage");
934     Mutex::Autolock lock(mMutex);
935     if (reqUsage != mReqUsage) {
936         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
937     }
938     mReqUsage = reqUsage;
939     return OK;
940 }
941 
setCrop(Rect const * rect)942 int Surface::setCrop(Rect const* rect)
943 {
944     ATRACE_CALL();
945 
946     Rect realRect(Rect::EMPTY_RECT);
947     if (rect == NULL || rect->isEmpty()) {
948         realRect.clear();
949     } else {
950         realRect = *rect;
951     }
952 
953     ALOGV("Surface::setCrop rect=[%d %d %d %d]",
954             realRect.left, realRect.top, realRect.right, realRect.bottom);
955 
956     Mutex::Autolock lock(mMutex);
957     mCrop = realRect;
958     return NO_ERROR;
959 }
960 
setBufferCount(int bufferCount)961 int Surface::setBufferCount(int bufferCount)
962 {
963     ATRACE_CALL();
964     ALOGV("Surface::setBufferCount");
965     Mutex::Autolock lock(mMutex);
966 
967     status_t err = NO_ERROR;
968     if (bufferCount == 0) {
969         err = mGraphicBufferProducer->setMaxDequeuedBufferCount(1);
970     } else {
971         int minUndequeuedBuffers = 0;
972         err = mGraphicBufferProducer->query(
973                 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers);
974         if (err == NO_ERROR) {
975             err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
976                     bufferCount - minUndequeuedBuffers);
977         }
978     }
979 
980     ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
981              bufferCount, strerror(-err));
982 
983     return err;
984 }
985 
setMaxDequeuedBufferCount(int maxDequeuedBuffers)986 int Surface::setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
987     ATRACE_CALL();
988     ALOGV("Surface::setMaxDequeuedBufferCount");
989     Mutex::Autolock lock(mMutex);
990 
991     status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
992             maxDequeuedBuffers);
993     ALOGE_IF(err, "IGraphicBufferProducer::setMaxDequeuedBufferCount(%d) "
994             "returned %s", maxDequeuedBuffers, strerror(-err));
995 
996     return err;
997 }
998 
setAsyncMode(bool async)999 int Surface::setAsyncMode(bool async) {
1000     ATRACE_CALL();
1001     ALOGV("Surface::setAsyncMode");
1002     Mutex::Autolock lock(mMutex);
1003 
1004     status_t err = mGraphicBufferProducer->setAsyncMode(async);
1005     ALOGE_IF(err, "IGraphicBufferProducer::setAsyncMode(%d) returned %s",
1006             async, strerror(-err));
1007 
1008     return err;
1009 }
1010 
setSharedBufferMode(bool sharedBufferMode)1011 int Surface::setSharedBufferMode(bool sharedBufferMode) {
1012     ATRACE_CALL();
1013     ALOGV("Surface::setSharedBufferMode (%d)", sharedBufferMode);
1014     Mutex::Autolock lock(mMutex);
1015 
1016     status_t err = mGraphicBufferProducer->setSharedBufferMode(
1017             sharedBufferMode);
1018     if (err == NO_ERROR) {
1019         mSharedBufferMode = sharedBufferMode;
1020     }
1021     ALOGE_IF(err, "IGraphicBufferProducer::setSharedBufferMode(%d) returned"
1022             "%s", sharedBufferMode, strerror(-err));
1023 
1024     return err;
1025 }
1026 
setAutoRefresh(bool autoRefresh)1027 int Surface::setAutoRefresh(bool autoRefresh) {
1028     ATRACE_CALL();
1029     ALOGV("Surface::setAutoRefresh (%d)", autoRefresh);
1030     Mutex::Autolock lock(mMutex);
1031 
1032     status_t err = mGraphicBufferProducer->setAutoRefresh(autoRefresh);
1033     if (err == NO_ERROR) {
1034         mAutoRefresh = autoRefresh;
1035     }
1036     ALOGE_IF(err, "IGraphicBufferProducer::setAutoRefresh(%d) returned %s",
1037             autoRefresh, strerror(-err));
1038     return err;
1039 }
1040 
setBuffersDimensions(uint32_t width,uint32_t height)1041 int Surface::setBuffersDimensions(uint32_t width, uint32_t height)
1042 {
1043     ATRACE_CALL();
1044     ALOGV("Surface::setBuffersDimensions");
1045 
1046     if ((width && !height) || (!width && height))
1047         return BAD_VALUE;
1048 
1049     Mutex::Autolock lock(mMutex);
1050     if (width != mReqWidth || height != mReqHeight) {
1051         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1052     }
1053     mReqWidth = width;
1054     mReqHeight = height;
1055     return NO_ERROR;
1056 }
1057 
setBuffersUserDimensions(uint32_t width,uint32_t height)1058 int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height)
1059 {
1060     ATRACE_CALL();
1061     ALOGV("Surface::setBuffersUserDimensions");
1062 
1063     if ((width && !height) || (!width && height))
1064         return BAD_VALUE;
1065 
1066     Mutex::Autolock lock(mMutex);
1067     if (width != mUserWidth || height != mUserHeight) {
1068         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1069     }
1070     mUserWidth = width;
1071     mUserHeight = height;
1072     return NO_ERROR;
1073 }
1074 
setBuffersFormat(PixelFormat format)1075 int Surface::setBuffersFormat(PixelFormat format)
1076 {
1077     ALOGV("Surface::setBuffersFormat");
1078 
1079     Mutex::Autolock lock(mMutex);
1080     if (format != mReqFormat) {
1081         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1082     }
1083     mReqFormat = format;
1084     return NO_ERROR;
1085 }
1086 
setScalingMode(int mode)1087 int Surface::setScalingMode(int mode)
1088 {
1089     ATRACE_CALL();
1090     ALOGV("Surface::setScalingMode(%d)", mode);
1091 
1092     switch (mode) {
1093         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
1094         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
1095         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
1096         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
1097             break;
1098         default:
1099             ALOGE("unknown scaling mode: %d", mode);
1100             return BAD_VALUE;
1101     }
1102 
1103     Mutex::Autolock lock(mMutex);
1104     mScalingMode = mode;
1105     return NO_ERROR;
1106 }
1107 
setBuffersTransform(uint32_t transform)1108 int Surface::setBuffersTransform(uint32_t transform)
1109 {
1110     ATRACE_CALL();
1111     ALOGV("Surface::setBuffersTransform");
1112     Mutex::Autolock lock(mMutex);
1113     mTransform = transform;
1114     return NO_ERROR;
1115 }
1116 
setBuffersStickyTransform(uint32_t transform)1117 int Surface::setBuffersStickyTransform(uint32_t transform)
1118 {
1119     ATRACE_CALL();
1120     ALOGV("Surface::setBuffersStickyTransform");
1121     Mutex::Autolock lock(mMutex);
1122     mStickyTransform = transform;
1123     return NO_ERROR;
1124 }
1125 
setBuffersTimestamp(int64_t timestamp)1126 int Surface::setBuffersTimestamp(int64_t timestamp)
1127 {
1128     ALOGV("Surface::setBuffersTimestamp");
1129     Mutex::Autolock lock(mMutex);
1130     mTimestamp = timestamp;
1131     return NO_ERROR;
1132 }
1133 
setBuffersDataSpace(android_dataspace dataSpace)1134 int Surface::setBuffersDataSpace(android_dataspace dataSpace)
1135 {
1136     ALOGV("Surface::setBuffersDataSpace");
1137     Mutex::Autolock lock(mMutex);
1138     mDataSpace = dataSpace;
1139     return NO_ERROR;
1140 }
1141 
freeAllBuffers()1142 void Surface::freeAllBuffers() {
1143     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
1144         mSlots[i].buffer = 0;
1145     }
1146 }
1147 
setSurfaceDamage(android_native_rect_t * rects,size_t numRects)1148 void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) {
1149     ATRACE_CALL();
1150     ALOGV("Surface::setSurfaceDamage");
1151     Mutex::Autolock lock(mMutex);
1152 
1153     if (mConnectedToCpu || numRects == 0) {
1154         mDirtyRegion = Region::INVALID_REGION;
1155         return;
1156     }
1157 
1158     mDirtyRegion.clear();
1159     for (size_t r = 0; r < numRects; ++r) {
1160         // We intentionally flip top and bottom here, since because they're
1161         // specified with a bottom-left origin, top > bottom, which fails
1162         // validation in the Region class. We will fix this up when we flip to a
1163         // top-left origin in queueBuffer.
1164         Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top);
1165         mDirtyRegion.orSelf(rect);
1166     }
1167 }
1168 
1169 // ----------------------------------------------------------------------
1170 // the lock/unlock APIs must be used from the same thread
1171 
copyBlt(const sp<GraphicBuffer> & dst,const sp<GraphicBuffer> & src,const Region & reg)1172 static status_t copyBlt(
1173         const sp<GraphicBuffer>& dst,
1174         const sp<GraphicBuffer>& src,
1175         const Region& reg)
1176 {
1177     // src and dst with, height and format must be identical. no verification
1178     // is done here.
1179     status_t err;
1180     uint8_t* src_bits = NULL;
1181     err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(),
1182             reinterpret_cast<void**>(&src_bits));
1183     ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
1184 
1185     uint8_t* dst_bits = NULL;
1186     err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(),
1187             reinterpret_cast<void**>(&dst_bits));
1188     ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
1189 
1190     Region::const_iterator head(reg.begin());
1191     Region::const_iterator tail(reg.end());
1192     if (head != tail && src_bits && dst_bits) {
1193         const size_t bpp = bytesPerPixel(src->format);
1194         const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp;
1195         const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp;
1196 
1197         while (head != tail) {
1198             const Rect& r(*head++);
1199             int32_t h = r.height();
1200             if (h <= 0) continue;
1201             size_t size = static_cast<uint32_t>(r.width()) * bpp;
1202             uint8_t const * s = src_bits +
1203                     static_cast<uint32_t>(r.left + src->stride * r.top) * bpp;
1204             uint8_t       * d = dst_bits +
1205                     static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp;
1206             if (dbpr==sbpr && size==sbpr) {
1207                 size *= static_cast<size_t>(h);
1208                 h = 1;
1209             }
1210             do {
1211                 memcpy(d, s, size);
1212                 d += dbpr;
1213                 s += sbpr;
1214             } while (--h > 0);
1215         }
1216     }
1217 
1218     if (src_bits)
1219         src->unlock();
1220 
1221     if (dst_bits)
1222         dst->unlock();
1223 
1224     return err;
1225 }
1226 
1227 // ----------------------------------------------------------------------------
1228 
lock(ANativeWindow_Buffer * outBuffer,ARect * inOutDirtyBounds)1229 status_t Surface::lock(
1230         ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
1231 {
1232     if (mLockedBuffer != 0) {
1233         ALOGE("Surface::lock failed, already locked");
1234         return INVALID_OPERATION;
1235     }
1236 
1237     if (!mConnectedToCpu) {
1238         int err = Surface::connect(NATIVE_WINDOW_API_CPU);
1239         if (err) {
1240             return err;
1241         }
1242         // we're intending to do software rendering from this point
1243         setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
1244     }
1245 
1246     ANativeWindowBuffer* out;
1247     int fenceFd = -1;
1248     status_t err = dequeueBuffer(&out, &fenceFd);
1249     ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
1250     if (err == NO_ERROR) {
1251         sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
1252         const Rect bounds(backBuffer->width, backBuffer->height);
1253 
1254         Region newDirtyRegion;
1255         if (inOutDirtyBounds) {
1256             newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
1257             newDirtyRegion.andSelf(bounds);
1258         } else {
1259             newDirtyRegion.set(bounds);
1260         }
1261 
1262         // figure out if we can copy the frontbuffer back
1263         const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
1264         const bool canCopyBack = (frontBuffer != 0 &&
1265                 backBuffer->width  == frontBuffer->width &&
1266                 backBuffer->height == frontBuffer->height &&
1267                 backBuffer->format == frontBuffer->format);
1268 
1269         if (canCopyBack) {
1270             // copy the area that is invalid and not repainted this round
1271             const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
1272             if (!copyback.isEmpty())
1273                 copyBlt(backBuffer, frontBuffer, copyback);
1274         } else {
1275             // if we can't copy-back anything, modify the user's dirty
1276             // region to make sure they redraw the whole buffer
1277             newDirtyRegion.set(bounds);
1278             mDirtyRegion.clear();
1279             Mutex::Autolock lock(mMutex);
1280             for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
1281                 mSlots[i].dirtyRegion.clear();
1282             }
1283         }
1284 
1285 
1286         { // scope for the lock
1287             Mutex::Autolock lock(mMutex);
1288             int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
1289             if (backBufferSlot >= 0) {
1290                 Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
1291                 mDirtyRegion.subtract(dirtyRegion);
1292                 dirtyRegion = newDirtyRegion;
1293             }
1294         }
1295 
1296         mDirtyRegion.orSelf(newDirtyRegion);
1297         if (inOutDirtyBounds) {
1298             *inOutDirtyBounds = newDirtyRegion.getBounds();
1299         }
1300 
1301         void* vaddr;
1302         status_t res = backBuffer->lockAsync(
1303                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1304                 newDirtyRegion.bounds(), &vaddr, fenceFd);
1305 
1306         ALOGW_IF(res, "failed locking buffer (handle = %p)",
1307                 backBuffer->handle);
1308 
1309         if (res != 0) {
1310             err = INVALID_OPERATION;
1311         } else {
1312             mLockedBuffer = backBuffer;
1313             outBuffer->width  = backBuffer->width;
1314             outBuffer->height = backBuffer->height;
1315             outBuffer->stride = backBuffer->stride;
1316             outBuffer->format = backBuffer->format;
1317             outBuffer->bits   = vaddr;
1318         }
1319     }
1320     return err;
1321 }
1322 
unlockAndPost()1323 status_t Surface::unlockAndPost()
1324 {
1325     if (mLockedBuffer == 0) {
1326         ALOGE("Surface::unlockAndPost failed, no locked buffer");
1327         return INVALID_OPERATION;
1328     }
1329 
1330     int fd = -1;
1331     status_t err = mLockedBuffer->unlockAsync(&fd);
1332     ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
1333 
1334     err = queueBuffer(mLockedBuffer.get(), fd);
1335     ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
1336             mLockedBuffer->handle, strerror(-err));
1337 
1338     mPostedBuffer = mLockedBuffer;
1339     mLockedBuffer = 0;
1340     return err;
1341 }
1342 
waitForNextFrame(uint64_t lastFrame,nsecs_t timeout)1343 bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) {
1344     Mutex::Autolock lock(mMutex);
1345     if (mNextFrameNumber > lastFrame) {
1346       return true;
1347     }
1348     return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK;
1349 }
1350 
getUniqueId(uint64_t * outId) const1351 status_t Surface::getUniqueId(uint64_t* outId) const {
1352     Mutex::Autolock lock(mMutex);
1353     return mGraphicBufferProducer->getUniqueId(outId);
1354 }
1355 
1356 namespace view {
1357 
writeToParcel(Parcel * parcel) const1358 status_t Surface::writeToParcel(Parcel* parcel) const {
1359     return writeToParcel(parcel, false);
1360 }
1361 
writeToParcel(Parcel * parcel,bool nameAlreadyWritten) const1362 status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const {
1363     if (parcel == nullptr) return BAD_VALUE;
1364 
1365     status_t res = OK;
1366 
1367     if (!nameAlreadyWritten) res = parcel->writeString16(name);
1368 
1369     if (res == OK) {
1370         res = parcel->writeStrongBinder(
1371                 IGraphicBufferProducer::asBinder(graphicBufferProducer));
1372     }
1373     return res;
1374 }
1375 
readFromParcel(const Parcel * parcel)1376 status_t Surface::readFromParcel(const Parcel* parcel) {
1377     return readFromParcel(parcel, false);
1378 }
1379 
readFromParcel(const Parcel * parcel,bool nameAlreadyRead)1380 status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) {
1381     if (parcel == nullptr) return BAD_VALUE;
1382 
1383     if (!nameAlreadyRead) {
1384         name = readMaybeEmptyString16(parcel);
1385     }
1386 
1387     sp<IBinder> binder;
1388 
1389     status_t res = parcel->readStrongBinder(&binder);
1390     if (res != OK) return res;
1391 
1392     graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder);
1393 
1394     return OK;
1395 }
1396 
readMaybeEmptyString16(const Parcel * parcel)1397 String16 Surface::readMaybeEmptyString16(const Parcel* parcel) {
1398     size_t len;
1399     const char16_t* str = parcel->readString16Inplace(&len);
1400     if (str != nullptr) {
1401         return String16(str, len);
1402     } else {
1403         return String16();
1404     }
1405 }
1406 
1407 } // namespace view
1408 
1409 }; // namespace android
1410