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 ×tamps);
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