• 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 
28 #include <ui/Fence.h>
29 
30 #include <gui/ISurfaceComposer.h>
31 #include <gui/SurfaceComposerClient.h>
32 #include <gui/GLConsumer.h>
33 #include <gui/Surface.h>
34 
35 #include <private/gui/ComposerService.h>
36 
37 namespace android {
38 
Surface(const sp<IGraphicBufferProducer> & bufferProducer,bool controlledByApp)39 Surface::Surface(
40         const sp<IGraphicBufferProducer>& bufferProducer,
41         bool controlledByApp)
42     : mGraphicBufferProducer(bufferProducer)
43 {
44     // Initialize the ANativeWindow function pointers.
45     ANativeWindow::setSwapInterval  = hook_setSwapInterval;
46     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
47     ANativeWindow::cancelBuffer     = hook_cancelBuffer;
48     ANativeWindow::queueBuffer      = hook_queueBuffer;
49     ANativeWindow::query            = hook_query;
50     ANativeWindow::perform          = hook_perform;
51 
52     ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
53     ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;
54     ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;
55     ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;
56 
57     const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
58     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
59 
60     mReqWidth = 0;
61     mReqHeight = 0;
62     mReqFormat = 0;
63     mReqUsage = 0;
64     mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
65     mCrop.clear();
66     mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
67     mTransform = 0;
68     mDefaultWidth = 0;
69     mDefaultHeight = 0;
70     mUserWidth = 0;
71     mUserHeight = 0;
72     mTransformHint = 0;
73     mConsumerRunningBehind = false;
74     mConnectedToCpu = false;
75     mProducerControlledByApp = controlledByApp;
76     mSwapIntervalZero = false;
77 }
78 
~Surface()79 Surface::~Surface() {
80     if (mConnectedToCpu) {
81         Surface::disconnect(NATIVE_WINDOW_API_CPU);
82     }
83 }
84 
getIGraphicBufferProducer() const85 sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const {
86     return mGraphicBufferProducer;
87 }
88 
hook_setSwapInterval(ANativeWindow * window,int interval)89 int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
90     Surface* c = getSelf(window);
91     return c->setSwapInterval(interval);
92 }
93 
hook_dequeueBuffer(ANativeWindow * window,ANativeWindowBuffer ** buffer,int * fenceFd)94 int Surface::hook_dequeueBuffer(ANativeWindow* window,
95         ANativeWindowBuffer** buffer, int* fenceFd) {
96     Surface* c = getSelf(window);
97     return c->dequeueBuffer(buffer, fenceFd);
98 }
99 
hook_cancelBuffer(ANativeWindow * window,ANativeWindowBuffer * buffer,int fenceFd)100 int Surface::hook_cancelBuffer(ANativeWindow* window,
101         ANativeWindowBuffer* buffer, int fenceFd) {
102     Surface* c = getSelf(window);
103     return c->cancelBuffer(buffer, fenceFd);
104 }
105 
hook_queueBuffer(ANativeWindow * window,ANativeWindowBuffer * buffer,int fenceFd)106 int Surface::hook_queueBuffer(ANativeWindow* window,
107         ANativeWindowBuffer* buffer, int fenceFd) {
108     Surface* c = getSelf(window);
109     return c->queueBuffer(buffer, fenceFd);
110 }
111 
hook_dequeueBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer ** buffer)112 int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
113         ANativeWindowBuffer** buffer) {
114     Surface* c = getSelf(window);
115     ANativeWindowBuffer* buf;
116     int fenceFd = -1;
117     int result = c->dequeueBuffer(&buf, &fenceFd);
118     sp<Fence> fence(new Fence(fenceFd));
119     int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
120     if (waitResult != OK) {
121         ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d",
122                 waitResult);
123         c->cancelBuffer(buf, -1);
124         return waitResult;
125     }
126     *buffer = buf;
127     return result;
128 }
129 
hook_cancelBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer * buffer)130 int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
131         ANativeWindowBuffer* buffer) {
132     Surface* c = getSelf(window);
133     return c->cancelBuffer(buffer, -1);
134 }
135 
hook_lockBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer * buffer)136 int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
137         ANativeWindowBuffer* buffer) {
138     Surface* c = getSelf(window);
139     return c->lockBuffer_DEPRECATED(buffer);
140 }
141 
hook_queueBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer * buffer)142 int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
143         ANativeWindowBuffer* buffer) {
144     Surface* c = getSelf(window);
145     return c->queueBuffer(buffer, -1);
146 }
147 
hook_query(const ANativeWindow * window,int what,int * value)148 int Surface::hook_query(const ANativeWindow* window,
149                                 int what, int* value) {
150     const Surface* c = getSelf(window);
151     return c->query(what, value);
152 }
153 
hook_perform(ANativeWindow * window,int operation,...)154 int Surface::hook_perform(ANativeWindow* window, int operation, ...) {
155     va_list args;
156     va_start(args, operation);
157     Surface* c = getSelf(window);
158     return c->perform(operation, args);
159 }
160 
setSwapInterval(int interval)161 int Surface::setSwapInterval(int interval) {
162     ATRACE_CALL();
163     // EGL specification states:
164     //  interval is silently clamped to minimum and maximum implementation
165     //  dependent values before being stored.
166 
167     if (interval < minSwapInterval)
168         interval = minSwapInterval;
169 
170     if (interval > maxSwapInterval)
171         interval = maxSwapInterval;
172 
173     mSwapIntervalZero = (interval == 0);
174 
175     return NO_ERROR;
176 }
177 
dequeueBuffer(android_native_buffer_t ** buffer,int * fenceFd)178 int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
179     ATRACE_CALL();
180     ALOGV("Surface::dequeueBuffer");
181     Mutex::Autolock lock(mMutex);
182     int buf = -1;
183     int reqW = mReqWidth ? mReqWidth : mUserWidth;
184     int reqH = mReqHeight ? mReqHeight : mUserHeight;
185     sp<Fence> fence;
186     status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, mSwapIntervalZero,
187             reqW, reqH, mReqFormat, mReqUsage);
188     if (result < 0) {
189         ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d)"
190              "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,
191              result);
192         return result;
193     }
194     sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
195 
196     // this should never happen
197     ALOGE_IF(fence == NULL, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);
198 
199     if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
200         freeAllBuffers();
201     }
202 
203     if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
204         result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
205         if (result != NO_ERROR) {
206             ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
207             return result;
208         }
209     }
210 
211     if (fence->isValid()) {
212         *fenceFd = fence->dup();
213         if (*fenceFd == -1) {
214             ALOGE("dequeueBuffer: error duping fence: %d", errno);
215             // dup() should never fail; something is badly wrong. Soldier on
216             // and hope for the best; the worst that should happen is some
217             // visible corruption that lasts until the next frame.
218         }
219     } else {
220         *fenceFd = -1;
221     }
222 
223     *buffer = gbuf.get();
224     return OK;
225 }
226 
cancelBuffer(android_native_buffer_t * buffer,int fenceFd)227 int Surface::cancelBuffer(android_native_buffer_t* buffer,
228         int fenceFd) {
229     ATRACE_CALL();
230     ALOGV("Surface::cancelBuffer");
231     Mutex::Autolock lock(mMutex);
232     int i = getSlotFromBufferLocked(buffer);
233     if (i < 0) {
234         return i;
235     }
236     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
237     mGraphicBufferProducer->cancelBuffer(i, fence);
238     return OK;
239 }
240 
getSlotFromBufferLocked(android_native_buffer_t * buffer) const241 int Surface::getSlotFromBufferLocked(
242         android_native_buffer_t* buffer) const {
243     bool dumpedState = false;
244     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
245         if (mSlots[i].buffer != NULL &&
246                 mSlots[i].buffer->handle == buffer->handle) {
247             return i;
248         }
249     }
250     ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
251     return BAD_VALUE;
252 }
253 
lockBuffer_DEPRECATED(android_native_buffer_t * buffer)254 int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer) {
255     ALOGV("Surface::lockBuffer");
256     Mutex::Autolock lock(mMutex);
257     return OK;
258 }
259 
queueBuffer(android_native_buffer_t * buffer,int fenceFd)260 int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
261     ATRACE_CALL();
262     ALOGV("Surface::queueBuffer");
263     Mutex::Autolock lock(mMutex);
264     int64_t timestamp;
265     bool isAutoTimestamp = false;
266     if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
267         timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
268         isAutoTimestamp = true;
269         ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
270             timestamp / 1000000.f);
271     } else {
272         timestamp = mTimestamp;
273     }
274     int i = getSlotFromBufferLocked(buffer);
275     if (i < 0) {
276         return i;
277     }
278 
279 
280     // Make sure the crop rectangle is entirely inside the buffer.
281     Rect crop;
282     mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
283 
284     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
285     IGraphicBufferProducer::QueueBufferOutput output;
286     IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
287             crop, mScalingMode, mTransform, mSwapIntervalZero, fence);
288     status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
289     if (err != OK)  {
290         ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
291     }
292     uint32_t numPendingBuffers = 0;
293     output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
294             &numPendingBuffers);
295 
296     mConsumerRunningBehind = (numPendingBuffers >= 2);
297 
298     return err;
299 }
300 
query(int what,int * value) const301 int Surface::query(int what, int* value) const {
302     ATRACE_CALL();
303     ALOGV("Surface::query");
304     { // scope for the lock
305         Mutex::Autolock lock(mMutex);
306         switch (what) {
307             case NATIVE_WINDOW_FORMAT:
308                 if (mReqFormat) {
309                     *value = mReqFormat;
310                     return NO_ERROR;
311                 }
312                 break;
313             case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
314                 sp<ISurfaceComposer> composer(
315                         ComposerService::getComposerService());
316                 if (composer->authenticateSurfaceTexture(mGraphicBufferProducer)) {
317                     *value = 1;
318                 } else {
319                     *value = 0;
320                 }
321                 return NO_ERROR;
322             }
323             case NATIVE_WINDOW_CONCRETE_TYPE:
324                 *value = NATIVE_WINDOW_SURFACE;
325                 return NO_ERROR;
326             case NATIVE_WINDOW_DEFAULT_WIDTH:
327                 *value = mUserWidth ? mUserWidth : mDefaultWidth;
328                 return NO_ERROR;
329             case NATIVE_WINDOW_DEFAULT_HEIGHT:
330                 *value = mUserHeight ? mUserHeight : mDefaultHeight;
331                 return NO_ERROR;
332             case NATIVE_WINDOW_TRANSFORM_HINT:
333                 *value = mTransformHint;
334                 return NO_ERROR;
335             case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
336                 status_t err = NO_ERROR;
337                 if (!mConsumerRunningBehind) {
338                     *value = 0;
339                 } else {
340                     err = mGraphicBufferProducer->query(what, value);
341                     if (err == NO_ERROR) {
342                         mConsumerRunningBehind = *value;
343                     }
344                 }
345                 return err;
346             }
347         }
348     }
349     return mGraphicBufferProducer->query(what, value);
350 }
351 
perform(int operation,va_list args)352 int Surface::perform(int operation, va_list args)
353 {
354     int res = NO_ERROR;
355     switch (operation) {
356     case NATIVE_WINDOW_CONNECT:
357         // deprecated. must return NO_ERROR.
358         break;
359     case NATIVE_WINDOW_DISCONNECT:
360         // deprecated. must return NO_ERROR.
361         break;
362     case NATIVE_WINDOW_SET_USAGE:
363         res = dispatchSetUsage(args);
364         break;
365     case NATIVE_WINDOW_SET_CROP:
366         res = dispatchSetCrop(args);
367         break;
368     case NATIVE_WINDOW_SET_BUFFER_COUNT:
369         res = dispatchSetBufferCount(args);
370         break;
371     case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
372         res = dispatchSetBuffersGeometry(args);
373         break;
374     case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
375         res = dispatchSetBuffersTransform(args);
376         break;
377     case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
378         res = dispatchSetBuffersTimestamp(args);
379         break;
380     case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
381         res = dispatchSetBuffersDimensions(args);
382         break;
383     case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
384         res = dispatchSetBuffersUserDimensions(args);
385         break;
386     case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
387         res = dispatchSetBuffersFormat(args);
388         break;
389     case NATIVE_WINDOW_LOCK:
390         res = dispatchLock(args);
391         break;
392     case NATIVE_WINDOW_UNLOCK_AND_POST:
393         res = dispatchUnlockAndPost(args);
394         break;
395     case NATIVE_WINDOW_SET_SCALING_MODE:
396         res = dispatchSetScalingMode(args);
397         break;
398     case NATIVE_WINDOW_API_CONNECT:
399         res = dispatchConnect(args);
400         break;
401     case NATIVE_WINDOW_API_DISCONNECT:
402         res = dispatchDisconnect(args);
403         break;
404     default:
405         res = NAME_NOT_FOUND;
406         break;
407     }
408     return res;
409 }
410 
dispatchConnect(va_list args)411 int Surface::dispatchConnect(va_list args) {
412     int api = va_arg(args, int);
413     return connect(api);
414 }
415 
dispatchDisconnect(va_list args)416 int Surface::dispatchDisconnect(va_list args) {
417     int api = va_arg(args, int);
418     return disconnect(api);
419 }
420 
dispatchSetUsage(va_list args)421 int Surface::dispatchSetUsage(va_list args) {
422     int usage = va_arg(args, int);
423     return setUsage(usage);
424 }
425 
dispatchSetCrop(va_list args)426 int Surface::dispatchSetCrop(va_list args) {
427     android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
428     return setCrop(reinterpret_cast<Rect const*>(rect));
429 }
430 
dispatchSetBufferCount(va_list args)431 int Surface::dispatchSetBufferCount(va_list args) {
432     size_t bufferCount = va_arg(args, size_t);
433     return setBufferCount(bufferCount);
434 }
435 
dispatchSetBuffersGeometry(va_list args)436 int Surface::dispatchSetBuffersGeometry(va_list args) {
437     int w = va_arg(args, int);
438     int h = va_arg(args, int);
439     int f = va_arg(args, int);
440     int err = setBuffersDimensions(w, h);
441     if (err != 0) {
442         return err;
443     }
444     return setBuffersFormat(f);
445 }
446 
dispatchSetBuffersDimensions(va_list args)447 int Surface::dispatchSetBuffersDimensions(va_list args) {
448     int w = va_arg(args, int);
449     int h = va_arg(args, int);
450     return setBuffersDimensions(w, h);
451 }
452 
dispatchSetBuffersUserDimensions(va_list args)453 int Surface::dispatchSetBuffersUserDimensions(va_list args) {
454     int w = va_arg(args, int);
455     int h = va_arg(args, int);
456     return setBuffersUserDimensions(w, h);
457 }
458 
dispatchSetBuffersFormat(va_list args)459 int Surface::dispatchSetBuffersFormat(va_list args) {
460     int f = va_arg(args, int);
461     return setBuffersFormat(f);
462 }
463 
dispatchSetScalingMode(va_list args)464 int Surface::dispatchSetScalingMode(va_list args) {
465     int m = va_arg(args, int);
466     return setScalingMode(m);
467 }
468 
dispatchSetBuffersTransform(va_list args)469 int Surface::dispatchSetBuffersTransform(va_list args) {
470     int transform = va_arg(args, int);
471     return setBuffersTransform(transform);
472 }
473 
dispatchSetBuffersTimestamp(va_list args)474 int Surface::dispatchSetBuffersTimestamp(va_list args) {
475     int64_t timestamp = va_arg(args, int64_t);
476     return setBuffersTimestamp(timestamp);
477 }
478 
dispatchLock(va_list args)479 int Surface::dispatchLock(va_list args) {
480     ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
481     ARect* inOutDirtyBounds = va_arg(args, ARect*);
482     return lock(outBuffer, inOutDirtyBounds);
483 }
484 
dispatchUnlockAndPost(va_list args)485 int Surface::dispatchUnlockAndPost(va_list args) {
486     return unlockAndPost();
487 }
488 
489 
connect(int api)490 int Surface::connect(int api) {
491     ATRACE_CALL();
492     ALOGV("Surface::connect");
493     static sp<BBinder> sLife = new BBinder();
494     Mutex::Autolock lock(mMutex);
495     IGraphicBufferProducer::QueueBufferOutput output;
496     int err = mGraphicBufferProducer->connect(sLife, api, mProducerControlledByApp, &output);
497     if (err == NO_ERROR) {
498         uint32_t numPendingBuffers = 0;
499         output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
500                 &numPendingBuffers);
501         mConsumerRunningBehind = (numPendingBuffers >= 2);
502     }
503     if (!err && api == NATIVE_WINDOW_API_CPU) {
504         mConnectedToCpu = true;
505     }
506     return err;
507 }
508 
509 
disconnect(int api)510 int Surface::disconnect(int api) {
511     ATRACE_CALL();
512     ALOGV("Surface::disconnect");
513     Mutex::Autolock lock(mMutex);
514     freeAllBuffers();
515     int err = mGraphicBufferProducer->disconnect(api);
516     if (!err) {
517         mReqFormat = 0;
518         mReqWidth = 0;
519         mReqHeight = 0;
520         mReqUsage = 0;
521         mCrop.clear();
522         mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
523         mTransform = 0;
524         if (api == NATIVE_WINDOW_API_CPU) {
525             mConnectedToCpu = false;
526         }
527     }
528     return err;
529 }
530 
setUsage(uint32_t reqUsage)531 int Surface::setUsage(uint32_t reqUsage)
532 {
533     ALOGV("Surface::setUsage");
534     Mutex::Autolock lock(mMutex);
535     mReqUsage = reqUsage;
536     return OK;
537 }
538 
setCrop(Rect const * rect)539 int Surface::setCrop(Rect const* rect)
540 {
541     ATRACE_CALL();
542 
543     Rect realRect;
544     if (rect == NULL || rect->isEmpty()) {
545         realRect.clear();
546     } else {
547         realRect = *rect;
548     }
549 
550     ALOGV("Surface::setCrop rect=[%d %d %d %d]",
551             realRect.left, realRect.top, realRect.right, realRect.bottom);
552 
553     Mutex::Autolock lock(mMutex);
554     mCrop = realRect;
555     return NO_ERROR;
556 }
557 
setBufferCount(int bufferCount)558 int Surface::setBufferCount(int bufferCount)
559 {
560     ATRACE_CALL();
561     ALOGV("Surface::setBufferCount");
562     Mutex::Autolock lock(mMutex);
563 
564     status_t err = mGraphicBufferProducer->setBufferCount(bufferCount);
565     ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
566             bufferCount, strerror(-err));
567 
568     if (err == NO_ERROR) {
569         freeAllBuffers();
570     }
571 
572     return err;
573 }
574 
setBuffersDimensions(int w,int h)575 int Surface::setBuffersDimensions(int w, int h)
576 {
577     ATRACE_CALL();
578     ALOGV("Surface::setBuffersDimensions");
579 
580     if (w<0 || h<0)
581         return BAD_VALUE;
582 
583     if ((w && !h) || (!w && h))
584         return BAD_VALUE;
585 
586     Mutex::Autolock lock(mMutex);
587     mReqWidth = w;
588     mReqHeight = h;
589     return NO_ERROR;
590 }
591 
setBuffersUserDimensions(int w,int h)592 int Surface::setBuffersUserDimensions(int w, int h)
593 {
594     ATRACE_CALL();
595     ALOGV("Surface::setBuffersUserDimensions");
596 
597     if (w<0 || h<0)
598         return BAD_VALUE;
599 
600     if ((w && !h) || (!w && h))
601         return BAD_VALUE;
602 
603     Mutex::Autolock lock(mMutex);
604     mUserWidth = w;
605     mUserHeight = h;
606     return NO_ERROR;
607 }
608 
setBuffersFormat(int format)609 int Surface::setBuffersFormat(int format)
610 {
611     ALOGV("Surface::setBuffersFormat");
612 
613     if (format<0)
614         return BAD_VALUE;
615 
616     Mutex::Autolock lock(mMutex);
617     mReqFormat = format;
618     return NO_ERROR;
619 }
620 
setScalingMode(int mode)621 int Surface::setScalingMode(int mode)
622 {
623     ATRACE_CALL();
624     ALOGV("Surface::setScalingMode(%d)", mode);
625 
626     switch (mode) {
627         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
628         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
629         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
630             break;
631         default:
632             ALOGE("unknown scaling mode: %d", mode);
633             return BAD_VALUE;
634     }
635 
636     Mutex::Autolock lock(mMutex);
637     mScalingMode = mode;
638     return NO_ERROR;
639 }
640 
setBuffersTransform(int transform)641 int Surface::setBuffersTransform(int transform)
642 {
643     ATRACE_CALL();
644     ALOGV("Surface::setBuffersTransform");
645     Mutex::Autolock lock(mMutex);
646     mTransform = transform;
647     return NO_ERROR;
648 }
649 
setBuffersTimestamp(int64_t timestamp)650 int Surface::setBuffersTimestamp(int64_t timestamp)
651 {
652     ALOGV("Surface::setBuffersTimestamp");
653     Mutex::Autolock lock(mMutex);
654     mTimestamp = timestamp;
655     return NO_ERROR;
656 }
657 
freeAllBuffers()658 void Surface::freeAllBuffers() {
659     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
660         mSlots[i].buffer = 0;
661     }
662 }
663 
664 // ----------------------------------------------------------------------
665 // the lock/unlock APIs must be used from the same thread
666 
copyBlt(const sp<GraphicBuffer> & dst,const sp<GraphicBuffer> & src,const Region & reg)667 static status_t copyBlt(
668         const sp<GraphicBuffer>& dst,
669         const sp<GraphicBuffer>& src,
670         const Region& reg)
671 {
672     // src and dst with, height and format must be identical. no verification
673     // is done here.
674     status_t err;
675     uint8_t const * src_bits = NULL;
676     err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
677     ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
678 
679     uint8_t* dst_bits = NULL;
680     err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
681     ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
682 
683     Region::const_iterator head(reg.begin());
684     Region::const_iterator tail(reg.end());
685     if (head != tail && src_bits && dst_bits) {
686         const size_t bpp = bytesPerPixel(src->format);
687         const size_t dbpr = dst->stride * bpp;
688         const size_t sbpr = src->stride * bpp;
689 
690         while (head != tail) {
691             const Rect& r(*head++);
692             ssize_t h = r.height();
693             if (h <= 0) continue;
694             size_t size = r.width() * bpp;
695             uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
696             uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
697             if (dbpr==sbpr && size==sbpr) {
698                 size *= h;
699                 h = 1;
700             }
701             do {
702                 memcpy(d, s, size);
703                 d += dbpr;
704                 s += sbpr;
705             } while (--h > 0);
706         }
707     }
708 
709     if (src_bits)
710         src->unlock();
711 
712     if (dst_bits)
713         dst->unlock();
714 
715     return err;
716 }
717 
718 // ----------------------------------------------------------------------------
719 
lock(ANativeWindow_Buffer * outBuffer,ARect * inOutDirtyBounds)720 status_t Surface::lock(
721         ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
722 {
723     if (mLockedBuffer != 0) {
724         ALOGE("Surface::lock failed, already locked");
725         return INVALID_OPERATION;
726     }
727 
728     if (!mConnectedToCpu) {
729         int err = Surface::connect(NATIVE_WINDOW_API_CPU);
730         if (err) {
731             return err;
732         }
733         // we're intending to do software rendering from this point
734         setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
735     }
736 
737     ANativeWindowBuffer* out;
738     int fenceFd = -1;
739     status_t err = dequeueBuffer(&out, &fenceFd);
740     ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
741     if (err == NO_ERROR) {
742         sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
743         sp<Fence> fence(new Fence(fenceFd));
744 
745         err = fence->waitForever("Surface::lock");
746         if (err != OK) {
747             ALOGE("Fence::wait failed (%s)", strerror(-err));
748             cancelBuffer(out, fenceFd);
749             return err;
750         }
751 
752         const Rect bounds(backBuffer->width, backBuffer->height);
753 
754         Region newDirtyRegion;
755         if (inOutDirtyBounds) {
756             newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
757             newDirtyRegion.andSelf(bounds);
758         } else {
759             newDirtyRegion.set(bounds);
760         }
761 
762         // figure out if we can copy the frontbuffer back
763         const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
764         const bool canCopyBack = (frontBuffer != 0 &&
765                 backBuffer->width  == frontBuffer->width &&
766                 backBuffer->height == frontBuffer->height &&
767                 backBuffer->format == frontBuffer->format);
768 
769         if (canCopyBack) {
770             // copy the area that is invalid and not repainted this round
771             const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
772             if (!copyback.isEmpty())
773                 copyBlt(backBuffer, frontBuffer, copyback);
774         } else {
775             // if we can't copy-back anything, modify the user's dirty
776             // region to make sure they redraw the whole buffer
777             newDirtyRegion.set(bounds);
778             mDirtyRegion.clear();
779             Mutex::Autolock lock(mMutex);
780             for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
781                 mSlots[i].dirtyRegion.clear();
782             }
783         }
784 
785 
786         { // scope for the lock
787             Mutex::Autolock lock(mMutex);
788             int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
789             if (backBufferSlot >= 0) {
790                 Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
791                 mDirtyRegion.subtract(dirtyRegion);
792                 dirtyRegion = newDirtyRegion;
793             }
794         }
795 
796         mDirtyRegion.orSelf(newDirtyRegion);
797         if (inOutDirtyBounds) {
798             *inOutDirtyBounds = newDirtyRegion.getBounds();
799         }
800 
801         void* vaddr;
802         status_t res = backBuffer->lock(
803                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
804                 newDirtyRegion.bounds(), &vaddr);
805 
806         ALOGW_IF(res, "failed locking buffer (handle = %p)",
807                 backBuffer->handle);
808 
809         if (res != 0) {
810             err = INVALID_OPERATION;
811         } else {
812             mLockedBuffer = backBuffer;
813             outBuffer->width  = backBuffer->width;
814             outBuffer->height = backBuffer->height;
815             outBuffer->stride = backBuffer->stride;
816             outBuffer->format = backBuffer->format;
817             outBuffer->bits   = vaddr;
818         }
819     }
820     return err;
821 }
822 
unlockAndPost()823 status_t Surface::unlockAndPost()
824 {
825     if (mLockedBuffer == 0) {
826         ALOGE("Surface::unlockAndPost failed, no locked buffer");
827         return INVALID_OPERATION;
828     }
829 
830     status_t err = mLockedBuffer->unlock();
831     ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
832 
833     err = queueBuffer(mLockedBuffer.get(), -1);
834     ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
835             mLockedBuffer->handle, strerror(-err));
836 
837     mPostedBuffer = mLockedBuffer;
838     mLockedBuffer = 0;
839     return err;
840 }
841 
842 }; // namespace android
843