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 <gui/Surface.h>
22
23 #include <condition_variable>
24 #include <deque>
25 #include <mutex>
26 #include <thread>
27
28 #include <inttypes.h>
29
30 #include <android/native_window.h>
31
32 #include <utils/Log.h>
33 #include <utils/Trace.h>
34 #include <utils/NativeHandle.h>
35
36 #include <ui/DisplayStatInfo.h>
37 #include <ui/Fence.h>
38 #include <ui/HdrCapabilities.h>
39 #include <ui/Region.h>
40
41 #include <gui/BufferItem.h>
42 #include <gui/IProducerListener.h>
43
44 #include <gui/ISurfaceComposer.h>
45 #include <private/gui/ComposerService.h>
46
47 namespace android {
48
49 using ui::ColorMode;
50 using ui::Dataspace;
51
Surface(const sp<IGraphicBufferProducer> & bufferProducer,bool controlledByApp)52 Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp)
53 : mGraphicBufferProducer(bufferProducer),
54 mCrop(Rect::EMPTY_RECT),
55 mBufferAge(0),
56 mGenerationNumber(0),
57 mSharedBufferMode(false),
58 mAutoRefresh(false),
59 mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
60 mSharedBufferHasBeenQueued(false),
61 mQueriedSupportedTimestamps(false),
62 mFrameTimestampsSupportsPresent(false),
63 mEnableFrameTimestamps(false),
64 mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) {
65 // Initialize the ANativeWindow function pointers.
66 ANativeWindow::setSwapInterval = hook_setSwapInterval;
67 ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
68 ANativeWindow::cancelBuffer = hook_cancelBuffer;
69 ANativeWindow::queueBuffer = hook_queueBuffer;
70 ANativeWindow::query = hook_query;
71 ANativeWindow::perform = hook_perform;
72
73 ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
74 ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
75 ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
76 ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
77
78 const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
79 const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
80
81 mReqWidth = 0;
82 mReqHeight = 0;
83 mReqFormat = 0;
84 mReqUsage = 0;
85 mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
86 mDataSpace = Dataspace::UNKNOWN;
87 mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
88 mTransform = 0;
89 mStickyTransform = 0;
90 mDefaultWidth = 0;
91 mDefaultHeight = 0;
92 mUserWidth = 0;
93 mUserHeight = 0;
94 mTransformHint = 0;
95 mConsumerRunningBehind = false;
96 mConnectedToCpu = false;
97 mProducerControlledByApp = controlledByApp;
98 mSwapIntervalZero = false;
99 }
100
~Surface()101 Surface::~Surface() {
102 if (mConnectedToCpu) {
103 Surface::disconnect(NATIVE_WINDOW_API_CPU);
104 }
105 }
106
composerService() const107 sp<ISurfaceComposer> Surface::composerService() const {
108 return ComposerService::getComposerService();
109 }
110
now() const111 nsecs_t Surface::now() const {
112 return systemTime();
113 }
114
getIGraphicBufferProducer() const115 sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const {
116 return mGraphicBufferProducer;
117 }
118
setSidebandStream(const sp<NativeHandle> & stream)119 void Surface::setSidebandStream(const sp<NativeHandle>& stream) {
120 mGraphicBufferProducer->setSidebandStream(stream);
121 }
122
allocateBuffers()123 void Surface::allocateBuffers() {
124 uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth;
125 uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight;
126 mGraphicBufferProducer->allocateBuffers(reqWidth, reqHeight,
127 mReqFormat, mReqUsage);
128 }
129
setGenerationNumber(uint32_t generation)130 status_t Surface::setGenerationNumber(uint32_t generation) {
131 status_t result = mGraphicBufferProducer->setGenerationNumber(generation);
132 if (result == NO_ERROR) {
133 mGenerationNumber = generation;
134 }
135 return result;
136 }
137
getNextFrameNumber() const138 uint64_t Surface::getNextFrameNumber() const {
139 Mutex::Autolock lock(mMutex);
140 return mNextFrameNumber;
141 }
142
getConsumerName() const143 String8 Surface::getConsumerName() const {
144 return mGraphicBufferProducer->getConsumerName();
145 }
146
setDequeueTimeout(nsecs_t timeout)147 status_t Surface::setDequeueTimeout(nsecs_t timeout) {
148 return mGraphicBufferProducer->setDequeueTimeout(timeout);
149 }
150
getLastQueuedBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence,float outTransformMatrix[16])151 status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
152 sp<Fence>* outFence, float outTransformMatrix[16]) {
153 return mGraphicBufferProducer->getLastQueuedBuffer(outBuffer, outFence,
154 outTransformMatrix);
155 }
156
getDisplayRefreshCycleDuration(nsecs_t * outRefreshDuration)157 status_t Surface::getDisplayRefreshCycleDuration(nsecs_t* outRefreshDuration) {
158 ATRACE_CALL();
159
160 DisplayStatInfo stats;
161 status_t result = composerService()->getDisplayStats(nullptr, &stats);
162 if (result != NO_ERROR) {
163 return result;
164 }
165
166 *outRefreshDuration = stats.vsyncPeriod;
167
168 return NO_ERROR;
169 }
170
enableFrameTimestamps(bool enable)171 void Surface::enableFrameTimestamps(bool enable) {
172 Mutex::Autolock lock(mMutex);
173 // If going from disabled to enabled, get the initial values for
174 // compositor and display timing.
175 if (!mEnableFrameTimestamps && enable) {
176 FrameEventHistoryDelta delta;
177 mGraphicBufferProducer->getFrameTimestamps(&delta);
178 mFrameEventHistory->applyDelta(delta);
179 }
180 mEnableFrameTimestamps = enable;
181 }
182
getCompositorTiming(nsecs_t * compositeDeadline,nsecs_t * compositeInterval,nsecs_t * compositeToPresentLatency)183 status_t Surface::getCompositorTiming(
184 nsecs_t* compositeDeadline, nsecs_t* compositeInterval,
185 nsecs_t* compositeToPresentLatency) {
186 Mutex::Autolock lock(mMutex);
187 if (!mEnableFrameTimestamps) {
188 return INVALID_OPERATION;
189 }
190
191 if (compositeDeadline != nullptr) {
192 *compositeDeadline =
193 mFrameEventHistory->getNextCompositeDeadline(now());
194 }
195 if (compositeInterval != nullptr) {
196 *compositeInterval = mFrameEventHistory->getCompositeInterval();
197 }
198 if (compositeToPresentLatency != nullptr) {
199 *compositeToPresentLatency =
200 mFrameEventHistory->getCompositeToPresentLatency();
201 }
202 return NO_ERROR;
203 }
204
checkConsumerForUpdates(const FrameEvents * e,const uint64_t lastFrameNumber,const nsecs_t * outLatchTime,const nsecs_t * outFirstRefreshStartTime,const nsecs_t * outLastRefreshStartTime,const nsecs_t * outGpuCompositionDoneTime,const nsecs_t * outDisplayPresentTime,const nsecs_t * outDequeueReadyTime,const nsecs_t * outReleaseTime)205 static bool checkConsumerForUpdates(
206 const FrameEvents* e, const uint64_t lastFrameNumber,
207 const nsecs_t* outLatchTime,
208 const nsecs_t* outFirstRefreshStartTime,
209 const nsecs_t* outLastRefreshStartTime,
210 const nsecs_t* outGpuCompositionDoneTime,
211 const nsecs_t* outDisplayPresentTime,
212 const nsecs_t* outDequeueReadyTime,
213 const nsecs_t* outReleaseTime) {
214 bool checkForLatch = (outLatchTime != nullptr) && !e->hasLatchInfo();
215 bool checkForFirstRefreshStart = (outFirstRefreshStartTime != nullptr) &&
216 !e->hasFirstRefreshStartInfo();
217 bool checkForGpuCompositionDone = (outGpuCompositionDoneTime != nullptr) &&
218 !e->hasGpuCompositionDoneInfo();
219 bool checkForDisplayPresent = (outDisplayPresentTime != nullptr) &&
220 !e->hasDisplayPresentInfo();
221
222 // LastRefreshStart, DequeueReady, and Release are never available for the
223 // last frame.
224 bool checkForLastRefreshStart = (outLastRefreshStartTime != nullptr) &&
225 !e->hasLastRefreshStartInfo() &&
226 (e->frameNumber != lastFrameNumber);
227 bool checkForDequeueReady = (outDequeueReadyTime != nullptr) &&
228 !e->hasDequeueReadyInfo() && (e->frameNumber != lastFrameNumber);
229 bool checkForRelease = (outReleaseTime != nullptr) &&
230 !e->hasReleaseInfo() && (e->frameNumber != lastFrameNumber);
231
232 // RequestedPresent and Acquire info are always available producer-side.
233 return checkForLatch || checkForFirstRefreshStart ||
234 checkForLastRefreshStart || checkForGpuCompositionDone ||
235 checkForDisplayPresent || checkForDequeueReady || checkForRelease;
236 }
237
getFrameTimestamp(nsecs_t * dst,const nsecs_t & src)238 static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) {
239 if (dst != nullptr) {
240 // We always get valid timestamps for these eventually.
241 *dst = (src == FrameEvents::TIMESTAMP_PENDING) ?
242 NATIVE_WINDOW_TIMESTAMP_PENDING : src;
243 }
244 }
245
getFrameTimestampFence(nsecs_t * dst,const std::shared_ptr<FenceTime> & src,bool fenceShouldBeKnown)246 static void getFrameTimestampFence(nsecs_t *dst,
247 const std::shared_ptr<FenceTime>& src, bool fenceShouldBeKnown) {
248 if (dst != nullptr) {
249 if (!fenceShouldBeKnown) {
250 *dst = NATIVE_WINDOW_TIMESTAMP_PENDING;
251 return;
252 }
253
254 nsecs_t signalTime = src->getSignalTime();
255 *dst = (signalTime == Fence::SIGNAL_TIME_PENDING) ?
256 NATIVE_WINDOW_TIMESTAMP_PENDING :
257 (signalTime == Fence::SIGNAL_TIME_INVALID) ?
258 NATIVE_WINDOW_TIMESTAMP_INVALID :
259 signalTime;
260 }
261 }
262
getFrameTimestamps(uint64_t frameNumber,nsecs_t * outRequestedPresentTime,nsecs_t * outAcquireTime,nsecs_t * outLatchTime,nsecs_t * outFirstRefreshStartTime,nsecs_t * outLastRefreshStartTime,nsecs_t * outGpuCompositionDoneTime,nsecs_t * outDisplayPresentTime,nsecs_t * outDequeueReadyTime,nsecs_t * outReleaseTime)263 status_t Surface::getFrameTimestamps(uint64_t frameNumber,
264 nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime,
265 nsecs_t* outLatchTime, nsecs_t* outFirstRefreshStartTime,
266 nsecs_t* outLastRefreshStartTime, nsecs_t* outGpuCompositionDoneTime,
267 nsecs_t* outDisplayPresentTime, nsecs_t* outDequeueReadyTime,
268 nsecs_t* outReleaseTime) {
269 ATRACE_CALL();
270
271 Mutex::Autolock lock(mMutex);
272
273 if (!mEnableFrameTimestamps) {
274 return INVALID_OPERATION;
275 }
276
277 // Verify the requested timestamps are supported.
278 querySupportedTimestampsLocked();
279 if (outDisplayPresentTime != nullptr && !mFrameTimestampsSupportsPresent) {
280 return BAD_VALUE;
281 }
282
283 FrameEvents* events = mFrameEventHistory->getFrame(frameNumber);
284 if (events == nullptr) {
285 // If the entry isn't available in the producer, it's definitely not
286 // available in the consumer.
287 return NAME_NOT_FOUND;
288 }
289
290 // Update our cache of events if the requested events are not available.
291 if (checkConsumerForUpdates(events, mLastFrameNumber,
292 outLatchTime, outFirstRefreshStartTime, outLastRefreshStartTime,
293 outGpuCompositionDoneTime, outDisplayPresentTime,
294 outDequeueReadyTime, outReleaseTime)) {
295 FrameEventHistoryDelta delta;
296 mGraphicBufferProducer->getFrameTimestamps(&delta);
297 mFrameEventHistory->applyDelta(delta);
298 events = mFrameEventHistory->getFrame(frameNumber);
299 }
300
301 if (events == nullptr) {
302 // The entry was available before the update, but was overwritten
303 // after the update. Make sure not to send the wrong frame's data.
304 return NAME_NOT_FOUND;
305 }
306
307 getFrameTimestamp(outRequestedPresentTime, events->requestedPresentTime);
308 getFrameTimestamp(outLatchTime, events->latchTime);
309 getFrameTimestamp(outFirstRefreshStartTime, events->firstRefreshStartTime);
310 getFrameTimestamp(outLastRefreshStartTime, events->lastRefreshStartTime);
311 getFrameTimestamp(outDequeueReadyTime, events->dequeueReadyTime);
312
313 getFrameTimestampFence(outAcquireTime, events->acquireFence,
314 events->hasAcquireInfo());
315 getFrameTimestampFence(outGpuCompositionDoneTime,
316 events->gpuCompositionDoneFence,
317 events->hasGpuCompositionDoneInfo());
318 getFrameTimestampFence(outDisplayPresentTime, events->displayPresentFence,
319 events->hasDisplayPresentInfo());
320 getFrameTimestampFence(outReleaseTime, events->releaseFence,
321 events->hasReleaseInfo());
322
323 return NO_ERROR;
324 }
325
getWideColorSupport(bool * supported)326 status_t Surface::getWideColorSupport(bool* supported) {
327 ATRACE_CALL();
328
329 const sp<IBinder> display = composerService()->getInternalDisplayToken();
330 if (display == nullptr) {
331 return NAME_NOT_FOUND;
332 }
333
334 *supported = false;
335 status_t error = composerService()->isWideColorDisplay(display, supported);
336 return error;
337 }
338
getHdrSupport(bool * supported)339 status_t Surface::getHdrSupport(bool* supported) {
340 ATRACE_CALL();
341
342 const sp<IBinder> display = composerService()->getInternalDisplayToken();
343 if (display == nullptr) {
344 return NAME_NOT_FOUND;
345 }
346
347 HdrCapabilities hdrCapabilities;
348 status_t err =
349 composerService()->getHdrCapabilities(display, &hdrCapabilities);
350
351 if (err)
352 return err;
353
354 *supported = !hdrCapabilities.getSupportedHdrTypes().empty();
355
356 return NO_ERROR;
357 }
358
hook_setSwapInterval(ANativeWindow * window,int interval)359 int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
360 Surface* c = getSelf(window);
361 return c->setSwapInterval(interval);
362 }
363
hook_dequeueBuffer(ANativeWindow * window,ANativeWindowBuffer ** buffer,int * fenceFd)364 int Surface::hook_dequeueBuffer(ANativeWindow* window,
365 ANativeWindowBuffer** buffer, int* fenceFd) {
366 Surface* c = getSelf(window);
367 return c->dequeueBuffer(buffer, fenceFd);
368 }
369
hook_cancelBuffer(ANativeWindow * window,ANativeWindowBuffer * buffer,int fenceFd)370 int Surface::hook_cancelBuffer(ANativeWindow* window,
371 ANativeWindowBuffer* buffer, int fenceFd) {
372 Surface* c = getSelf(window);
373 return c->cancelBuffer(buffer, fenceFd);
374 }
375
hook_queueBuffer(ANativeWindow * window,ANativeWindowBuffer * buffer,int fenceFd)376 int Surface::hook_queueBuffer(ANativeWindow* window,
377 ANativeWindowBuffer* buffer, int fenceFd) {
378 Surface* c = getSelf(window);
379 return c->queueBuffer(buffer, fenceFd);
380 }
381
hook_dequeueBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer ** buffer)382 int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
383 ANativeWindowBuffer** buffer) {
384 Surface* c = getSelf(window);
385 ANativeWindowBuffer* buf;
386 int fenceFd = -1;
387 int result = c->dequeueBuffer(&buf, &fenceFd);
388 if (result != OK) {
389 return result;
390 }
391 sp<Fence> fence(new Fence(fenceFd));
392 int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
393 if (waitResult != OK) {
394 ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d",
395 waitResult);
396 c->cancelBuffer(buf, -1);
397 return waitResult;
398 }
399 *buffer = buf;
400 return result;
401 }
402
hook_cancelBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer * buffer)403 int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
404 ANativeWindowBuffer* buffer) {
405 Surface* c = getSelf(window);
406 return c->cancelBuffer(buffer, -1);
407 }
408
hook_lockBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer * buffer)409 int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
410 ANativeWindowBuffer* buffer) {
411 Surface* c = getSelf(window);
412 return c->lockBuffer_DEPRECATED(buffer);
413 }
414
hook_queueBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer * buffer)415 int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
416 ANativeWindowBuffer* buffer) {
417 Surface* c = getSelf(window);
418 return c->queueBuffer(buffer, -1);
419 }
420
hook_query(const ANativeWindow * window,int what,int * value)421 int Surface::hook_query(const ANativeWindow* window,
422 int what, int* value) {
423 const Surface* c = getSelf(window);
424 return c->query(what, value);
425 }
426
hook_perform(ANativeWindow * window,int operation,...)427 int Surface::hook_perform(ANativeWindow* window, int operation, ...) {
428 va_list args;
429 va_start(args, operation);
430 Surface* c = getSelf(window);
431 int result = c->perform(operation, args);
432 va_end(args);
433 return result;
434 }
435
setSwapInterval(int interval)436 int Surface::setSwapInterval(int interval) {
437 ATRACE_CALL();
438 // EGL specification states:
439 // interval is silently clamped to minimum and maximum implementation
440 // dependent values before being stored.
441
442 if (interval < minSwapInterval)
443 interval = minSwapInterval;
444
445 if (interval > maxSwapInterval)
446 interval = maxSwapInterval;
447
448 const bool wasSwapIntervalZero = mSwapIntervalZero;
449 mSwapIntervalZero = (interval == 0);
450
451 if (mSwapIntervalZero != wasSwapIntervalZero) {
452 mGraphicBufferProducer->setAsyncMode(mSwapIntervalZero);
453 }
454
455 return NO_ERROR;
456 }
457
458 class FenceMonitor {
459 public:
FenceMonitor(const char * name)460 explicit FenceMonitor(const char* name) : mName(name), mFencesQueued(0), mFencesSignaled(0) {
461 std::thread thread(&FenceMonitor::loop, this);
462 pthread_setname_np(thread.native_handle(), mName);
463 thread.detach();
464 }
465
queueFence(const sp<Fence> & fence)466 void queueFence(const sp<Fence>& fence) {
467 char message[64];
468
469 std::lock_guard<std::mutex> lock(mMutex);
470 if (fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) {
471 snprintf(message, sizeof(message), "%s fence %u has signaled", mName, mFencesQueued);
472 ATRACE_NAME(message);
473 // Need an increment on both to make the trace number correct.
474 mFencesQueued++;
475 mFencesSignaled++;
476 return;
477 }
478 snprintf(message, sizeof(message), "Trace %s fence %u", mName, mFencesQueued);
479 ATRACE_NAME(message);
480
481 mQueue.push_back(fence);
482 mCondition.notify_one();
483 mFencesQueued++;
484 ATRACE_INT(mName, int32_t(mQueue.size()));
485 }
486
487 private:
488 #pragma clang diagnostic push
489 #pragma clang diagnostic ignored "-Wmissing-noreturn"
loop()490 void loop() {
491 while (true) {
492 threadLoop();
493 }
494 }
495 #pragma clang diagnostic pop
496
threadLoop()497 void threadLoop() {
498 sp<Fence> fence;
499 uint32_t fenceNum;
500 {
501 std::unique_lock<std::mutex> lock(mMutex);
502 while (mQueue.empty()) {
503 mCondition.wait(lock);
504 }
505 fence = mQueue[0];
506 fenceNum = mFencesSignaled;
507 }
508 {
509 char message[64];
510 snprintf(message, sizeof(message), "waiting for %s %u", mName, fenceNum);
511 ATRACE_NAME(message);
512
513 status_t result = fence->waitForever(message);
514 if (result != OK) {
515 ALOGE("Error waiting for fence: %d", result);
516 }
517 }
518 {
519 std::lock_guard<std::mutex> lock(mMutex);
520 mQueue.pop_front();
521 mFencesSignaled++;
522 ATRACE_INT(mName, int32_t(mQueue.size()));
523 }
524 }
525
526 const char* mName;
527 uint32_t mFencesQueued;
528 uint32_t mFencesSignaled;
529 std::deque<sp<Fence>> mQueue;
530 std::condition_variable mCondition;
531 std::mutex mMutex;
532 };
533
dequeueBuffer(android_native_buffer_t ** buffer,int * fenceFd)534 int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
535 ATRACE_CALL();
536 ALOGV("Surface::dequeueBuffer");
537
538 uint32_t reqWidth;
539 uint32_t reqHeight;
540 PixelFormat reqFormat;
541 uint64_t reqUsage;
542 bool enableFrameTimestamps;
543
544 {
545 Mutex::Autolock lock(mMutex);
546 if (mReportRemovedBuffers) {
547 mRemovedBuffers.clear();
548 }
549
550 reqWidth = mReqWidth ? mReqWidth : mUserWidth;
551 reqHeight = mReqHeight ? mReqHeight : mUserHeight;
552
553 reqFormat = mReqFormat;
554 reqUsage = mReqUsage;
555
556 enableFrameTimestamps = mEnableFrameTimestamps;
557
558 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot !=
559 BufferItem::INVALID_BUFFER_SLOT) {
560 sp<GraphicBuffer>& gbuf(mSlots[mSharedBufferSlot].buffer);
561 if (gbuf != nullptr) {
562 *buffer = gbuf.get();
563 *fenceFd = -1;
564 return OK;
565 }
566 }
567 } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer
568
569 int buf = -1;
570 sp<Fence> fence;
571 nsecs_t startTime = systemTime();
572
573 FrameEventHistoryDelta frameTimestamps;
574 status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight,
575 reqFormat, reqUsage, &mBufferAge,
576 enableFrameTimestamps ? &frameTimestamps
577 : nullptr);
578 mLastDequeueDuration = systemTime() - startTime;
579
580 if (result < 0) {
581 ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer"
582 "(%d, %d, %d, %#" PRIx64 ") failed: %d",
583 reqWidth, reqHeight, reqFormat, reqUsage, result);
584 return result;
585 }
586
587 if (buf < 0 || buf >= NUM_BUFFER_SLOTS) {
588 ALOGE("dequeueBuffer: IGraphicBufferProducer returned invalid slot number %d", buf);
589 android_errorWriteLog(0x534e4554, "36991414"); // SafetyNet logging
590 return FAILED_TRANSACTION;
591 }
592
593 Mutex::Autolock lock(mMutex);
594
595 // Write this while holding the mutex
596 mLastDequeueStartTime = startTime;
597
598 sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
599
600 // this should never happen
601 ALOGE_IF(fence == nullptr, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);
602
603 if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
604 static FenceMonitor hwcReleaseThread("HWC release");
605 hwcReleaseThread.queueFence(fence);
606 }
607
608 if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
609 freeAllBuffers();
610 }
611
612 if (enableFrameTimestamps) {
613 mFrameEventHistory->applyDelta(frameTimestamps);
614 }
615
616 if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) {
617 if (mReportRemovedBuffers && (gbuf != nullptr)) {
618 mRemovedBuffers.push_back(gbuf);
619 }
620 result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
621 if (result != NO_ERROR) {
622 ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
623 mGraphicBufferProducer->cancelBuffer(buf, fence);
624 return result;
625 }
626 }
627
628 if (fence->isValid()) {
629 *fenceFd = fence->dup();
630 if (*fenceFd == -1) {
631 ALOGE("dequeueBuffer: error duping fence: %d", errno);
632 // dup() should never fail; something is badly wrong. Soldier on
633 // and hope for the best; the worst that should happen is some
634 // visible corruption that lasts until the next frame.
635 }
636 } else {
637 *fenceFd = -1;
638 }
639
640 *buffer = gbuf.get();
641
642 if (mSharedBufferMode && mAutoRefresh) {
643 mSharedBufferSlot = buf;
644 mSharedBufferHasBeenQueued = false;
645 } else if (mSharedBufferSlot == buf) {
646 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
647 mSharedBufferHasBeenQueued = false;
648 }
649
650 return OK;
651 }
652
cancelBuffer(android_native_buffer_t * buffer,int fenceFd)653 int Surface::cancelBuffer(android_native_buffer_t* buffer,
654 int fenceFd) {
655 ATRACE_CALL();
656 ALOGV("Surface::cancelBuffer");
657 Mutex::Autolock lock(mMutex);
658 int i = getSlotFromBufferLocked(buffer);
659 if (i < 0) {
660 if (fenceFd >= 0) {
661 close(fenceFd);
662 }
663 return i;
664 }
665 if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
666 if (fenceFd >= 0) {
667 close(fenceFd);
668 }
669 return OK;
670 }
671 sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
672 mGraphicBufferProducer->cancelBuffer(i, fence);
673
674 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
675 mSharedBufferHasBeenQueued = true;
676 }
677
678 return OK;
679 }
680
getSlotFromBufferLocked(android_native_buffer_t * buffer) const681 int Surface::getSlotFromBufferLocked(
682 android_native_buffer_t* buffer) const {
683 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
684 if (mSlots[i].buffer != nullptr &&
685 mSlots[i].buffer->handle == buffer->handle) {
686 return i;
687 }
688 }
689 ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
690 return BAD_VALUE;
691 }
692
lockBuffer_DEPRECATED(android_native_buffer_t * buffer)693 int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) {
694 ALOGV("Surface::lockBuffer");
695 Mutex::Autolock lock(mMutex);
696 return OK;
697 }
698
queueBuffer(android_native_buffer_t * buffer,int fenceFd)699 int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
700 ATRACE_CALL();
701 ALOGV("Surface::queueBuffer");
702 Mutex::Autolock lock(mMutex);
703 int64_t timestamp;
704 bool isAutoTimestamp = false;
705
706 if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
707 timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
708 isAutoTimestamp = true;
709 ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
710 timestamp / 1000000.0);
711 } else {
712 timestamp = mTimestamp;
713 }
714 int i = getSlotFromBufferLocked(buffer);
715 if (i < 0) {
716 if (fenceFd >= 0) {
717 close(fenceFd);
718 }
719 return i;
720 }
721 if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
722 if (fenceFd >= 0) {
723 close(fenceFd);
724 }
725 return OK;
726 }
727
728
729 // Make sure the crop rectangle is entirely inside the buffer.
730 Rect crop(Rect::EMPTY_RECT);
731 mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
732
733 sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
734 IGraphicBufferProducer::QueueBufferOutput output;
735 IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
736 static_cast<android_dataspace>(mDataSpace), crop, mScalingMode,
737 mTransform ^ mStickyTransform, fence, mStickyTransform,
738 mEnableFrameTimestamps);
739
740 // we should send HDR metadata as needed if this becomes a bottleneck
741 input.setHdrMetadata(mHdrMetadata);
742
743 if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) {
744 input.setSurfaceDamage(Region::INVALID_REGION);
745 } else {
746 // Here we do two things:
747 // 1) The surface damage was specified using the OpenGL ES convention of
748 // the origin being in the bottom-left corner. Here we flip to the
749 // convention that the rest of the system uses (top-left corner) by
750 // subtracting all top/bottom coordinates from the buffer height.
751 // 2) If the buffer is coming in rotated (for example, because the EGL
752 // implementation is reacting to the transform hint coming back from
753 // SurfaceFlinger), the surface damage needs to be rotated the
754 // opposite direction, since it was generated assuming an unrotated
755 // buffer (the app doesn't know that the EGL implementation is
756 // reacting to the transform hint behind its back). The
757 // transformations in the switch statement below apply those
758 // complementary rotations (e.g., if 90 degrees, rotate 270 degrees).
759
760 int width = buffer->width;
761 int height = buffer->height;
762 bool rotated90 = (mTransform ^ mStickyTransform) &
763 NATIVE_WINDOW_TRANSFORM_ROT_90;
764 if (rotated90) {
765 std::swap(width, height);
766 }
767
768 Region flippedRegion;
769 for (auto rect : mDirtyRegion) {
770 int left = rect.left;
771 int right = rect.right;
772 int top = height - rect.bottom; // Flip from OpenGL convention
773 int bottom = height - rect.top; // Flip from OpenGL convention
774 switch (mTransform ^ mStickyTransform) {
775 case NATIVE_WINDOW_TRANSFORM_ROT_90: {
776 // Rotate 270 degrees
777 Rect flippedRect{top, width - right, bottom, width - left};
778 flippedRegion.orSelf(flippedRect);
779 break;
780 }
781 case NATIVE_WINDOW_TRANSFORM_ROT_180: {
782 // Rotate 180 degrees
783 Rect flippedRect{width - right, height - bottom,
784 width - left, height - top};
785 flippedRegion.orSelf(flippedRect);
786 break;
787 }
788 case NATIVE_WINDOW_TRANSFORM_ROT_270: {
789 // Rotate 90 degrees
790 Rect flippedRect{height - bottom, left,
791 height - top, right};
792 flippedRegion.orSelf(flippedRect);
793 break;
794 }
795 default: {
796 Rect flippedRect{left, top, right, bottom};
797 flippedRegion.orSelf(flippedRect);
798 break;
799 }
800 }
801 }
802
803 input.setSurfaceDamage(flippedRegion);
804 }
805
806 nsecs_t now = systemTime();
807 status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
808 mLastQueueDuration = systemTime() - now;
809 if (err != OK) {
810 ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
811 }
812
813 if (mEnableFrameTimestamps) {
814 mFrameEventHistory->applyDelta(output.frameTimestamps);
815 // Update timestamps with the local acquire fence.
816 // The consumer doesn't send it back to prevent us from having two
817 // file descriptors of the same fence.
818 mFrameEventHistory->updateAcquireFence(mNextFrameNumber,
819 std::make_shared<FenceTime>(fence));
820
821 // Cache timestamps of signaled fences so we can close their file
822 // descriptors.
823 mFrameEventHistory->updateSignalTimes();
824 }
825
826 mLastFrameNumber = mNextFrameNumber;
827
828 mDefaultWidth = output.width;
829 mDefaultHeight = output.height;
830 mNextFrameNumber = output.nextFrameNumber;
831
832 // Ignore transform hint if sticky transform is set or transform to display inverse flag is
833 // set.
834 if (mStickyTransform == 0 && !transformToDisplayInverse()) {
835 mTransformHint = output.transformHint;
836 }
837
838 mConsumerRunningBehind = (output.numPendingBuffers >= 2);
839
840 if (!mConnectedToCpu) {
841 // Clear surface damage back to full-buffer
842 mDirtyRegion = Region::INVALID_REGION;
843 }
844
845 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
846 mSharedBufferHasBeenQueued = true;
847 }
848
849 mQueueBufferCondition.broadcast();
850
851 if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
852 static FenceMonitor gpuCompletionThread("GPU completion");
853 gpuCompletionThread.queueFence(fence);
854 }
855
856 return err;
857 }
858
querySupportedTimestampsLocked() const859 void Surface::querySupportedTimestampsLocked() const {
860 // mMutex must be locked when calling this method.
861
862 if (mQueriedSupportedTimestamps) {
863 return;
864 }
865 mQueriedSupportedTimestamps = true;
866
867 std::vector<FrameEvent> supportedFrameTimestamps;
868 status_t err = composerService()->getSupportedFrameTimestamps(
869 &supportedFrameTimestamps);
870
871 if (err != NO_ERROR) {
872 return;
873 }
874
875 for (auto sft : supportedFrameTimestamps) {
876 if (sft == FrameEvent::DISPLAY_PRESENT) {
877 mFrameTimestampsSupportsPresent = true;
878 }
879 }
880 }
881
query(int what,int * value) const882 int Surface::query(int what, int* value) const {
883 ATRACE_CALL();
884 ALOGV("Surface::query");
885 { // scope for the lock
886 Mutex::Autolock lock(mMutex);
887 switch (what) {
888 case NATIVE_WINDOW_FORMAT:
889 if (mReqFormat) {
890 *value = static_cast<int>(mReqFormat);
891 return NO_ERROR;
892 }
893 break;
894 case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
895 if (composerService()->authenticateSurfaceTexture(
896 mGraphicBufferProducer)) {
897 *value = 1;
898 } else {
899 *value = 0;
900 }
901 return NO_ERROR;
902 }
903 case NATIVE_WINDOW_CONCRETE_TYPE:
904 *value = NATIVE_WINDOW_SURFACE;
905 return NO_ERROR;
906 case NATIVE_WINDOW_DEFAULT_WIDTH:
907 *value = static_cast<int>(
908 mUserWidth ? mUserWidth : mDefaultWidth);
909 return NO_ERROR;
910 case NATIVE_WINDOW_DEFAULT_HEIGHT:
911 *value = static_cast<int>(
912 mUserHeight ? mUserHeight : mDefaultHeight);
913 return NO_ERROR;
914 case NATIVE_WINDOW_TRANSFORM_HINT:
915 *value = static_cast<int>(mTransformHint);
916 return NO_ERROR;
917 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
918 status_t err = NO_ERROR;
919 if (!mConsumerRunningBehind) {
920 *value = 0;
921 } else {
922 err = mGraphicBufferProducer->query(what, value);
923 if (err == NO_ERROR) {
924 mConsumerRunningBehind = *value;
925 }
926 }
927 return err;
928 }
929 case NATIVE_WINDOW_BUFFER_AGE: {
930 if (mBufferAge > INT32_MAX) {
931 *value = 0;
932 } else {
933 *value = static_cast<int32_t>(mBufferAge);
934 }
935 return NO_ERROR;
936 }
937 case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: {
938 int64_t durationUs = mLastDequeueDuration / 1000;
939 *value = durationUs > std::numeric_limits<int>::max() ?
940 std::numeric_limits<int>::max() :
941 static_cast<int>(durationUs);
942 return NO_ERROR;
943 }
944 case NATIVE_WINDOW_LAST_QUEUE_DURATION: {
945 int64_t durationUs = mLastQueueDuration / 1000;
946 *value = durationUs > std::numeric_limits<int>::max() ?
947 std::numeric_limits<int>::max() :
948 static_cast<int>(durationUs);
949 return NO_ERROR;
950 }
951 case NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT: {
952 querySupportedTimestampsLocked();
953 *value = mFrameTimestampsSupportsPresent ? 1 : 0;
954 return NO_ERROR;
955 }
956 case NATIVE_WINDOW_IS_VALID: {
957 *value = mGraphicBufferProducer != nullptr ? 1 : 0;
958 return NO_ERROR;
959 }
960 case NATIVE_WINDOW_DATASPACE: {
961 *value = static_cast<int>(mDataSpace);
962 return NO_ERROR;
963 }
964 }
965 }
966 return mGraphicBufferProducer->query(what, value);
967 }
968
perform(int operation,va_list args)969 int Surface::perform(int operation, va_list args)
970 {
971 int res = NO_ERROR;
972 switch (operation) {
973 case NATIVE_WINDOW_CONNECT:
974 // deprecated. must return NO_ERROR.
975 break;
976 case NATIVE_WINDOW_DISCONNECT:
977 // deprecated. must return NO_ERROR.
978 break;
979 case NATIVE_WINDOW_SET_USAGE:
980 res = dispatchSetUsage(args);
981 break;
982 case NATIVE_WINDOW_SET_CROP:
983 res = dispatchSetCrop(args);
984 break;
985 case NATIVE_WINDOW_SET_BUFFER_COUNT:
986 res = dispatchSetBufferCount(args);
987 break;
988 case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
989 res = dispatchSetBuffersGeometry(args);
990 break;
991 case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
992 res = dispatchSetBuffersTransform(args);
993 break;
994 case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM:
995 res = dispatchSetBuffersStickyTransform(args);
996 break;
997 case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
998 res = dispatchSetBuffersTimestamp(args);
999 break;
1000 case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
1001 res = dispatchSetBuffersDimensions(args);
1002 break;
1003 case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
1004 res = dispatchSetBuffersUserDimensions(args);
1005 break;
1006 case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
1007 res = dispatchSetBuffersFormat(args);
1008 break;
1009 case NATIVE_WINDOW_LOCK:
1010 res = dispatchLock(args);
1011 break;
1012 case NATIVE_WINDOW_UNLOCK_AND_POST:
1013 res = dispatchUnlockAndPost(args);
1014 break;
1015 case NATIVE_WINDOW_SET_SCALING_MODE:
1016 res = dispatchSetScalingMode(args);
1017 break;
1018 case NATIVE_WINDOW_API_CONNECT:
1019 res = dispatchConnect(args);
1020 break;
1021 case NATIVE_WINDOW_API_DISCONNECT:
1022 res = dispatchDisconnect(args);
1023 break;
1024 case NATIVE_WINDOW_SET_SIDEBAND_STREAM:
1025 res = dispatchSetSidebandStream(args);
1026 break;
1027 case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
1028 res = dispatchSetBuffersDataSpace(args);
1029 break;
1030 case NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA:
1031 res = dispatchSetBuffersSmpte2086Metadata(args);
1032 break;
1033 case NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA:
1034 res = dispatchSetBuffersCta8613Metadata(args);
1035 break;
1036 case NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA:
1037 res = dispatchSetBuffersHdr10PlusMetadata(args);
1038 break;
1039 case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
1040 res = dispatchSetSurfaceDamage(args);
1041 break;
1042 case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE:
1043 res = dispatchSetSharedBufferMode(args);
1044 break;
1045 case NATIVE_WINDOW_SET_AUTO_REFRESH:
1046 res = dispatchSetAutoRefresh(args);
1047 break;
1048 case NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION:
1049 res = dispatchGetDisplayRefreshCycleDuration(args);
1050 break;
1051 case NATIVE_WINDOW_GET_NEXT_FRAME_ID:
1052 res = dispatchGetNextFrameId(args);
1053 break;
1054 case NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS:
1055 res = dispatchEnableFrameTimestamps(args);
1056 break;
1057 case NATIVE_WINDOW_GET_COMPOSITOR_TIMING:
1058 res = dispatchGetCompositorTiming(args);
1059 break;
1060 case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS:
1061 res = dispatchGetFrameTimestamps(args);
1062 break;
1063 case NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT:
1064 res = dispatchGetWideColorSupport(args);
1065 break;
1066 case NATIVE_WINDOW_GET_HDR_SUPPORT:
1067 res = dispatchGetHdrSupport(args);
1068 break;
1069 case NATIVE_WINDOW_SET_USAGE64:
1070 res = dispatchSetUsage64(args);
1071 break;
1072 case NATIVE_WINDOW_GET_CONSUMER_USAGE64:
1073 res = dispatchGetConsumerUsage64(args);
1074 break;
1075 default:
1076 res = NAME_NOT_FOUND;
1077 break;
1078 }
1079 return res;
1080 }
1081
dispatchConnect(va_list args)1082 int Surface::dispatchConnect(va_list args) {
1083 int api = va_arg(args, int);
1084 return connect(api);
1085 }
1086
dispatchDisconnect(va_list args)1087 int Surface::dispatchDisconnect(va_list args) {
1088 int api = va_arg(args, int);
1089 return disconnect(api);
1090 }
1091
dispatchSetUsage(va_list args)1092 int Surface::dispatchSetUsage(va_list args) {
1093 uint64_t usage = va_arg(args, uint32_t);
1094 return setUsage(usage);
1095 }
1096
dispatchSetUsage64(va_list args)1097 int Surface::dispatchSetUsage64(va_list args) {
1098 uint64_t usage = va_arg(args, uint64_t);
1099 return setUsage(usage);
1100 }
1101
dispatchSetCrop(va_list args)1102 int Surface::dispatchSetCrop(va_list args) {
1103 android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
1104 return setCrop(reinterpret_cast<Rect const*>(rect));
1105 }
1106
dispatchSetBufferCount(va_list args)1107 int Surface::dispatchSetBufferCount(va_list args) {
1108 size_t bufferCount = va_arg(args, size_t);
1109 return setBufferCount(static_cast<int32_t>(bufferCount));
1110 }
1111
dispatchSetBuffersGeometry(va_list args)1112 int Surface::dispatchSetBuffersGeometry(va_list args) {
1113 uint32_t width = va_arg(args, uint32_t);
1114 uint32_t height = va_arg(args, uint32_t);
1115 PixelFormat format = va_arg(args, PixelFormat);
1116 int err = setBuffersDimensions(width, height);
1117 if (err != 0) {
1118 return err;
1119 }
1120 return setBuffersFormat(format);
1121 }
1122
dispatchSetBuffersDimensions(va_list args)1123 int Surface::dispatchSetBuffersDimensions(va_list args) {
1124 uint32_t width = va_arg(args, uint32_t);
1125 uint32_t height = va_arg(args, uint32_t);
1126 return setBuffersDimensions(width, height);
1127 }
1128
dispatchSetBuffersUserDimensions(va_list args)1129 int Surface::dispatchSetBuffersUserDimensions(va_list args) {
1130 uint32_t width = va_arg(args, uint32_t);
1131 uint32_t height = va_arg(args, uint32_t);
1132 return setBuffersUserDimensions(width, height);
1133 }
1134
dispatchSetBuffersFormat(va_list args)1135 int Surface::dispatchSetBuffersFormat(va_list args) {
1136 PixelFormat format = va_arg(args, PixelFormat);
1137 return setBuffersFormat(format);
1138 }
1139
dispatchSetScalingMode(va_list args)1140 int Surface::dispatchSetScalingMode(va_list args) {
1141 int mode = va_arg(args, int);
1142 return setScalingMode(mode);
1143 }
1144
dispatchSetBuffersTransform(va_list args)1145 int Surface::dispatchSetBuffersTransform(va_list args) {
1146 uint32_t transform = va_arg(args, uint32_t);
1147 return setBuffersTransform(transform);
1148 }
1149
dispatchSetBuffersStickyTransform(va_list args)1150 int Surface::dispatchSetBuffersStickyTransform(va_list args) {
1151 uint32_t transform = va_arg(args, uint32_t);
1152 return setBuffersStickyTransform(transform);
1153 }
1154
dispatchSetBuffersTimestamp(va_list args)1155 int Surface::dispatchSetBuffersTimestamp(va_list args) {
1156 int64_t timestamp = va_arg(args, int64_t);
1157 return setBuffersTimestamp(timestamp);
1158 }
1159
dispatchLock(va_list args)1160 int Surface::dispatchLock(va_list args) {
1161 ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
1162 ARect* inOutDirtyBounds = va_arg(args, ARect*);
1163 return lock(outBuffer, inOutDirtyBounds);
1164 }
1165
dispatchUnlockAndPost(va_list args)1166 int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) {
1167 return unlockAndPost();
1168 }
1169
dispatchSetSidebandStream(va_list args)1170 int Surface::dispatchSetSidebandStream(va_list args) {
1171 native_handle_t* sH = va_arg(args, native_handle_t*);
1172 sp<NativeHandle> sidebandHandle = NativeHandle::create(sH, false);
1173 setSidebandStream(sidebandHandle);
1174 return OK;
1175 }
1176
dispatchSetBuffersDataSpace(va_list args)1177 int Surface::dispatchSetBuffersDataSpace(va_list args) {
1178 Dataspace dataspace = static_cast<Dataspace>(va_arg(args, int));
1179 return setBuffersDataSpace(dataspace);
1180 }
1181
dispatchSetBuffersSmpte2086Metadata(va_list args)1182 int Surface::dispatchSetBuffersSmpte2086Metadata(va_list args) {
1183 const android_smpte2086_metadata* metadata =
1184 va_arg(args, const android_smpte2086_metadata*);
1185 return setBuffersSmpte2086Metadata(metadata);
1186 }
1187
dispatchSetBuffersCta8613Metadata(va_list args)1188 int Surface::dispatchSetBuffersCta8613Metadata(va_list args) {
1189 const android_cta861_3_metadata* metadata =
1190 va_arg(args, const android_cta861_3_metadata*);
1191 return setBuffersCta8613Metadata(metadata);
1192 }
1193
dispatchSetBuffersHdr10PlusMetadata(va_list args)1194 int Surface::dispatchSetBuffersHdr10PlusMetadata(va_list args) {
1195 const size_t size = va_arg(args, size_t);
1196 const uint8_t* metadata = va_arg(args, const uint8_t*);
1197 return setBuffersHdr10PlusMetadata(size, metadata);
1198 }
1199
dispatchSetSurfaceDamage(va_list args)1200 int Surface::dispatchSetSurfaceDamage(va_list args) {
1201 android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
1202 size_t numRects = va_arg(args, size_t);
1203 setSurfaceDamage(rects, numRects);
1204 return NO_ERROR;
1205 }
1206
dispatchSetSharedBufferMode(va_list args)1207 int Surface::dispatchSetSharedBufferMode(va_list args) {
1208 bool sharedBufferMode = va_arg(args, int);
1209 return setSharedBufferMode(sharedBufferMode);
1210 }
1211
dispatchSetAutoRefresh(va_list args)1212 int Surface::dispatchSetAutoRefresh(va_list args) {
1213 bool autoRefresh = va_arg(args, int);
1214 return setAutoRefresh(autoRefresh);
1215 }
1216
dispatchGetDisplayRefreshCycleDuration(va_list args)1217 int Surface::dispatchGetDisplayRefreshCycleDuration(va_list args) {
1218 nsecs_t* outRefreshDuration = va_arg(args, int64_t*);
1219 return getDisplayRefreshCycleDuration(outRefreshDuration);
1220 }
1221
dispatchGetNextFrameId(va_list args)1222 int Surface::dispatchGetNextFrameId(va_list args) {
1223 uint64_t* nextFrameId = va_arg(args, uint64_t*);
1224 *nextFrameId = getNextFrameNumber();
1225 return NO_ERROR;
1226 }
1227
dispatchEnableFrameTimestamps(va_list args)1228 int Surface::dispatchEnableFrameTimestamps(va_list args) {
1229 bool enable = va_arg(args, int);
1230 enableFrameTimestamps(enable);
1231 return NO_ERROR;
1232 }
1233
dispatchGetCompositorTiming(va_list args)1234 int Surface::dispatchGetCompositorTiming(va_list args) {
1235 nsecs_t* compositeDeadline = va_arg(args, int64_t*);
1236 nsecs_t* compositeInterval = va_arg(args, int64_t*);
1237 nsecs_t* compositeToPresentLatency = va_arg(args, int64_t*);
1238 return getCompositorTiming(compositeDeadline, compositeInterval,
1239 compositeToPresentLatency);
1240 }
1241
dispatchGetFrameTimestamps(va_list args)1242 int Surface::dispatchGetFrameTimestamps(va_list args) {
1243 uint64_t frameId = va_arg(args, uint64_t);
1244 nsecs_t* outRequestedPresentTime = va_arg(args, int64_t*);
1245 nsecs_t* outAcquireTime = va_arg(args, int64_t*);
1246 nsecs_t* outLatchTime = va_arg(args, int64_t*);
1247 nsecs_t* outFirstRefreshStartTime = va_arg(args, int64_t*);
1248 nsecs_t* outLastRefreshStartTime = va_arg(args, int64_t*);
1249 nsecs_t* outGpuCompositionDoneTime = va_arg(args, int64_t*);
1250 nsecs_t* outDisplayPresentTime = va_arg(args, int64_t*);
1251 nsecs_t* outDequeueReadyTime = va_arg(args, int64_t*);
1252 nsecs_t* outReleaseTime = va_arg(args, int64_t*);
1253 return getFrameTimestamps(frameId,
1254 outRequestedPresentTime, outAcquireTime, outLatchTime,
1255 outFirstRefreshStartTime, outLastRefreshStartTime,
1256 outGpuCompositionDoneTime, outDisplayPresentTime,
1257 outDequeueReadyTime, outReleaseTime);
1258 }
1259
dispatchGetWideColorSupport(va_list args)1260 int Surface::dispatchGetWideColorSupport(va_list args) {
1261 bool* outSupport = va_arg(args, bool*);
1262 return getWideColorSupport(outSupport);
1263 }
1264
dispatchGetHdrSupport(va_list args)1265 int Surface::dispatchGetHdrSupport(va_list args) {
1266 bool* outSupport = va_arg(args, bool*);
1267 return getHdrSupport(outSupport);
1268 }
1269
dispatchGetConsumerUsage64(va_list args)1270 int Surface::dispatchGetConsumerUsage64(va_list args) {
1271 uint64_t* usage = va_arg(args, uint64_t*);
1272 return getConsumerUsage(usage);
1273 }
1274
transformToDisplayInverse()1275 bool Surface::transformToDisplayInverse() {
1276 return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) ==
1277 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
1278 }
1279
connect(int api)1280 int Surface::connect(int api) {
1281 static sp<IProducerListener> listener = new DummyProducerListener();
1282 return connect(api, listener);
1283 }
1284
connect(int api,const sp<IProducerListener> & listener)1285 int Surface::connect(int api, const sp<IProducerListener>& listener) {
1286 return connect(api, listener, false);
1287 }
1288
connect(int api,const sp<IProducerListener> & listener,bool reportBufferRemoval)1289 int Surface::connect(
1290 int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) {
1291 ATRACE_CALL();
1292 ALOGV("Surface::connect");
1293 Mutex::Autolock lock(mMutex);
1294 IGraphicBufferProducer::QueueBufferOutput output;
1295 mReportRemovedBuffers = reportBufferRemoval;
1296 int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
1297 if (err == NO_ERROR) {
1298 mDefaultWidth = output.width;
1299 mDefaultHeight = output.height;
1300 mNextFrameNumber = output.nextFrameNumber;
1301
1302 // Ignore transform hint if sticky transform is set or transform to display inverse flag is
1303 // set. Transform hint should be ignored if the client is expected to always submit buffers
1304 // in the same orientation.
1305 if (mStickyTransform == 0 && !transformToDisplayInverse()) {
1306 mTransformHint = output.transformHint;
1307 }
1308
1309 mConsumerRunningBehind = (output.numPendingBuffers >= 2);
1310 }
1311 if (!err && api == NATIVE_WINDOW_API_CPU) {
1312 mConnectedToCpu = true;
1313 // Clear the dirty region in case we're switching from a non-CPU API
1314 mDirtyRegion.clear();
1315 } else if (!err) {
1316 // Initialize the dirty region for tracking surface damage
1317 mDirtyRegion = Region::INVALID_REGION;
1318 }
1319
1320 return err;
1321 }
1322
1323
disconnect(int api,IGraphicBufferProducer::DisconnectMode mode)1324 int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) {
1325 ATRACE_CALL();
1326 ALOGV("Surface::disconnect");
1327 Mutex::Autolock lock(mMutex);
1328 mRemovedBuffers.clear();
1329 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1330 mSharedBufferHasBeenQueued = false;
1331 freeAllBuffers();
1332 int err = mGraphicBufferProducer->disconnect(api, mode);
1333 if (!err) {
1334 mReqFormat = 0;
1335 mReqWidth = 0;
1336 mReqHeight = 0;
1337 mReqUsage = 0;
1338 mCrop.clear();
1339 mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
1340 mTransform = 0;
1341 mStickyTransform = 0;
1342
1343 if (api == NATIVE_WINDOW_API_CPU) {
1344 mConnectedToCpu = false;
1345 }
1346 }
1347 return err;
1348 }
1349
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)1350 int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
1351 sp<Fence>* outFence) {
1352 ATRACE_CALL();
1353 ALOGV("Surface::detachNextBuffer");
1354
1355 if (outBuffer == nullptr || outFence == nullptr) {
1356 return BAD_VALUE;
1357 }
1358
1359 Mutex::Autolock lock(mMutex);
1360 if (mReportRemovedBuffers) {
1361 mRemovedBuffers.clear();
1362 }
1363
1364 sp<GraphicBuffer> buffer(nullptr);
1365 sp<Fence> fence(nullptr);
1366 status_t result = mGraphicBufferProducer->detachNextBuffer(
1367 &buffer, &fence);
1368 if (result != NO_ERROR) {
1369 return result;
1370 }
1371
1372 *outBuffer = buffer;
1373 if (fence != nullptr && fence->isValid()) {
1374 *outFence = fence;
1375 } else {
1376 *outFence = Fence::NO_FENCE;
1377 }
1378
1379 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
1380 if (mSlots[i].buffer != nullptr &&
1381 mSlots[i].buffer->getId() == buffer->getId()) {
1382 if (mReportRemovedBuffers) {
1383 mRemovedBuffers.push_back(mSlots[i].buffer);
1384 }
1385 mSlots[i].buffer = nullptr;
1386 }
1387 }
1388
1389 return NO_ERROR;
1390 }
1391
attachBuffer(ANativeWindowBuffer * buffer)1392 int Surface::attachBuffer(ANativeWindowBuffer* buffer)
1393 {
1394 ATRACE_CALL();
1395 ALOGV("Surface::attachBuffer");
1396
1397 Mutex::Autolock lock(mMutex);
1398 if (mReportRemovedBuffers) {
1399 mRemovedBuffers.clear();
1400 }
1401
1402 sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
1403 uint32_t priorGeneration = graphicBuffer->mGenerationNumber;
1404 graphicBuffer->mGenerationNumber = mGenerationNumber;
1405 int32_t attachedSlot = -1;
1406 status_t result = mGraphicBufferProducer->attachBuffer(&attachedSlot, graphicBuffer);
1407 if (result != NO_ERROR) {
1408 ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result);
1409 graphicBuffer->mGenerationNumber = priorGeneration;
1410 return result;
1411 }
1412 if (mReportRemovedBuffers && (mSlots[attachedSlot].buffer != nullptr)) {
1413 mRemovedBuffers.push_back(mSlots[attachedSlot].buffer);
1414 }
1415 mSlots[attachedSlot].buffer = graphicBuffer;
1416
1417 return NO_ERROR;
1418 }
1419
setUsage(uint64_t reqUsage)1420 int Surface::setUsage(uint64_t reqUsage)
1421 {
1422 ALOGV("Surface::setUsage");
1423 Mutex::Autolock lock(mMutex);
1424 if (reqUsage != mReqUsage) {
1425 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1426 }
1427 mReqUsage = reqUsage;
1428 return OK;
1429 }
1430
setCrop(Rect const * rect)1431 int Surface::setCrop(Rect const* rect)
1432 {
1433 ATRACE_CALL();
1434
1435 Rect realRect(Rect::EMPTY_RECT);
1436 if (rect == nullptr || rect->isEmpty()) {
1437 realRect.clear();
1438 } else {
1439 realRect = *rect;
1440 }
1441
1442 ALOGV("Surface::setCrop rect=[%d %d %d %d]",
1443 realRect.left, realRect.top, realRect.right, realRect.bottom);
1444
1445 Mutex::Autolock lock(mMutex);
1446 mCrop = realRect;
1447 return NO_ERROR;
1448 }
1449
setBufferCount(int bufferCount)1450 int Surface::setBufferCount(int bufferCount)
1451 {
1452 ATRACE_CALL();
1453 ALOGV("Surface::setBufferCount");
1454 Mutex::Autolock lock(mMutex);
1455
1456 status_t err = NO_ERROR;
1457 if (bufferCount == 0) {
1458 err = mGraphicBufferProducer->setMaxDequeuedBufferCount(1);
1459 } else {
1460 int minUndequeuedBuffers = 0;
1461 err = mGraphicBufferProducer->query(
1462 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers);
1463 if (err == NO_ERROR) {
1464 err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
1465 bufferCount - minUndequeuedBuffers);
1466 }
1467 }
1468
1469 ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
1470 bufferCount, strerror(-err));
1471
1472 return err;
1473 }
1474
setMaxDequeuedBufferCount(int maxDequeuedBuffers)1475 int Surface::setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
1476 ATRACE_CALL();
1477 ALOGV("Surface::setMaxDequeuedBufferCount");
1478 Mutex::Autolock lock(mMutex);
1479
1480 status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
1481 maxDequeuedBuffers);
1482 ALOGE_IF(err, "IGraphicBufferProducer::setMaxDequeuedBufferCount(%d) "
1483 "returned %s", maxDequeuedBuffers, strerror(-err));
1484
1485 return err;
1486 }
1487
setAsyncMode(bool async)1488 int Surface::setAsyncMode(bool async) {
1489 ATRACE_CALL();
1490 ALOGV("Surface::setAsyncMode");
1491 Mutex::Autolock lock(mMutex);
1492
1493 status_t err = mGraphicBufferProducer->setAsyncMode(async);
1494 ALOGE_IF(err, "IGraphicBufferProducer::setAsyncMode(%d) returned %s",
1495 async, strerror(-err));
1496
1497 return err;
1498 }
1499
setSharedBufferMode(bool sharedBufferMode)1500 int Surface::setSharedBufferMode(bool sharedBufferMode) {
1501 ATRACE_CALL();
1502 ALOGV("Surface::setSharedBufferMode (%d)", sharedBufferMode);
1503 Mutex::Autolock lock(mMutex);
1504
1505 status_t err = mGraphicBufferProducer->setSharedBufferMode(
1506 sharedBufferMode);
1507 if (err == NO_ERROR) {
1508 mSharedBufferMode = sharedBufferMode;
1509 }
1510 ALOGE_IF(err, "IGraphicBufferProducer::setSharedBufferMode(%d) returned"
1511 "%s", sharedBufferMode, strerror(-err));
1512
1513 return err;
1514 }
1515
setAutoRefresh(bool autoRefresh)1516 int Surface::setAutoRefresh(bool autoRefresh) {
1517 ATRACE_CALL();
1518 ALOGV("Surface::setAutoRefresh (%d)", autoRefresh);
1519 Mutex::Autolock lock(mMutex);
1520
1521 status_t err = mGraphicBufferProducer->setAutoRefresh(autoRefresh);
1522 if (err == NO_ERROR) {
1523 mAutoRefresh = autoRefresh;
1524 }
1525 ALOGE_IF(err, "IGraphicBufferProducer::setAutoRefresh(%d) returned %s",
1526 autoRefresh, strerror(-err));
1527 return err;
1528 }
1529
setBuffersDimensions(uint32_t width,uint32_t height)1530 int Surface::setBuffersDimensions(uint32_t width, uint32_t height)
1531 {
1532 ATRACE_CALL();
1533 ALOGV("Surface::setBuffersDimensions");
1534
1535 if ((width && !height) || (!width && height))
1536 return BAD_VALUE;
1537
1538 Mutex::Autolock lock(mMutex);
1539 if (width != mReqWidth || height != mReqHeight) {
1540 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1541 }
1542 mReqWidth = width;
1543 mReqHeight = height;
1544 return NO_ERROR;
1545 }
1546
setBuffersUserDimensions(uint32_t width,uint32_t height)1547 int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height)
1548 {
1549 ATRACE_CALL();
1550 ALOGV("Surface::setBuffersUserDimensions");
1551
1552 if ((width && !height) || (!width && height))
1553 return BAD_VALUE;
1554
1555 Mutex::Autolock lock(mMutex);
1556 if (width != mUserWidth || height != mUserHeight) {
1557 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1558 }
1559 mUserWidth = width;
1560 mUserHeight = height;
1561 return NO_ERROR;
1562 }
1563
setBuffersFormat(PixelFormat format)1564 int Surface::setBuffersFormat(PixelFormat format)
1565 {
1566 ALOGV("Surface::setBuffersFormat");
1567
1568 Mutex::Autolock lock(mMutex);
1569 if (format != mReqFormat) {
1570 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1571 }
1572 mReqFormat = format;
1573 return NO_ERROR;
1574 }
1575
setScalingMode(int mode)1576 int Surface::setScalingMode(int mode)
1577 {
1578 ATRACE_CALL();
1579 ALOGV("Surface::setScalingMode(%d)", mode);
1580
1581 switch (mode) {
1582 case NATIVE_WINDOW_SCALING_MODE_FREEZE:
1583 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
1584 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
1585 case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
1586 break;
1587 default:
1588 ALOGE("unknown scaling mode: %d", mode);
1589 return BAD_VALUE;
1590 }
1591
1592 Mutex::Autolock lock(mMutex);
1593 mScalingMode = mode;
1594 return NO_ERROR;
1595 }
1596
setBuffersTransform(uint32_t transform)1597 int Surface::setBuffersTransform(uint32_t transform)
1598 {
1599 ATRACE_CALL();
1600 ALOGV("Surface::setBuffersTransform");
1601 Mutex::Autolock lock(mMutex);
1602 // Ensure NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY is sticky. If the client sets the flag, do not
1603 // override it until the surface is disconnected. This is a temporary workaround for camera
1604 // until they switch to using Buffer State Layers. Currently if client sets the buffer transform
1605 // it may be overriden by the buffer producer when the producer sets the buffer transform.
1606 if (transformToDisplayInverse()) {
1607 transform |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
1608 }
1609 mTransform = transform;
1610 return NO_ERROR;
1611 }
1612
setBuffersStickyTransform(uint32_t transform)1613 int Surface::setBuffersStickyTransform(uint32_t transform)
1614 {
1615 ATRACE_CALL();
1616 ALOGV("Surface::setBuffersStickyTransform");
1617 Mutex::Autolock lock(mMutex);
1618 mStickyTransform = transform;
1619 return NO_ERROR;
1620 }
1621
setBuffersTimestamp(int64_t timestamp)1622 int Surface::setBuffersTimestamp(int64_t timestamp)
1623 {
1624 ALOGV("Surface::setBuffersTimestamp");
1625 Mutex::Autolock lock(mMutex);
1626 mTimestamp = timestamp;
1627 return NO_ERROR;
1628 }
1629
setBuffersDataSpace(Dataspace dataSpace)1630 int Surface::setBuffersDataSpace(Dataspace dataSpace)
1631 {
1632 ALOGV("Surface::setBuffersDataSpace");
1633 Mutex::Autolock lock(mMutex);
1634 mDataSpace = dataSpace;
1635 return NO_ERROR;
1636 }
1637
setBuffersSmpte2086Metadata(const android_smpte2086_metadata * metadata)1638 int Surface::setBuffersSmpte2086Metadata(const android_smpte2086_metadata* metadata) {
1639 ALOGV("Surface::setBuffersSmpte2086Metadata");
1640 Mutex::Autolock lock(mMutex);
1641 if (metadata) {
1642 mHdrMetadata.smpte2086 = *metadata;
1643 mHdrMetadata.validTypes |= HdrMetadata::SMPTE2086;
1644 } else {
1645 mHdrMetadata.validTypes &= ~HdrMetadata::SMPTE2086;
1646 }
1647 return NO_ERROR;
1648 }
1649
setBuffersCta8613Metadata(const android_cta861_3_metadata * metadata)1650 int Surface::setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata) {
1651 ALOGV("Surface::setBuffersCta8613Metadata");
1652 Mutex::Autolock lock(mMutex);
1653 if (metadata) {
1654 mHdrMetadata.cta8613 = *metadata;
1655 mHdrMetadata.validTypes |= HdrMetadata::CTA861_3;
1656 } else {
1657 mHdrMetadata.validTypes &= ~HdrMetadata::CTA861_3;
1658 }
1659 return NO_ERROR;
1660 }
1661
setBuffersHdr10PlusMetadata(const size_t size,const uint8_t * metadata)1662 int Surface::setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata) {
1663 ALOGV("Surface::setBuffersBlobMetadata");
1664 Mutex::Autolock lock(mMutex);
1665 if (size > 0) {
1666 mHdrMetadata.hdr10plus.assign(metadata, metadata + size);
1667 mHdrMetadata.validTypes |= HdrMetadata::HDR10PLUS;
1668 } else {
1669 mHdrMetadata.validTypes &= ~HdrMetadata::HDR10PLUS;
1670 mHdrMetadata.hdr10plus.clear();
1671 }
1672 return NO_ERROR;
1673 }
1674
getBuffersDataSpace()1675 Dataspace Surface::getBuffersDataSpace() {
1676 ALOGV("Surface::getBuffersDataSpace");
1677 Mutex::Autolock lock(mMutex);
1678 return mDataSpace;
1679 }
1680
freeAllBuffers()1681 void Surface::freeAllBuffers() {
1682 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
1683 mSlots[i].buffer = nullptr;
1684 }
1685 }
1686
setSurfaceDamage(android_native_rect_t * rects,size_t numRects)1687 void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) {
1688 ATRACE_CALL();
1689 ALOGV("Surface::setSurfaceDamage");
1690 Mutex::Autolock lock(mMutex);
1691
1692 if (mConnectedToCpu || numRects == 0) {
1693 mDirtyRegion = Region::INVALID_REGION;
1694 return;
1695 }
1696
1697 mDirtyRegion.clear();
1698 for (size_t r = 0; r < numRects; ++r) {
1699 // We intentionally flip top and bottom here, since because they're
1700 // specified with a bottom-left origin, top > bottom, which fails
1701 // validation in the Region class. We will fix this up when we flip to a
1702 // top-left origin in queueBuffer.
1703 Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top);
1704 mDirtyRegion.orSelf(rect);
1705 }
1706 }
1707
1708 // ----------------------------------------------------------------------
1709 // the lock/unlock APIs must be used from the same thread
1710
copyBlt(const sp<GraphicBuffer> & dst,const sp<GraphicBuffer> & src,const Region & reg,int * dstFenceFd)1711 static status_t copyBlt(
1712 const sp<GraphicBuffer>& dst,
1713 const sp<GraphicBuffer>& src,
1714 const Region& reg,
1715 int *dstFenceFd)
1716 {
1717 if (dst->getId() == src->getId())
1718 return OK;
1719
1720 // src and dst with, height and format must be identical. no verification
1721 // is done here.
1722 status_t err;
1723 uint8_t* src_bits = nullptr;
1724 err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(),
1725 reinterpret_cast<void**>(&src_bits));
1726 ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
1727
1728 uint8_t* dst_bits = nullptr;
1729 err = dst->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(),
1730 reinterpret_cast<void**>(&dst_bits), *dstFenceFd);
1731 ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
1732 *dstFenceFd = -1;
1733
1734 Region::const_iterator head(reg.begin());
1735 Region::const_iterator tail(reg.end());
1736 if (head != tail && src_bits && dst_bits) {
1737 const size_t bpp = bytesPerPixel(src->format);
1738 const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp;
1739 const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp;
1740
1741 while (head != tail) {
1742 const Rect& r(*head++);
1743 int32_t h = r.height();
1744 if (h <= 0) continue;
1745 size_t size = static_cast<uint32_t>(r.width()) * bpp;
1746 uint8_t const * s = src_bits +
1747 static_cast<uint32_t>(r.left + src->stride * r.top) * bpp;
1748 uint8_t * d = dst_bits +
1749 static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp;
1750 if (dbpr==sbpr && size==sbpr) {
1751 size *= static_cast<size_t>(h);
1752 h = 1;
1753 }
1754 do {
1755 memcpy(d, s, size);
1756 d += dbpr;
1757 s += sbpr;
1758 } while (--h > 0);
1759 }
1760 }
1761
1762 if (src_bits)
1763 src->unlock();
1764
1765 if (dst_bits)
1766 dst->unlockAsync(dstFenceFd);
1767
1768 return err;
1769 }
1770
1771 // ----------------------------------------------------------------------------
1772
lock(ANativeWindow_Buffer * outBuffer,ARect * inOutDirtyBounds)1773 status_t Surface::lock(
1774 ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
1775 {
1776 if (mLockedBuffer != nullptr) {
1777 ALOGE("Surface::lock failed, already locked");
1778 return INVALID_OPERATION;
1779 }
1780
1781 if (!mConnectedToCpu) {
1782 int err = Surface::connect(NATIVE_WINDOW_API_CPU);
1783 if (err) {
1784 return err;
1785 }
1786 // we're intending to do software rendering from this point
1787 setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
1788 }
1789
1790 ANativeWindowBuffer* out;
1791 int fenceFd = -1;
1792 status_t err = dequeueBuffer(&out, &fenceFd);
1793 ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
1794 if (err == NO_ERROR) {
1795 sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
1796 const Rect bounds(backBuffer->width, backBuffer->height);
1797
1798 Region newDirtyRegion;
1799 if (inOutDirtyBounds) {
1800 newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
1801 newDirtyRegion.andSelf(bounds);
1802 } else {
1803 newDirtyRegion.set(bounds);
1804 }
1805
1806 // figure out if we can copy the frontbuffer back
1807 const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
1808 const bool canCopyBack = (frontBuffer != nullptr &&
1809 backBuffer->width == frontBuffer->width &&
1810 backBuffer->height == frontBuffer->height &&
1811 backBuffer->format == frontBuffer->format);
1812
1813 if (canCopyBack) {
1814 // copy the area that is invalid and not repainted this round
1815 const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
1816 if (!copyback.isEmpty()) {
1817 copyBlt(backBuffer, frontBuffer, copyback, &fenceFd);
1818 }
1819 } else {
1820 // if we can't copy-back anything, modify the user's dirty
1821 // region to make sure they redraw the whole buffer
1822 newDirtyRegion.set(bounds);
1823 mDirtyRegion.clear();
1824 Mutex::Autolock lock(mMutex);
1825 for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
1826 mSlots[i].dirtyRegion.clear();
1827 }
1828 }
1829
1830
1831 { // scope for the lock
1832 Mutex::Autolock lock(mMutex);
1833 int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
1834 if (backBufferSlot >= 0) {
1835 Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
1836 mDirtyRegion.subtract(dirtyRegion);
1837 dirtyRegion = newDirtyRegion;
1838 }
1839 }
1840
1841 mDirtyRegion.orSelf(newDirtyRegion);
1842 if (inOutDirtyBounds) {
1843 *inOutDirtyBounds = newDirtyRegion.getBounds();
1844 }
1845
1846 void* vaddr;
1847 status_t res = backBuffer->lockAsync(
1848 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1849 newDirtyRegion.bounds(), &vaddr, fenceFd);
1850
1851 ALOGW_IF(res, "failed locking buffer (handle = %p)",
1852 backBuffer->handle);
1853
1854 if (res != 0) {
1855 err = INVALID_OPERATION;
1856 } else {
1857 mLockedBuffer = backBuffer;
1858 outBuffer->width = backBuffer->width;
1859 outBuffer->height = backBuffer->height;
1860 outBuffer->stride = backBuffer->stride;
1861 outBuffer->format = backBuffer->format;
1862 outBuffer->bits = vaddr;
1863 }
1864 }
1865 return err;
1866 }
1867
unlockAndPost()1868 status_t Surface::unlockAndPost()
1869 {
1870 if (mLockedBuffer == nullptr) {
1871 ALOGE("Surface::unlockAndPost failed, no locked buffer");
1872 return INVALID_OPERATION;
1873 }
1874
1875 int fd = -1;
1876 status_t err = mLockedBuffer->unlockAsync(&fd);
1877 ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
1878
1879 err = queueBuffer(mLockedBuffer.get(), fd);
1880 ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
1881 mLockedBuffer->handle, strerror(-err));
1882
1883 mPostedBuffer = mLockedBuffer;
1884 mLockedBuffer = nullptr;
1885 return err;
1886 }
1887
waitForNextFrame(uint64_t lastFrame,nsecs_t timeout)1888 bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) {
1889 Mutex::Autolock lock(mMutex);
1890 if (mNextFrameNumber > lastFrame) {
1891 return true;
1892 }
1893 return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK;
1894 }
1895
getUniqueId(uint64_t * outId) const1896 status_t Surface::getUniqueId(uint64_t* outId) const {
1897 Mutex::Autolock lock(mMutex);
1898 return mGraphicBufferProducer->getUniqueId(outId);
1899 }
1900
getConsumerUsage(uint64_t * outUsage) const1901 int Surface::getConsumerUsage(uint64_t* outUsage) const {
1902 Mutex::Autolock lock(mMutex);
1903 return mGraphicBufferProducer->getConsumerUsage(outUsage);
1904 }
1905
getLastDequeueStartTime() const1906 nsecs_t Surface::getLastDequeueStartTime() const {
1907 Mutex::Autolock lock(mMutex);
1908 return mLastDequeueStartTime;
1909 }
1910
getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>> * out)1911 status_t Surface::getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out) {
1912 if (out == nullptr) {
1913 ALOGE("%s: out must not be null!", __FUNCTION__);
1914 return BAD_VALUE;
1915 }
1916
1917 Mutex::Autolock lock(mMutex);
1918 *out = mRemovedBuffers;
1919 mRemovedBuffers.clear();
1920 return OK;
1921 }
1922
attachAndQueueBuffer(Surface * surface,sp<GraphicBuffer> buffer)1923 status_t Surface::attachAndQueueBuffer(Surface* surface, sp<GraphicBuffer> buffer) {
1924 if (buffer == nullptr) {
1925 return BAD_VALUE;
1926 }
1927 int err = static_cast<ANativeWindow*>(surface)->perform(surface, NATIVE_WINDOW_API_CONNECT,
1928 NATIVE_WINDOW_API_CPU);
1929 if (err != OK) {
1930 return err;
1931 }
1932 err = surface->attachBuffer(buffer->getNativeBuffer());
1933 if (err != OK) {
1934 return err;
1935 }
1936 err = static_cast<ANativeWindow*>(surface)->queueBuffer(surface, buffer->getNativeBuffer(), -1);
1937 if (err != OK) {
1938 return err;
1939 }
1940 err = surface->disconnect(NATIVE_WINDOW_API_CPU);
1941 return err;
1942 }
1943
1944 }; // namespace android
1945