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