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