• 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     if (buf < 0 || buf >= NUM_BUFFER_SLOTS) {
310         ALOGE("dequeueBuffer: IGraphicBufferProducer returned invalid slot number %d", buf);
311         android_errorWriteLog(0x534e4554, "36991414"); // SafetyNet logging
312         return FAILED_TRANSACTION;
313     }
314 
315     Mutex::Autolock lock(mMutex);
316 
317     sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
318 
319     // this should never happen
320     ALOGE_IF(fence == NULL, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);
321 
322     if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
323         freeAllBuffers();
324     }
325 
326     if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
327         result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
328         if (result != NO_ERROR) {
329             ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
330             mGraphicBufferProducer->cancelBuffer(buf, fence);
331             return result;
332         }
333     }
334 
335     if (fence->isValid()) {
336         *fenceFd = fence->dup();
337         if (*fenceFd == -1) {
338             ALOGE("dequeueBuffer: error duping fence: %d", errno);
339             // dup() should never fail; something is badly wrong. Soldier on
340             // and hope for the best; the worst that should happen is some
341             // visible corruption that lasts until the next frame.
342         }
343     } else {
344         *fenceFd = -1;
345     }
346 
347     *buffer = gbuf.get();
348 
349     if (mSharedBufferMode && mAutoRefresh) {
350         mSharedBufferSlot = buf;
351         mSharedBufferHasBeenQueued = false;
352     } else if (mSharedBufferSlot == buf) {
353         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
354         mSharedBufferHasBeenQueued = false;
355     }
356 
357     return OK;
358 }
359 
cancelBuffer(android_native_buffer_t * buffer,int fenceFd)360 int Surface::cancelBuffer(android_native_buffer_t* buffer,
361         int fenceFd) {
362     ATRACE_CALL();
363     ALOGV("Surface::cancelBuffer");
364     Mutex::Autolock lock(mMutex);
365     int i = getSlotFromBufferLocked(buffer);
366     if (i < 0) {
367         if (fenceFd >= 0) {
368             close(fenceFd);
369         }
370         return i;
371     }
372     if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
373         if (fenceFd >= 0) {
374             close(fenceFd);
375         }
376         return OK;
377     }
378     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
379     mGraphicBufferProducer->cancelBuffer(i, fence);
380 
381     if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
382         mSharedBufferHasBeenQueued = true;
383     }
384 
385     return OK;
386 }
387 
getSlotFromBufferLocked(android_native_buffer_t * buffer) const388 int Surface::getSlotFromBufferLocked(
389         android_native_buffer_t* buffer) const {
390     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
391         if (mSlots[i].buffer != NULL &&
392                 mSlots[i].buffer->handle == buffer->handle) {
393             return i;
394         }
395     }
396     ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
397     return BAD_VALUE;
398 }
399 
lockBuffer_DEPRECATED(android_native_buffer_t * buffer)400 int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) {
401     ALOGV("Surface::lockBuffer");
402     Mutex::Autolock lock(mMutex);
403     return OK;
404 }
405 
queueBuffer(android_native_buffer_t * buffer,int fenceFd)406 int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
407     ATRACE_CALL();
408     ALOGV("Surface::queueBuffer");
409     Mutex::Autolock lock(mMutex);
410     int64_t timestamp;
411     bool isAutoTimestamp = false;
412 
413     if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
414         timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
415         isAutoTimestamp = true;
416         ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
417             timestamp / 1000000.f);
418     } else {
419         timestamp = mTimestamp;
420     }
421     int i = getSlotFromBufferLocked(buffer);
422     if (i < 0) {
423         if (fenceFd >= 0) {
424             close(fenceFd);
425         }
426         return i;
427     }
428     if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
429         if (fenceFd >= 0) {
430             close(fenceFd);
431         }
432         return OK;
433     }
434 
435 
436     // Make sure the crop rectangle is entirely inside the buffer.
437     Rect crop(Rect::EMPTY_RECT);
438     mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
439 
440     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
441     IGraphicBufferProducer::QueueBufferOutput output;
442     IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
443             mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform,
444             fence, mStickyTransform);
445 
446     if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) {
447         input.setSurfaceDamage(Region::INVALID_REGION);
448     } else {
449         // Here we do two things:
450         // 1) The surface damage was specified using the OpenGL ES convention of
451         //    the origin being in the bottom-left corner. Here we flip to the
452         //    convention that the rest of the system uses (top-left corner) by
453         //    subtracting all top/bottom coordinates from the buffer height.
454         // 2) If the buffer is coming in rotated (for example, because the EGL
455         //    implementation is reacting to the transform hint coming back from
456         //    SurfaceFlinger), the surface damage needs to be rotated the
457         //    opposite direction, since it was generated assuming an unrotated
458         //    buffer (the app doesn't know that the EGL implementation is
459         //    reacting to the transform hint behind its back). The
460         //    transformations in the switch statement below apply those
461         //    complementary rotations (e.g., if 90 degrees, rotate 270 degrees).
462 
463         int width = buffer->width;
464         int height = buffer->height;
465         bool rotated90 = (mTransform ^ mStickyTransform) &
466                 NATIVE_WINDOW_TRANSFORM_ROT_90;
467         if (rotated90) {
468             std::swap(width, height);
469         }
470 
471         Region flippedRegion;
472         for (auto rect : mDirtyRegion) {
473             int left = rect.left;
474             int right = rect.right;
475             int top = height - rect.bottom; // Flip from OpenGL convention
476             int bottom = height - rect.top; // Flip from OpenGL convention
477             switch (mTransform ^ mStickyTransform) {
478                 case NATIVE_WINDOW_TRANSFORM_ROT_90: {
479                     // Rotate 270 degrees
480                     Rect flippedRect{top, width - right, bottom, width - left};
481                     flippedRegion.orSelf(flippedRect);
482                     break;
483                 }
484                 case NATIVE_WINDOW_TRANSFORM_ROT_180: {
485                     // Rotate 180 degrees
486                     Rect flippedRect{width - right, height - bottom,
487                             width - left, height - top};
488                     flippedRegion.orSelf(flippedRect);
489                     break;
490                 }
491                 case NATIVE_WINDOW_TRANSFORM_ROT_270: {
492                     // Rotate 90 degrees
493                     Rect flippedRect{height - bottom, left,
494                             height - top, right};
495                     flippedRegion.orSelf(flippedRect);
496                     break;
497                 }
498                 default: {
499                     Rect flippedRect{left, top, right, bottom};
500                     flippedRegion.orSelf(flippedRect);
501                     break;
502                 }
503             }
504         }
505 
506         input.setSurfaceDamage(flippedRegion);
507     }
508 
509     nsecs_t now = systemTime();
510     status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
511     mLastQueueDuration = systemTime() - now;
512     if (err != OK)  {
513         ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
514     }
515 
516     uint32_t numPendingBuffers = 0;
517     uint32_t hint = 0;
518     output.deflate(&mDefaultWidth, &mDefaultHeight, &hint,
519             &numPendingBuffers, &mNextFrameNumber);
520 
521     // Disable transform hint if sticky transform is set.
522     if (mStickyTransform == 0) {
523         mTransformHint = hint;
524     }
525 
526     mConsumerRunningBehind = (numPendingBuffers >= 2);
527 
528     if (!mConnectedToCpu) {
529         // Clear surface damage back to full-buffer
530         mDirtyRegion = Region::INVALID_REGION;
531     }
532 
533     if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
534         mSharedBufferHasBeenQueued = true;
535     }
536 
537     mQueueBufferCondition.broadcast();
538 
539     return err;
540 }
541 
query(int what,int * value) const542 int Surface::query(int what, int* value) const {
543     ATRACE_CALL();
544     ALOGV("Surface::query");
545     { // scope for the lock
546         Mutex::Autolock lock(mMutex);
547         switch (what) {
548             case NATIVE_WINDOW_FORMAT:
549                 if (mReqFormat) {
550                     *value = static_cast<int>(mReqFormat);
551                     return NO_ERROR;
552                 }
553                 break;
554             case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
555                 sp<ISurfaceComposer> composer(
556                         ComposerService::getComposerService());
557                 if (composer->authenticateSurfaceTexture(mGraphicBufferProducer)) {
558                     *value = 1;
559                 } else {
560                     *value = 0;
561                 }
562                 return NO_ERROR;
563             }
564             case NATIVE_WINDOW_CONCRETE_TYPE:
565                 *value = NATIVE_WINDOW_SURFACE;
566                 return NO_ERROR;
567             case NATIVE_WINDOW_DEFAULT_WIDTH:
568                 *value = static_cast<int>(
569                         mUserWidth ? mUserWidth : mDefaultWidth);
570                 return NO_ERROR;
571             case NATIVE_WINDOW_DEFAULT_HEIGHT:
572                 *value = static_cast<int>(
573                         mUserHeight ? mUserHeight : mDefaultHeight);
574                 return NO_ERROR;
575             case NATIVE_WINDOW_TRANSFORM_HINT:
576                 *value = static_cast<int>(mTransformHint);
577                 return NO_ERROR;
578             case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
579                 status_t err = NO_ERROR;
580                 if (!mConsumerRunningBehind) {
581                     *value = 0;
582                 } else {
583                     err = mGraphicBufferProducer->query(what, value);
584                     if (err == NO_ERROR) {
585                         mConsumerRunningBehind = *value;
586                     }
587                 }
588                 return err;
589             }
590             case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: {
591                 int64_t durationUs = mLastDequeueDuration / 1000;
592                 *value = durationUs > std::numeric_limits<int>::max() ?
593                         std::numeric_limits<int>::max() :
594                         static_cast<int>(durationUs);
595                 return NO_ERROR;
596             }
597             case NATIVE_WINDOW_LAST_QUEUE_DURATION: {
598                 int64_t durationUs = mLastQueueDuration / 1000;
599                 *value = durationUs > std::numeric_limits<int>::max() ?
600                         std::numeric_limits<int>::max() :
601                         static_cast<int>(durationUs);
602                 return NO_ERROR;
603             }
604         }
605     }
606     return mGraphicBufferProducer->query(what, value);
607 }
608 
perform(int operation,va_list args)609 int Surface::perform(int operation, va_list args)
610 {
611     int res = NO_ERROR;
612     switch (operation) {
613     case NATIVE_WINDOW_CONNECT:
614         // deprecated. must return NO_ERROR.
615         break;
616     case NATIVE_WINDOW_DISCONNECT:
617         // deprecated. must return NO_ERROR.
618         break;
619     case NATIVE_WINDOW_SET_USAGE:
620         res = dispatchSetUsage(args);
621         break;
622     case NATIVE_WINDOW_SET_CROP:
623         res = dispatchSetCrop(args);
624         break;
625     case NATIVE_WINDOW_SET_BUFFER_COUNT:
626         res = dispatchSetBufferCount(args);
627         break;
628     case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
629         res = dispatchSetBuffersGeometry(args);
630         break;
631     case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
632         res = dispatchSetBuffersTransform(args);
633         break;
634     case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM:
635         res = dispatchSetBuffersStickyTransform(args);
636         break;
637     case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
638         res = dispatchSetBuffersTimestamp(args);
639         break;
640     case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
641         res = dispatchSetBuffersDimensions(args);
642         break;
643     case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
644         res = dispatchSetBuffersUserDimensions(args);
645         break;
646     case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
647         res = dispatchSetBuffersFormat(args);
648         break;
649     case NATIVE_WINDOW_LOCK:
650         res = dispatchLock(args);
651         break;
652     case NATIVE_WINDOW_UNLOCK_AND_POST:
653         res = dispatchUnlockAndPost(args);
654         break;
655     case NATIVE_WINDOW_SET_SCALING_MODE:
656         res = dispatchSetScalingMode(args);
657         break;
658     case NATIVE_WINDOW_API_CONNECT:
659         res = dispatchConnect(args);
660         break;
661     case NATIVE_WINDOW_API_DISCONNECT:
662         res = dispatchDisconnect(args);
663         break;
664     case NATIVE_WINDOW_SET_SIDEBAND_STREAM:
665         res = dispatchSetSidebandStream(args);
666         break;
667     case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
668         res = dispatchSetBuffersDataSpace(args);
669         break;
670     case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
671         res = dispatchSetSurfaceDamage(args);
672         break;
673     case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE:
674         res = dispatchSetSharedBufferMode(args);
675         break;
676     case NATIVE_WINDOW_SET_AUTO_REFRESH:
677         res = dispatchSetAutoRefresh(args);
678         break;
679     case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS:
680         res = dispatchGetFrameTimestamps(args);
681         break;
682     default:
683         res = NAME_NOT_FOUND;
684         break;
685     }
686     return res;
687 }
688 
dispatchConnect(va_list args)689 int Surface::dispatchConnect(va_list args) {
690     int api = va_arg(args, int);
691     return connect(api);
692 }
693 
dispatchDisconnect(va_list args)694 int Surface::dispatchDisconnect(va_list args) {
695     int api = va_arg(args, int);
696     return disconnect(api);
697 }
698 
dispatchSetUsage(va_list args)699 int Surface::dispatchSetUsage(va_list args) {
700     int usage = va_arg(args, int);
701     return setUsage(static_cast<uint32_t>(usage));
702 }
703 
dispatchSetCrop(va_list args)704 int Surface::dispatchSetCrop(va_list args) {
705     android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
706     return setCrop(reinterpret_cast<Rect const*>(rect));
707 }
708 
dispatchSetBufferCount(va_list args)709 int Surface::dispatchSetBufferCount(va_list args) {
710     size_t bufferCount = va_arg(args, size_t);
711     return setBufferCount(static_cast<int32_t>(bufferCount));
712 }
713 
dispatchSetBuffersGeometry(va_list args)714 int Surface::dispatchSetBuffersGeometry(va_list args) {
715     uint32_t width = va_arg(args, uint32_t);
716     uint32_t height = va_arg(args, uint32_t);
717     PixelFormat format = va_arg(args, PixelFormat);
718     int err = setBuffersDimensions(width, height);
719     if (err != 0) {
720         return err;
721     }
722     return setBuffersFormat(format);
723 }
724 
dispatchSetBuffersDimensions(va_list args)725 int Surface::dispatchSetBuffersDimensions(va_list args) {
726     uint32_t width = va_arg(args, uint32_t);
727     uint32_t height = va_arg(args, uint32_t);
728     return setBuffersDimensions(width, height);
729 }
730 
dispatchSetBuffersUserDimensions(va_list args)731 int Surface::dispatchSetBuffersUserDimensions(va_list args) {
732     uint32_t width = va_arg(args, uint32_t);
733     uint32_t height = va_arg(args, uint32_t);
734     return setBuffersUserDimensions(width, height);
735 }
736 
dispatchSetBuffersFormat(va_list args)737 int Surface::dispatchSetBuffersFormat(va_list args) {
738     PixelFormat format = va_arg(args, PixelFormat);
739     return setBuffersFormat(format);
740 }
741 
dispatchSetScalingMode(va_list args)742 int Surface::dispatchSetScalingMode(va_list args) {
743     int mode = va_arg(args, int);
744     return setScalingMode(mode);
745 }
746 
dispatchSetBuffersTransform(va_list args)747 int Surface::dispatchSetBuffersTransform(va_list args) {
748     uint32_t transform = va_arg(args, uint32_t);
749     return setBuffersTransform(transform);
750 }
751 
dispatchSetBuffersStickyTransform(va_list args)752 int Surface::dispatchSetBuffersStickyTransform(va_list args) {
753     uint32_t transform = va_arg(args, uint32_t);
754     return setBuffersStickyTransform(transform);
755 }
756 
dispatchSetBuffersTimestamp(va_list args)757 int Surface::dispatchSetBuffersTimestamp(va_list args) {
758     int64_t timestamp = va_arg(args, int64_t);
759     return setBuffersTimestamp(timestamp);
760 }
761 
dispatchLock(va_list args)762 int Surface::dispatchLock(va_list args) {
763     ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
764     ARect* inOutDirtyBounds = va_arg(args, ARect*);
765     return lock(outBuffer, inOutDirtyBounds);
766 }
767 
dispatchUnlockAndPost(va_list args)768 int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) {
769     return unlockAndPost();
770 }
771 
dispatchSetSidebandStream(va_list args)772 int Surface::dispatchSetSidebandStream(va_list args) {
773     native_handle_t* sH = va_arg(args, native_handle_t*);
774     sp<NativeHandle> sidebandHandle = NativeHandle::create(sH, false);
775     setSidebandStream(sidebandHandle);
776     return OK;
777 }
778 
dispatchSetBuffersDataSpace(va_list args)779 int Surface::dispatchSetBuffersDataSpace(va_list args) {
780     android_dataspace dataspace =
781             static_cast<android_dataspace>(va_arg(args, int));
782     return setBuffersDataSpace(dataspace);
783 }
784 
dispatchSetSurfaceDamage(va_list args)785 int Surface::dispatchSetSurfaceDamage(va_list args) {
786     android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
787     size_t numRects = va_arg(args, size_t);
788     setSurfaceDamage(rects, numRects);
789     return NO_ERROR;
790 }
791 
dispatchSetSharedBufferMode(va_list args)792 int Surface::dispatchSetSharedBufferMode(va_list args) {
793     bool sharedBufferMode = va_arg(args, int);
794     return setSharedBufferMode(sharedBufferMode);
795 }
796 
dispatchSetAutoRefresh(va_list args)797 int Surface::dispatchSetAutoRefresh(va_list args) {
798     bool autoRefresh = va_arg(args, int);
799     return setAutoRefresh(autoRefresh);
800 }
801 
dispatchGetFrameTimestamps(va_list args)802 int Surface::dispatchGetFrameTimestamps(va_list args) {
803     uint32_t framesAgo = va_arg(args, uint32_t);
804     nsecs_t* outPostedTime = va_arg(args, int64_t*);
805     nsecs_t* outAcquireTime = va_arg(args, int64_t*);
806     nsecs_t* outRefreshStartTime = va_arg(args, int64_t*);
807     nsecs_t* outGlCompositionDoneTime = va_arg(args, int64_t*);
808     nsecs_t* outDisplayRetireTime = va_arg(args, int64_t*);
809     nsecs_t* outReleaseTime = va_arg(args, int64_t*);
810     bool ret = getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo,
811             outPostedTime, outAcquireTime, outRefreshStartTime,
812             outGlCompositionDoneTime, outDisplayRetireTime, outReleaseTime);
813     return ret ? NO_ERROR : BAD_VALUE;
814 }
815 
connect(int api)816 int Surface::connect(int api) {
817     static sp<IProducerListener> listener = new DummyProducerListener();
818     return connect(api, listener);
819 }
820 
connect(int api,const sp<IProducerListener> & listener)821 int Surface::connect(int api, const sp<IProducerListener>& listener) {
822     ATRACE_CALL();
823     ALOGV("Surface::connect");
824     Mutex::Autolock lock(mMutex);
825     IGraphicBufferProducer::QueueBufferOutput output;
826     int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
827     if (err == NO_ERROR) {
828         uint32_t numPendingBuffers = 0;
829         uint32_t hint = 0;
830         output.deflate(&mDefaultWidth, &mDefaultHeight, &hint,
831                 &numPendingBuffers, &mNextFrameNumber);
832 
833         // Disable transform hint if sticky transform is set.
834         if (mStickyTransform == 0) {
835             mTransformHint = hint;
836         }
837 
838         mConsumerRunningBehind = (numPendingBuffers >= 2);
839     }
840     if (!err && api == NATIVE_WINDOW_API_CPU) {
841         mConnectedToCpu = true;
842         // Clear the dirty region in case we're switching from a non-CPU API
843         mDirtyRegion.clear();
844     } else if (!err) {
845         // Initialize the dirty region for tracking surface damage
846         mDirtyRegion = Region::INVALID_REGION;
847     }
848 
849     return err;
850 }
851 
852 
disconnect(int api,IGraphicBufferProducer::DisconnectMode mode)853 int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) {
854     ATRACE_CALL();
855     ALOGV("Surface::disconnect");
856     Mutex::Autolock lock(mMutex);
857     mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
858     mSharedBufferHasBeenQueued = false;
859     freeAllBuffers();
860     int err = mGraphicBufferProducer->disconnect(api, mode);
861     if (!err) {
862         mReqFormat = 0;
863         mReqWidth = 0;
864         mReqHeight = 0;
865         mReqUsage = 0;
866         mCrop.clear();
867         mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
868         mTransform = 0;
869         mStickyTransform = 0;
870 
871         if (api == NATIVE_WINDOW_API_CPU) {
872             mConnectedToCpu = false;
873         }
874     }
875     return err;
876 }
877 
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)878 int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
879         sp<Fence>* outFence) {
880     ATRACE_CALL();
881     ALOGV("Surface::detachNextBuffer");
882 
883     if (outBuffer == NULL || outFence == NULL) {
884         return BAD_VALUE;
885     }
886 
887     Mutex::Autolock lock(mMutex);
888 
889     sp<GraphicBuffer> buffer(NULL);
890     sp<Fence> fence(NULL);
891     status_t result = mGraphicBufferProducer->detachNextBuffer(
892             &buffer, &fence);
893     if (result != NO_ERROR) {
894         return result;
895     }
896 
897     *outBuffer = buffer;
898     if (fence != NULL && fence->isValid()) {
899         *outFence = fence;
900     } else {
901         *outFence = Fence::NO_FENCE;
902     }
903 
904     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
905         if (mSlots[i].buffer != NULL &&
906                 mSlots[i].buffer->handle == buffer->handle) {
907             mSlots[i].buffer = NULL;
908         }
909     }
910 
911     return NO_ERROR;
912 }
913 
attachBuffer(ANativeWindowBuffer * buffer)914 int Surface::attachBuffer(ANativeWindowBuffer* buffer)
915 {
916     ATRACE_CALL();
917     ALOGV("Surface::attachBuffer");
918 
919     Mutex::Autolock lock(mMutex);
920 
921     sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
922     uint32_t priorGeneration = graphicBuffer->mGenerationNumber;
923     graphicBuffer->mGenerationNumber = mGenerationNumber;
924     int32_t attachedSlot = -1;
925     status_t result = mGraphicBufferProducer->attachBuffer(
926             &attachedSlot, graphicBuffer);
927     if (result != NO_ERROR) {
928         ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result);
929         graphicBuffer->mGenerationNumber = priorGeneration;
930         return result;
931     }
932     mSlots[attachedSlot].buffer = graphicBuffer;
933 
934     return NO_ERROR;
935 }
936 
setUsage(uint32_t reqUsage)937 int Surface::setUsage(uint32_t reqUsage)
938 {
939     ALOGV("Surface::setUsage");
940     Mutex::Autolock lock(mMutex);
941     if (reqUsage != mReqUsage) {
942         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
943     }
944     mReqUsage = reqUsage;
945     return OK;
946 }
947 
setCrop(Rect const * rect)948 int Surface::setCrop(Rect const* rect)
949 {
950     ATRACE_CALL();
951 
952     Rect realRect(Rect::EMPTY_RECT);
953     if (rect == NULL || rect->isEmpty()) {
954         realRect.clear();
955     } else {
956         realRect = *rect;
957     }
958 
959     ALOGV("Surface::setCrop rect=[%d %d %d %d]",
960             realRect.left, realRect.top, realRect.right, realRect.bottom);
961 
962     Mutex::Autolock lock(mMutex);
963     mCrop = realRect;
964     return NO_ERROR;
965 }
966 
setBufferCount(int bufferCount)967 int Surface::setBufferCount(int bufferCount)
968 {
969     ATRACE_CALL();
970     ALOGV("Surface::setBufferCount");
971     Mutex::Autolock lock(mMutex);
972 
973     status_t err = NO_ERROR;
974     if (bufferCount == 0) {
975         err = mGraphicBufferProducer->setMaxDequeuedBufferCount(1);
976     } else {
977         int minUndequeuedBuffers = 0;
978         err = mGraphicBufferProducer->query(
979                 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers);
980         if (err == NO_ERROR) {
981             err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
982                     bufferCount - minUndequeuedBuffers);
983         }
984     }
985 
986     ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
987              bufferCount, strerror(-err));
988 
989     return err;
990 }
991 
setMaxDequeuedBufferCount(int maxDequeuedBuffers)992 int Surface::setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
993     ATRACE_CALL();
994     ALOGV("Surface::setMaxDequeuedBufferCount");
995     Mutex::Autolock lock(mMutex);
996 
997     status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
998             maxDequeuedBuffers);
999     ALOGE_IF(err, "IGraphicBufferProducer::setMaxDequeuedBufferCount(%d) "
1000             "returned %s", maxDequeuedBuffers, strerror(-err));
1001 
1002     return err;
1003 }
1004 
setAsyncMode(bool async)1005 int Surface::setAsyncMode(bool async) {
1006     ATRACE_CALL();
1007     ALOGV("Surface::setAsyncMode");
1008     Mutex::Autolock lock(mMutex);
1009 
1010     status_t err = mGraphicBufferProducer->setAsyncMode(async);
1011     ALOGE_IF(err, "IGraphicBufferProducer::setAsyncMode(%d) returned %s",
1012             async, strerror(-err));
1013 
1014     return err;
1015 }
1016 
setSharedBufferMode(bool sharedBufferMode)1017 int Surface::setSharedBufferMode(bool sharedBufferMode) {
1018     ATRACE_CALL();
1019     ALOGV("Surface::setSharedBufferMode (%d)", sharedBufferMode);
1020     Mutex::Autolock lock(mMutex);
1021 
1022     status_t err = mGraphicBufferProducer->setSharedBufferMode(
1023             sharedBufferMode);
1024     if (err == NO_ERROR) {
1025         mSharedBufferMode = sharedBufferMode;
1026     }
1027     ALOGE_IF(err, "IGraphicBufferProducer::setSharedBufferMode(%d) returned"
1028             "%s", sharedBufferMode, strerror(-err));
1029 
1030     return err;
1031 }
1032 
setAutoRefresh(bool autoRefresh)1033 int Surface::setAutoRefresh(bool autoRefresh) {
1034     ATRACE_CALL();
1035     ALOGV("Surface::setAutoRefresh (%d)", autoRefresh);
1036     Mutex::Autolock lock(mMutex);
1037 
1038     status_t err = mGraphicBufferProducer->setAutoRefresh(autoRefresh);
1039     if (err == NO_ERROR) {
1040         mAutoRefresh = autoRefresh;
1041     }
1042     ALOGE_IF(err, "IGraphicBufferProducer::setAutoRefresh(%d) returned %s",
1043             autoRefresh, strerror(-err));
1044     return err;
1045 }
1046 
setBuffersDimensions(uint32_t width,uint32_t height)1047 int Surface::setBuffersDimensions(uint32_t width, uint32_t height)
1048 {
1049     ATRACE_CALL();
1050     ALOGV("Surface::setBuffersDimensions");
1051 
1052     if ((width && !height) || (!width && height))
1053         return BAD_VALUE;
1054 
1055     Mutex::Autolock lock(mMutex);
1056     if (width != mReqWidth || height != mReqHeight) {
1057         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1058     }
1059     mReqWidth = width;
1060     mReqHeight = height;
1061     return NO_ERROR;
1062 }
1063 
setBuffersUserDimensions(uint32_t width,uint32_t height)1064 int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height)
1065 {
1066     ATRACE_CALL();
1067     ALOGV("Surface::setBuffersUserDimensions");
1068 
1069     if ((width && !height) || (!width && height))
1070         return BAD_VALUE;
1071 
1072     Mutex::Autolock lock(mMutex);
1073     if (width != mUserWidth || height != mUserHeight) {
1074         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1075     }
1076     mUserWidth = width;
1077     mUserHeight = height;
1078     return NO_ERROR;
1079 }
1080 
setBuffersFormat(PixelFormat format)1081 int Surface::setBuffersFormat(PixelFormat format)
1082 {
1083     ALOGV("Surface::setBuffersFormat");
1084 
1085     Mutex::Autolock lock(mMutex);
1086     if (format != mReqFormat) {
1087         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1088     }
1089     mReqFormat = format;
1090     return NO_ERROR;
1091 }
1092 
setScalingMode(int mode)1093 int Surface::setScalingMode(int mode)
1094 {
1095     ATRACE_CALL();
1096     ALOGV("Surface::setScalingMode(%d)", mode);
1097 
1098     switch (mode) {
1099         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
1100         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
1101         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
1102         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
1103             break;
1104         default:
1105             ALOGE("unknown scaling mode: %d", mode);
1106             return BAD_VALUE;
1107     }
1108 
1109     Mutex::Autolock lock(mMutex);
1110     mScalingMode = mode;
1111     return NO_ERROR;
1112 }
1113 
setBuffersTransform(uint32_t transform)1114 int Surface::setBuffersTransform(uint32_t transform)
1115 {
1116     ATRACE_CALL();
1117     ALOGV("Surface::setBuffersTransform");
1118     Mutex::Autolock lock(mMutex);
1119     mTransform = transform;
1120     return NO_ERROR;
1121 }
1122 
setBuffersStickyTransform(uint32_t transform)1123 int Surface::setBuffersStickyTransform(uint32_t transform)
1124 {
1125     ATRACE_CALL();
1126     ALOGV("Surface::setBuffersStickyTransform");
1127     Mutex::Autolock lock(mMutex);
1128     mStickyTransform = transform;
1129     return NO_ERROR;
1130 }
1131 
setBuffersTimestamp(int64_t timestamp)1132 int Surface::setBuffersTimestamp(int64_t timestamp)
1133 {
1134     ALOGV("Surface::setBuffersTimestamp");
1135     Mutex::Autolock lock(mMutex);
1136     mTimestamp = timestamp;
1137     return NO_ERROR;
1138 }
1139 
setBuffersDataSpace(android_dataspace dataSpace)1140 int Surface::setBuffersDataSpace(android_dataspace dataSpace)
1141 {
1142     ALOGV("Surface::setBuffersDataSpace");
1143     Mutex::Autolock lock(mMutex);
1144     mDataSpace = dataSpace;
1145     return NO_ERROR;
1146 }
1147 
freeAllBuffers()1148 void Surface::freeAllBuffers() {
1149     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
1150         mSlots[i].buffer = 0;
1151     }
1152 }
1153 
setSurfaceDamage(android_native_rect_t * rects,size_t numRects)1154 void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) {
1155     ATRACE_CALL();
1156     ALOGV("Surface::setSurfaceDamage");
1157     Mutex::Autolock lock(mMutex);
1158 
1159     if (mConnectedToCpu || numRects == 0) {
1160         mDirtyRegion = Region::INVALID_REGION;
1161         return;
1162     }
1163 
1164     mDirtyRegion.clear();
1165     for (size_t r = 0; r < numRects; ++r) {
1166         // We intentionally flip top and bottom here, since because they're
1167         // specified with a bottom-left origin, top > bottom, which fails
1168         // validation in the Region class. We will fix this up when we flip to a
1169         // top-left origin in queueBuffer.
1170         Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top);
1171         mDirtyRegion.orSelf(rect);
1172     }
1173 }
1174 
1175 // ----------------------------------------------------------------------
1176 // the lock/unlock APIs must be used from the same thread
1177 
copyBlt(const sp<GraphicBuffer> & dst,const sp<GraphicBuffer> & src,const Region & reg)1178 static status_t copyBlt(
1179         const sp<GraphicBuffer>& dst,
1180         const sp<GraphicBuffer>& src,
1181         const Region& reg)
1182 {
1183     // src and dst with, height and format must be identical. no verification
1184     // is done here.
1185     status_t err;
1186     uint8_t* src_bits = NULL;
1187     err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(),
1188             reinterpret_cast<void**>(&src_bits));
1189     ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
1190 
1191     uint8_t* dst_bits = NULL;
1192     err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(),
1193             reinterpret_cast<void**>(&dst_bits));
1194     ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
1195 
1196     Region::const_iterator head(reg.begin());
1197     Region::const_iterator tail(reg.end());
1198     if (head != tail && src_bits && dst_bits) {
1199         const size_t bpp = bytesPerPixel(src->format);
1200         const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp;
1201         const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp;
1202 
1203         while (head != tail) {
1204             const Rect& r(*head++);
1205             int32_t h = r.height();
1206             if (h <= 0) continue;
1207             size_t size = static_cast<uint32_t>(r.width()) * bpp;
1208             uint8_t const * s = src_bits +
1209                     static_cast<uint32_t>(r.left + src->stride * r.top) * bpp;
1210             uint8_t       * d = dst_bits +
1211                     static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp;
1212             if (dbpr==sbpr && size==sbpr) {
1213                 size *= static_cast<size_t>(h);
1214                 h = 1;
1215             }
1216             do {
1217                 memcpy(d, s, size);
1218                 d += dbpr;
1219                 s += sbpr;
1220             } while (--h > 0);
1221         }
1222     }
1223 
1224     if (src_bits)
1225         src->unlock();
1226 
1227     if (dst_bits)
1228         dst->unlock();
1229 
1230     return err;
1231 }
1232 
1233 // ----------------------------------------------------------------------------
1234 
lock(ANativeWindow_Buffer * outBuffer,ARect * inOutDirtyBounds)1235 status_t Surface::lock(
1236         ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
1237 {
1238     if (mLockedBuffer != 0) {
1239         ALOGE("Surface::lock failed, already locked");
1240         return INVALID_OPERATION;
1241     }
1242 
1243     if (!mConnectedToCpu) {
1244         int err = Surface::connect(NATIVE_WINDOW_API_CPU);
1245         if (err) {
1246             return err;
1247         }
1248         // we're intending to do software rendering from this point
1249         setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
1250     }
1251 
1252     ANativeWindowBuffer* out;
1253     int fenceFd = -1;
1254     status_t err = dequeueBuffer(&out, &fenceFd);
1255     ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
1256     if (err == NO_ERROR) {
1257         sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
1258         const Rect bounds(backBuffer->width, backBuffer->height);
1259 
1260         Region newDirtyRegion;
1261         if (inOutDirtyBounds) {
1262             newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
1263             newDirtyRegion.andSelf(bounds);
1264         } else {
1265             newDirtyRegion.set(bounds);
1266         }
1267 
1268         // figure out if we can copy the frontbuffer back
1269         const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
1270         const bool canCopyBack = (frontBuffer != 0 &&
1271                 backBuffer->width  == frontBuffer->width &&
1272                 backBuffer->height == frontBuffer->height &&
1273                 backBuffer->format == frontBuffer->format);
1274 
1275         if (canCopyBack) {
1276             // copy the area that is invalid and not repainted this round
1277             const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
1278             if (!copyback.isEmpty())
1279                 copyBlt(backBuffer, frontBuffer, copyback);
1280         } else {
1281             // if we can't copy-back anything, modify the user's dirty
1282             // region to make sure they redraw the whole buffer
1283             newDirtyRegion.set(bounds);
1284             mDirtyRegion.clear();
1285             Mutex::Autolock lock(mMutex);
1286             for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
1287                 mSlots[i].dirtyRegion.clear();
1288             }
1289         }
1290 
1291 
1292         { // scope for the lock
1293             Mutex::Autolock lock(mMutex);
1294             int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
1295             if (backBufferSlot >= 0) {
1296                 Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
1297                 mDirtyRegion.subtract(dirtyRegion);
1298                 dirtyRegion = newDirtyRegion;
1299             }
1300         }
1301 
1302         mDirtyRegion.orSelf(newDirtyRegion);
1303         if (inOutDirtyBounds) {
1304             *inOutDirtyBounds = newDirtyRegion.getBounds();
1305         }
1306 
1307         void* vaddr;
1308         status_t res = backBuffer->lockAsync(
1309                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1310                 newDirtyRegion.bounds(), &vaddr, fenceFd);
1311 
1312         ALOGW_IF(res, "failed locking buffer (handle = %p)",
1313                 backBuffer->handle);
1314 
1315         if (res != 0) {
1316             err = INVALID_OPERATION;
1317         } else {
1318             mLockedBuffer = backBuffer;
1319             outBuffer->width  = backBuffer->width;
1320             outBuffer->height = backBuffer->height;
1321             outBuffer->stride = backBuffer->stride;
1322             outBuffer->format = backBuffer->format;
1323             outBuffer->bits   = vaddr;
1324         }
1325     }
1326     return err;
1327 }
1328 
unlockAndPost()1329 status_t Surface::unlockAndPost()
1330 {
1331     if (mLockedBuffer == 0) {
1332         ALOGE("Surface::unlockAndPost failed, no locked buffer");
1333         return INVALID_OPERATION;
1334     }
1335 
1336     int fd = -1;
1337     status_t err = mLockedBuffer->unlockAsync(&fd);
1338     ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
1339 
1340     err = queueBuffer(mLockedBuffer.get(), fd);
1341     ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
1342             mLockedBuffer->handle, strerror(-err));
1343 
1344     mPostedBuffer = mLockedBuffer;
1345     mLockedBuffer = 0;
1346     return err;
1347 }
1348 
waitForNextFrame(uint64_t lastFrame,nsecs_t timeout)1349 bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) {
1350     Mutex::Autolock lock(mMutex);
1351     if (mNextFrameNumber > lastFrame) {
1352       return true;
1353     }
1354     return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK;
1355 }
1356 
getUniqueId(uint64_t * outId) const1357 status_t Surface::getUniqueId(uint64_t* outId) const {
1358     Mutex::Autolock lock(mMutex);
1359     return mGraphicBufferProducer->getUniqueId(outId);
1360 }
1361 
1362 namespace view {
1363 
writeToParcel(Parcel * parcel) const1364 status_t Surface::writeToParcel(Parcel* parcel) const {
1365     return writeToParcel(parcel, false);
1366 }
1367 
writeToParcel(Parcel * parcel,bool nameAlreadyWritten) const1368 status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const {
1369     if (parcel == nullptr) return BAD_VALUE;
1370 
1371     status_t res = OK;
1372 
1373     if (!nameAlreadyWritten) {
1374         res = parcel->writeString16(name);
1375         if (res != OK) return res;
1376 
1377         /* isSingleBuffered defaults to no */
1378         res = parcel->writeInt32(0);
1379         if (res != OK) return res;
1380     }
1381 
1382     res = parcel->writeStrongBinder(
1383             IGraphicBufferProducer::asBinder(graphicBufferProducer));
1384 
1385     return res;
1386 }
1387 
readFromParcel(const Parcel * parcel)1388 status_t Surface::readFromParcel(const Parcel* parcel) {
1389     return readFromParcel(parcel, false);
1390 }
1391 
readFromParcel(const Parcel * parcel,bool nameAlreadyRead)1392 status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) {
1393     if (parcel == nullptr) return BAD_VALUE;
1394 
1395     status_t res = OK;
1396     if (!nameAlreadyRead) {
1397         name = readMaybeEmptyString16(parcel);
1398         // Discard this for now
1399         int isSingleBuffered;
1400         res = parcel->readInt32(&isSingleBuffered);
1401         if (res != OK) {
1402             return res;
1403         }
1404     }
1405 
1406     sp<IBinder> binder;
1407 
1408     res = parcel->readStrongBinder(&binder);
1409     if (res != OK) return res;
1410 
1411     graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder);
1412 
1413     return OK;
1414 }
1415 
readMaybeEmptyString16(const Parcel * parcel)1416 String16 Surface::readMaybeEmptyString16(const Parcel* parcel) {
1417     size_t len;
1418     const char16_t* str = parcel->readString16Inplace(&len);
1419     if (str != nullptr) {
1420         return String16(str, len);
1421     } else {
1422         return String16();
1423     }
1424 }
1425 
1426 } // namespace view
1427 
1428 }; // namespace android
1429