1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2010 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "Surface"
18*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_GRAPHICS
19*38e8c45fSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
20*38e8c45fSAndroid Build Coastguard Worker
21*38e8c45fSAndroid Build Coastguard Worker #include <gui/Surface.h>
22*38e8c45fSAndroid Build Coastguard Worker
23*38e8c45fSAndroid Build Coastguard Worker #include <condition_variable>
24*38e8c45fSAndroid Build Coastguard Worker #include <cstddef>
25*38e8c45fSAndroid Build Coastguard Worker #include <cstdint>
26*38e8c45fSAndroid Build Coastguard Worker #include <deque>
27*38e8c45fSAndroid Build Coastguard Worker #include <mutex>
28*38e8c45fSAndroid Build Coastguard Worker #include <thread>
29*38e8c45fSAndroid Build Coastguard Worker
30*38e8c45fSAndroid Build Coastguard Worker #include <inttypes.h>
31*38e8c45fSAndroid Build Coastguard Worker
32*38e8c45fSAndroid Build Coastguard Worker #include <android/gui/DisplayStatInfo.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <android/native_window.h>
34*38e8c45fSAndroid Build Coastguard Worker
35*38e8c45fSAndroid Build Coastguard Worker #include <gui/FenceMonitor.h>
36*38e8c45fSAndroid Build Coastguard Worker #include <gui/TraceUtils.h>
37*38e8c45fSAndroid Build Coastguard Worker #include <utils/Log.h>
38*38e8c45fSAndroid Build Coastguard Worker #include <utils/NativeHandle.h>
39*38e8c45fSAndroid Build Coastguard Worker #include <utils/Trace.h>
40*38e8c45fSAndroid Build Coastguard Worker
41*38e8c45fSAndroid Build Coastguard Worker #include <ui/DynamicDisplayInfo.h>
42*38e8c45fSAndroid Build Coastguard Worker #include <ui/Fence.h>
43*38e8c45fSAndroid Build Coastguard Worker #include <ui/GraphicBuffer.h>
44*38e8c45fSAndroid Build Coastguard Worker #include <ui/Region.h>
45*38e8c45fSAndroid Build Coastguard Worker
46*38e8c45fSAndroid Build Coastguard Worker #include <gui/AidlUtil.h>
47*38e8c45fSAndroid Build Coastguard Worker #include <gui/BufferItem.h>
48*38e8c45fSAndroid Build Coastguard Worker
49*38e8c45fSAndroid Build Coastguard Worker #include <gui/ISurfaceComposer.h>
50*38e8c45fSAndroid Build Coastguard Worker #include <gui/LayerState.h>
51*38e8c45fSAndroid Build Coastguard Worker #include <private/gui/ComposerService.h>
52*38e8c45fSAndroid Build Coastguard Worker #include <private/gui/ComposerServiceAIDL.h>
53*38e8c45fSAndroid Build Coastguard Worker
54*38e8c45fSAndroid Build Coastguard Worker #include <com_android_graphics_libgui_flags.h>
55*38e8c45fSAndroid Build Coastguard Worker
56*38e8c45fSAndroid Build Coastguard Worker namespace android {
57*38e8c45fSAndroid Build Coastguard Worker
58*38e8c45fSAndroid Build Coastguard Worker using namespace com::android::graphics::libgui;
59*38e8c45fSAndroid Build Coastguard Worker using gui::aidl_utils::statusTFromBinderStatus;
60*38e8c45fSAndroid Build Coastguard Worker using ui::Dataspace;
61*38e8c45fSAndroid Build Coastguard Worker
62*38e8c45fSAndroid Build Coastguard Worker namespace {
63*38e8c45fSAndroid Build Coastguard Worker
64*38e8c45fSAndroid Build Coastguard Worker enum {
65*38e8c45fSAndroid Build Coastguard Worker // moved from nativewindow/include/system/window.h, to be removed
66*38e8c45fSAndroid Build Coastguard Worker NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT = 28,
67*38e8c45fSAndroid Build Coastguard Worker NATIVE_WINDOW_GET_HDR_SUPPORT = 29,
68*38e8c45fSAndroid Build Coastguard Worker };
69*38e8c45fSAndroid Build Coastguard Worker
isInterceptorRegistrationOp(int op)70*38e8c45fSAndroid Build Coastguard Worker bool isInterceptorRegistrationOp(int op) {
71*38e8c45fSAndroid Build Coastguard Worker return op == NATIVE_WINDOW_SET_CANCEL_INTERCEPTOR ||
72*38e8c45fSAndroid Build Coastguard Worker op == NATIVE_WINDOW_SET_DEQUEUE_INTERCEPTOR ||
73*38e8c45fSAndroid Build Coastguard Worker op == NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR ||
74*38e8c45fSAndroid Build Coastguard Worker op == NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR ||
75*38e8c45fSAndroid Build Coastguard Worker op == NATIVE_WINDOW_SET_QUERY_INTERCEPTOR;
76*38e8c45fSAndroid Build Coastguard Worker }
77*38e8c45fSAndroid Build Coastguard Worker
78*38e8c45fSAndroid Build Coastguard Worker } // namespace
79*38e8c45fSAndroid Build Coastguard Worker
80*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
ProducerDeathListenerProxy(wp<SurfaceListener> surfaceListener)81*38e8c45fSAndroid Build Coastguard Worker Surface::ProducerDeathListenerProxy::ProducerDeathListenerProxy(wp<SurfaceListener> surfaceListener)
82*38e8c45fSAndroid Build Coastguard Worker : mSurfaceListener(surfaceListener) {}
83*38e8c45fSAndroid Build Coastguard Worker
binderDied(const wp<IBinder> &)84*38e8c45fSAndroid Build Coastguard Worker void Surface::ProducerDeathListenerProxy::binderDied(const wp<IBinder>&) {
85*38e8c45fSAndroid Build Coastguard Worker sp<SurfaceListener> surfaceListener = mSurfaceListener.promote();
86*38e8c45fSAndroid Build Coastguard Worker if (!surfaceListener) {
87*38e8c45fSAndroid Build Coastguard Worker return;
88*38e8c45fSAndroid Build Coastguard Worker }
89*38e8c45fSAndroid Build Coastguard Worker
90*38e8c45fSAndroid Build Coastguard Worker if (surfaceListener->needsDeathNotify()) {
91*38e8c45fSAndroid Build Coastguard Worker surfaceListener->onRemoteDied();
92*38e8c45fSAndroid Build Coastguard Worker }
93*38e8c45fSAndroid Build Coastguard Worker }
94*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
95*38e8c45fSAndroid Build Coastguard Worker
Surface(const sp<IGraphicBufferProducer> & bufferProducer,bool controlledByApp,const sp<IBinder> & surfaceControlHandle)96*38e8c45fSAndroid Build Coastguard Worker Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp,
97*38e8c45fSAndroid Build Coastguard Worker const sp<IBinder>& surfaceControlHandle)
98*38e8c45fSAndroid Build Coastguard Worker : mGraphicBufferProducer(bufferProducer),
99*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
100*38e8c45fSAndroid Build Coastguard Worker mSurfaceDeathListener(nullptr),
101*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
102*38e8c45fSAndroid Build Coastguard Worker mCrop(Rect::EMPTY_RECT),
103*38e8c45fSAndroid Build Coastguard Worker mBufferAge(0),
104*38e8c45fSAndroid Build Coastguard Worker mGenerationNumber(0),
105*38e8c45fSAndroid Build Coastguard Worker mSharedBufferMode(false),
106*38e8c45fSAndroid Build Coastguard Worker mAutoRefresh(false),
107*38e8c45fSAndroid Build Coastguard Worker mAutoPrerotation(false),
108*38e8c45fSAndroid Build Coastguard Worker mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
109*38e8c45fSAndroid Build Coastguard Worker mSharedBufferHasBeenQueued(false),
110*38e8c45fSAndroid Build Coastguard Worker mQueriedSupportedTimestamps(false),
111*38e8c45fSAndroid Build Coastguard Worker mFrameTimestampsSupportsPresent(false),
112*38e8c45fSAndroid Build Coastguard Worker mEnableFrameTimestamps(false),
113*38e8c45fSAndroid Build Coastguard Worker mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) {
114*38e8c45fSAndroid Build Coastguard Worker // Initialize the ANativeWindow function pointers.
115*38e8c45fSAndroid Build Coastguard Worker ANativeWindow::setSwapInterval = hook_setSwapInterval;
116*38e8c45fSAndroid Build Coastguard Worker ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
117*38e8c45fSAndroid Build Coastguard Worker ANativeWindow::cancelBuffer = hook_cancelBuffer;
118*38e8c45fSAndroid Build Coastguard Worker ANativeWindow::queueBuffer = hook_queueBuffer;
119*38e8c45fSAndroid Build Coastguard Worker ANativeWindow::query = hook_query;
120*38e8c45fSAndroid Build Coastguard Worker ANativeWindow::perform = hook_perform;
121*38e8c45fSAndroid Build Coastguard Worker
122*38e8c45fSAndroid Build Coastguard Worker ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
123*38e8c45fSAndroid Build Coastguard Worker ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
124*38e8c45fSAndroid Build Coastguard Worker ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
125*38e8c45fSAndroid Build Coastguard Worker ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
126*38e8c45fSAndroid Build Coastguard Worker
127*38e8c45fSAndroid Build Coastguard Worker const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
128*38e8c45fSAndroid Build Coastguard Worker const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
129*38e8c45fSAndroid Build Coastguard Worker
130*38e8c45fSAndroid Build Coastguard Worker mReqWidth = 0;
131*38e8c45fSAndroid Build Coastguard Worker mReqHeight = 0;
132*38e8c45fSAndroid Build Coastguard Worker mReqFormat = 0;
133*38e8c45fSAndroid Build Coastguard Worker mReqUsage = 0;
134*38e8c45fSAndroid Build Coastguard Worker mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
135*38e8c45fSAndroid Build Coastguard Worker mDataSpace = Dataspace::UNKNOWN;
136*38e8c45fSAndroid Build Coastguard Worker mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
137*38e8c45fSAndroid Build Coastguard Worker mTransform = 0;
138*38e8c45fSAndroid Build Coastguard Worker mStickyTransform = 0;
139*38e8c45fSAndroid Build Coastguard Worker mDefaultWidth = 0;
140*38e8c45fSAndroid Build Coastguard Worker mDefaultHeight = 0;
141*38e8c45fSAndroid Build Coastguard Worker mUserWidth = 0;
142*38e8c45fSAndroid Build Coastguard Worker mUserHeight = 0;
143*38e8c45fSAndroid Build Coastguard Worker mTransformHint = 0;
144*38e8c45fSAndroid Build Coastguard Worker mConsumerRunningBehind = false;
145*38e8c45fSAndroid Build Coastguard Worker mConnectedToCpu = false;
146*38e8c45fSAndroid Build Coastguard Worker mProducerControlledByApp = controlledByApp;
147*38e8c45fSAndroid Build Coastguard Worker mSwapIntervalZero = false;
148*38e8c45fSAndroid Build Coastguard Worker mMaxBufferCount = NUM_BUFFER_SLOTS;
149*38e8c45fSAndroid Build Coastguard Worker mSurfaceControlHandle = surfaceControlHandle;
150*38e8c45fSAndroid Build Coastguard Worker }
151*38e8c45fSAndroid Build Coastguard Worker
~Surface()152*38e8c45fSAndroid Build Coastguard Worker Surface::~Surface() {
153*38e8c45fSAndroid Build Coastguard Worker if (mConnectedToCpu) {
154*38e8c45fSAndroid Build Coastguard Worker Surface::disconnect(NATIVE_WINDOW_API_CPU);
155*38e8c45fSAndroid Build Coastguard Worker }
156*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
157*38e8c45fSAndroid Build Coastguard Worker if (mSurfaceDeathListener != nullptr) {
158*38e8c45fSAndroid Build Coastguard Worker IInterface::asBinder(mGraphicBufferProducer)->unlinkToDeath(mSurfaceDeathListener);
159*38e8c45fSAndroid Build Coastguard Worker mSurfaceDeathListener = nullptr;
160*38e8c45fSAndroid Build Coastguard Worker }
161*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
162*38e8c45fSAndroid Build Coastguard Worker }
163*38e8c45fSAndroid Build Coastguard Worker
composerService() const164*38e8c45fSAndroid Build Coastguard Worker sp<ISurfaceComposer> Surface::composerService() const {
165*38e8c45fSAndroid Build Coastguard Worker return ComposerService::getComposerService();
166*38e8c45fSAndroid Build Coastguard Worker }
167*38e8c45fSAndroid Build Coastguard Worker
composerServiceAIDL() const168*38e8c45fSAndroid Build Coastguard Worker sp<gui::ISurfaceComposer> Surface::composerServiceAIDL() const {
169*38e8c45fSAndroid Build Coastguard Worker return ComposerServiceAIDL::getComposerService();
170*38e8c45fSAndroid Build Coastguard Worker }
171*38e8c45fSAndroid Build Coastguard Worker
now() const172*38e8c45fSAndroid Build Coastguard Worker nsecs_t Surface::now() const {
173*38e8c45fSAndroid Build Coastguard Worker return systemTime();
174*38e8c45fSAndroid Build Coastguard Worker }
175*38e8c45fSAndroid Build Coastguard Worker
getIGraphicBufferProducer() const176*38e8c45fSAndroid Build Coastguard Worker sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const {
177*38e8c45fSAndroid Build Coastguard Worker return mGraphicBufferProducer;
178*38e8c45fSAndroid Build Coastguard Worker }
179*38e8c45fSAndroid Build Coastguard Worker
setSidebandStream(const sp<NativeHandle> & stream)180*38e8c45fSAndroid Build Coastguard Worker void Surface::setSidebandStream(const sp<NativeHandle>& stream) {
181*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->setSidebandStream(stream);
182*38e8c45fSAndroid Build Coastguard Worker }
183*38e8c45fSAndroid Build Coastguard Worker
allocateBuffers()184*38e8c45fSAndroid Build Coastguard Worker void Surface::allocateBuffers() {
185*38e8c45fSAndroid Build Coastguard Worker uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth;
186*38e8c45fSAndroid Build Coastguard Worker uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight;
187*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->allocateBuffers(reqWidth, reqHeight,
188*38e8c45fSAndroid Build Coastguard Worker mReqFormat, mReqUsage);
189*38e8c45fSAndroid Build Coastguard Worker }
190*38e8c45fSAndroid Build Coastguard Worker
191*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
allowAllocation(bool allowAllocation)192*38e8c45fSAndroid Build Coastguard Worker status_t Surface::allowAllocation(bool allowAllocation) {
193*38e8c45fSAndroid Build Coastguard Worker return mGraphicBufferProducer->allowAllocation(allowAllocation);
194*38e8c45fSAndroid Build Coastguard Worker }
195*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
196*38e8c45fSAndroid Build Coastguard Worker
setGenerationNumber(uint32_t generation)197*38e8c45fSAndroid Build Coastguard Worker status_t Surface::setGenerationNumber(uint32_t generation) {
198*38e8c45fSAndroid Build Coastguard Worker status_t result = mGraphicBufferProducer->setGenerationNumber(generation);
199*38e8c45fSAndroid Build Coastguard Worker if (result == NO_ERROR) {
200*38e8c45fSAndroid Build Coastguard Worker mGenerationNumber = generation;
201*38e8c45fSAndroid Build Coastguard Worker }
202*38e8c45fSAndroid Build Coastguard Worker return result;
203*38e8c45fSAndroid Build Coastguard Worker }
204*38e8c45fSAndroid Build Coastguard Worker
getNextFrameNumber() const205*38e8c45fSAndroid Build Coastguard Worker uint64_t Surface::getNextFrameNumber() const {
206*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
207*38e8c45fSAndroid Build Coastguard Worker return mNextFrameNumber;
208*38e8c45fSAndroid Build Coastguard Worker }
209*38e8c45fSAndroid Build Coastguard Worker
getConsumerName() const210*38e8c45fSAndroid Build Coastguard Worker String8 Surface::getConsumerName() const {
211*38e8c45fSAndroid Build Coastguard Worker return mGraphicBufferProducer->getConsumerName();
212*38e8c45fSAndroid Build Coastguard Worker }
213*38e8c45fSAndroid Build Coastguard Worker
setDequeueTimeout(nsecs_t timeout)214*38e8c45fSAndroid Build Coastguard Worker status_t Surface::setDequeueTimeout(nsecs_t timeout) {
215*38e8c45fSAndroid Build Coastguard Worker return mGraphicBufferProducer->setDequeueTimeout(timeout);
216*38e8c45fSAndroid Build Coastguard Worker }
217*38e8c45fSAndroid Build Coastguard Worker
getLastQueuedBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence,float outTransformMatrix[16])218*38e8c45fSAndroid Build Coastguard Worker status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
219*38e8c45fSAndroid Build Coastguard Worker sp<Fence>* outFence, float outTransformMatrix[16]) {
220*38e8c45fSAndroid Build Coastguard Worker return mGraphicBufferProducer->getLastQueuedBuffer(outBuffer, outFence,
221*38e8c45fSAndroid Build Coastguard Worker outTransformMatrix);
222*38e8c45fSAndroid Build Coastguard Worker }
223*38e8c45fSAndroid Build Coastguard Worker
getDisplayRefreshCycleDuration(nsecs_t * outRefreshDuration)224*38e8c45fSAndroid Build Coastguard Worker status_t Surface::getDisplayRefreshCycleDuration(nsecs_t* outRefreshDuration) {
225*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
226*38e8c45fSAndroid Build Coastguard Worker
227*38e8c45fSAndroid Build Coastguard Worker gui::DisplayStatInfo stats;
228*38e8c45fSAndroid Build Coastguard Worker binder::Status status = composerServiceAIDL()->getDisplayStats(nullptr, &stats);
229*38e8c45fSAndroid Build Coastguard Worker if (!status.isOk()) {
230*38e8c45fSAndroid Build Coastguard Worker return statusTFromBinderStatus(status);
231*38e8c45fSAndroid Build Coastguard Worker }
232*38e8c45fSAndroid Build Coastguard Worker
233*38e8c45fSAndroid Build Coastguard Worker *outRefreshDuration = stats.vsyncPeriod;
234*38e8c45fSAndroid Build Coastguard Worker
235*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
236*38e8c45fSAndroid Build Coastguard Worker }
237*38e8c45fSAndroid Build Coastguard Worker
enableFrameTimestamps(bool enable)238*38e8c45fSAndroid Build Coastguard Worker void Surface::enableFrameTimestamps(bool enable) {
239*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
240*38e8c45fSAndroid Build Coastguard Worker // If going from disabled to enabled, get the initial values for
241*38e8c45fSAndroid Build Coastguard Worker // compositor and display timing.
242*38e8c45fSAndroid Build Coastguard Worker if (!mEnableFrameTimestamps && enable) {
243*38e8c45fSAndroid Build Coastguard Worker FrameEventHistoryDelta delta;
244*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->getFrameTimestamps(&delta);
245*38e8c45fSAndroid Build Coastguard Worker mFrameEventHistory->applyDelta(delta);
246*38e8c45fSAndroid Build Coastguard Worker }
247*38e8c45fSAndroid Build Coastguard Worker mEnableFrameTimestamps = enable;
248*38e8c45fSAndroid Build Coastguard Worker }
249*38e8c45fSAndroid Build Coastguard Worker
getCompositorTiming(nsecs_t * compositeDeadline,nsecs_t * compositeInterval,nsecs_t * compositeToPresentLatency)250*38e8c45fSAndroid Build Coastguard Worker status_t Surface::getCompositorTiming(
251*38e8c45fSAndroid Build Coastguard Worker nsecs_t* compositeDeadline, nsecs_t* compositeInterval,
252*38e8c45fSAndroid Build Coastguard Worker nsecs_t* compositeToPresentLatency) {
253*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
254*38e8c45fSAndroid Build Coastguard Worker if (!mEnableFrameTimestamps) {
255*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
256*38e8c45fSAndroid Build Coastguard Worker }
257*38e8c45fSAndroid Build Coastguard Worker
258*38e8c45fSAndroid Build Coastguard Worker if (compositeDeadline != nullptr) {
259*38e8c45fSAndroid Build Coastguard Worker *compositeDeadline =
260*38e8c45fSAndroid Build Coastguard Worker mFrameEventHistory->getNextCompositeDeadline(now());
261*38e8c45fSAndroid Build Coastguard Worker }
262*38e8c45fSAndroid Build Coastguard Worker if (compositeInterval != nullptr) {
263*38e8c45fSAndroid Build Coastguard Worker *compositeInterval = mFrameEventHistory->getCompositeInterval();
264*38e8c45fSAndroid Build Coastguard Worker }
265*38e8c45fSAndroid Build Coastguard Worker if (compositeToPresentLatency != nullptr) {
266*38e8c45fSAndroid Build Coastguard Worker *compositeToPresentLatency =
267*38e8c45fSAndroid Build Coastguard Worker mFrameEventHistory->getCompositeToPresentLatency();
268*38e8c45fSAndroid Build Coastguard Worker }
269*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
270*38e8c45fSAndroid Build Coastguard Worker }
271*38e8c45fSAndroid Build Coastguard Worker
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)272*38e8c45fSAndroid Build Coastguard Worker static bool checkConsumerForUpdates(
273*38e8c45fSAndroid Build Coastguard Worker const FrameEvents* e, const uint64_t lastFrameNumber,
274*38e8c45fSAndroid Build Coastguard Worker const nsecs_t* outLatchTime,
275*38e8c45fSAndroid Build Coastguard Worker const nsecs_t* outFirstRefreshStartTime,
276*38e8c45fSAndroid Build Coastguard Worker const nsecs_t* outLastRefreshStartTime,
277*38e8c45fSAndroid Build Coastguard Worker const nsecs_t* outGpuCompositionDoneTime,
278*38e8c45fSAndroid Build Coastguard Worker const nsecs_t* outDisplayPresentTime,
279*38e8c45fSAndroid Build Coastguard Worker const nsecs_t* outDequeueReadyTime,
280*38e8c45fSAndroid Build Coastguard Worker const nsecs_t* outReleaseTime) {
281*38e8c45fSAndroid Build Coastguard Worker bool checkForLatch = (outLatchTime != nullptr) && !e->hasLatchInfo();
282*38e8c45fSAndroid Build Coastguard Worker bool checkForFirstRefreshStart = (outFirstRefreshStartTime != nullptr) &&
283*38e8c45fSAndroid Build Coastguard Worker !e->hasFirstRefreshStartInfo();
284*38e8c45fSAndroid Build Coastguard Worker bool checkForGpuCompositionDone = (outGpuCompositionDoneTime != nullptr) &&
285*38e8c45fSAndroid Build Coastguard Worker !e->hasGpuCompositionDoneInfo();
286*38e8c45fSAndroid Build Coastguard Worker bool checkForDisplayPresent = (outDisplayPresentTime != nullptr) &&
287*38e8c45fSAndroid Build Coastguard Worker !e->hasDisplayPresentInfo();
288*38e8c45fSAndroid Build Coastguard Worker
289*38e8c45fSAndroid Build Coastguard Worker // LastRefreshStart, DequeueReady, and Release are never available for the
290*38e8c45fSAndroid Build Coastguard Worker // last frame.
291*38e8c45fSAndroid Build Coastguard Worker bool checkForLastRefreshStart = (outLastRefreshStartTime != nullptr) &&
292*38e8c45fSAndroid Build Coastguard Worker !e->hasLastRefreshStartInfo() &&
293*38e8c45fSAndroid Build Coastguard Worker (e->frameNumber != lastFrameNumber);
294*38e8c45fSAndroid Build Coastguard Worker bool checkForDequeueReady = (outDequeueReadyTime != nullptr) &&
295*38e8c45fSAndroid Build Coastguard Worker !e->hasDequeueReadyInfo() && (e->frameNumber != lastFrameNumber);
296*38e8c45fSAndroid Build Coastguard Worker bool checkForRelease = (outReleaseTime != nullptr) &&
297*38e8c45fSAndroid Build Coastguard Worker !e->hasReleaseInfo() && (e->frameNumber != lastFrameNumber);
298*38e8c45fSAndroid Build Coastguard Worker
299*38e8c45fSAndroid Build Coastguard Worker // RequestedPresent and Acquire info are always available producer-side.
300*38e8c45fSAndroid Build Coastguard Worker return checkForLatch || checkForFirstRefreshStart ||
301*38e8c45fSAndroid Build Coastguard Worker checkForLastRefreshStart || checkForGpuCompositionDone ||
302*38e8c45fSAndroid Build Coastguard Worker checkForDisplayPresent || checkForDequeueReady || checkForRelease;
303*38e8c45fSAndroid Build Coastguard Worker }
304*38e8c45fSAndroid Build Coastguard Worker
getFrameTimestamp(nsecs_t * dst,const nsecs_t & src)305*38e8c45fSAndroid Build Coastguard Worker static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) {
306*38e8c45fSAndroid Build Coastguard Worker if (dst != nullptr) {
307*38e8c45fSAndroid Build Coastguard Worker // We always get valid timestamps for these eventually.
308*38e8c45fSAndroid Build Coastguard Worker *dst = (src == FrameEvents::TIMESTAMP_PENDING) ?
309*38e8c45fSAndroid Build Coastguard Worker NATIVE_WINDOW_TIMESTAMP_PENDING : src;
310*38e8c45fSAndroid Build Coastguard Worker }
311*38e8c45fSAndroid Build Coastguard Worker }
312*38e8c45fSAndroid Build Coastguard Worker
getFrameTimestampFence(nsecs_t * dst,const std::shared_ptr<FenceTime> & src,bool fenceShouldBeKnown)313*38e8c45fSAndroid Build Coastguard Worker static void getFrameTimestampFence(nsecs_t *dst,
314*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<FenceTime>& src, bool fenceShouldBeKnown) {
315*38e8c45fSAndroid Build Coastguard Worker if (dst != nullptr) {
316*38e8c45fSAndroid Build Coastguard Worker if (!fenceShouldBeKnown) {
317*38e8c45fSAndroid Build Coastguard Worker *dst = NATIVE_WINDOW_TIMESTAMP_PENDING;
318*38e8c45fSAndroid Build Coastguard Worker return;
319*38e8c45fSAndroid Build Coastguard Worker }
320*38e8c45fSAndroid Build Coastguard Worker
321*38e8c45fSAndroid Build Coastguard Worker nsecs_t signalTime = src->getSignalTime();
322*38e8c45fSAndroid Build Coastguard Worker *dst = (signalTime == Fence::SIGNAL_TIME_PENDING) ?
323*38e8c45fSAndroid Build Coastguard Worker NATIVE_WINDOW_TIMESTAMP_PENDING :
324*38e8c45fSAndroid Build Coastguard Worker (signalTime == Fence::SIGNAL_TIME_INVALID) ?
325*38e8c45fSAndroid Build Coastguard Worker NATIVE_WINDOW_TIMESTAMP_INVALID :
326*38e8c45fSAndroid Build Coastguard Worker signalTime;
327*38e8c45fSAndroid Build Coastguard Worker }
328*38e8c45fSAndroid Build Coastguard Worker }
329*38e8c45fSAndroid Build Coastguard Worker
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)330*38e8c45fSAndroid Build Coastguard Worker status_t Surface::getFrameTimestamps(uint64_t frameNumber,
331*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime,
332*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outLatchTime, nsecs_t* outFirstRefreshStartTime,
333*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outLastRefreshStartTime, nsecs_t* outGpuCompositionDoneTime,
334*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outDisplayPresentTime, nsecs_t* outDequeueReadyTime,
335*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outReleaseTime) {
336*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
337*38e8c45fSAndroid Build Coastguard Worker
338*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
339*38e8c45fSAndroid Build Coastguard Worker
340*38e8c45fSAndroid Build Coastguard Worker if (!mEnableFrameTimestamps) {
341*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
342*38e8c45fSAndroid Build Coastguard Worker }
343*38e8c45fSAndroid Build Coastguard Worker
344*38e8c45fSAndroid Build Coastguard Worker // Verify the requested timestamps are supported.
345*38e8c45fSAndroid Build Coastguard Worker querySupportedTimestampsLocked();
346*38e8c45fSAndroid Build Coastguard Worker if (outDisplayPresentTime != nullptr && !mFrameTimestampsSupportsPresent) {
347*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
348*38e8c45fSAndroid Build Coastguard Worker }
349*38e8c45fSAndroid Build Coastguard Worker
350*38e8c45fSAndroid Build Coastguard Worker FrameEvents* events = mFrameEventHistory->getFrame(frameNumber);
351*38e8c45fSAndroid Build Coastguard Worker if (events == nullptr) {
352*38e8c45fSAndroid Build Coastguard Worker // If the entry isn't available in the producer, it's definitely not
353*38e8c45fSAndroid Build Coastguard Worker // available in the consumer.
354*38e8c45fSAndroid Build Coastguard Worker return NAME_NOT_FOUND;
355*38e8c45fSAndroid Build Coastguard Worker }
356*38e8c45fSAndroid Build Coastguard Worker
357*38e8c45fSAndroid Build Coastguard Worker // Update our cache of events if the requested events are not available.
358*38e8c45fSAndroid Build Coastguard Worker if (checkConsumerForUpdates(events, mLastFrameNumber,
359*38e8c45fSAndroid Build Coastguard Worker outLatchTime, outFirstRefreshStartTime, outLastRefreshStartTime,
360*38e8c45fSAndroid Build Coastguard Worker outGpuCompositionDoneTime, outDisplayPresentTime,
361*38e8c45fSAndroid Build Coastguard Worker outDequeueReadyTime, outReleaseTime)) {
362*38e8c45fSAndroid Build Coastguard Worker FrameEventHistoryDelta delta;
363*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->getFrameTimestamps(&delta);
364*38e8c45fSAndroid Build Coastguard Worker mFrameEventHistory->applyDelta(delta);
365*38e8c45fSAndroid Build Coastguard Worker events = mFrameEventHistory->getFrame(frameNumber);
366*38e8c45fSAndroid Build Coastguard Worker }
367*38e8c45fSAndroid Build Coastguard Worker
368*38e8c45fSAndroid Build Coastguard Worker if (events == nullptr) {
369*38e8c45fSAndroid Build Coastguard Worker // The entry was available before the update, but was overwritten
370*38e8c45fSAndroid Build Coastguard Worker // after the update. Make sure not to send the wrong frame's data.
371*38e8c45fSAndroid Build Coastguard Worker return NAME_NOT_FOUND;
372*38e8c45fSAndroid Build Coastguard Worker }
373*38e8c45fSAndroid Build Coastguard Worker
374*38e8c45fSAndroid Build Coastguard Worker getFrameTimestamp(outRequestedPresentTime, events->requestedPresentTime);
375*38e8c45fSAndroid Build Coastguard Worker getFrameTimestamp(outLatchTime, events->latchTime);
376*38e8c45fSAndroid Build Coastguard Worker
377*38e8c45fSAndroid Build Coastguard Worker nsecs_t firstRefreshStartTime = NATIVE_WINDOW_TIMESTAMP_INVALID;
378*38e8c45fSAndroid Build Coastguard Worker getFrameTimestamp(&firstRefreshStartTime, events->firstRefreshStartTime);
379*38e8c45fSAndroid Build Coastguard Worker if (outFirstRefreshStartTime) {
380*38e8c45fSAndroid Build Coastguard Worker *outFirstRefreshStartTime = firstRefreshStartTime;
381*38e8c45fSAndroid Build Coastguard Worker }
382*38e8c45fSAndroid Build Coastguard Worker
383*38e8c45fSAndroid Build Coastguard Worker getFrameTimestamp(outLastRefreshStartTime, events->lastRefreshStartTime);
384*38e8c45fSAndroid Build Coastguard Worker getFrameTimestamp(outDequeueReadyTime, events->dequeueReadyTime);
385*38e8c45fSAndroid Build Coastguard Worker
386*38e8c45fSAndroid Build Coastguard Worker nsecs_t acquireTime = NATIVE_WINDOW_TIMESTAMP_INVALID;
387*38e8c45fSAndroid Build Coastguard Worker getFrameTimestampFence(&acquireTime, events->acquireFence,
388*38e8c45fSAndroid Build Coastguard Worker events->hasAcquireInfo());
389*38e8c45fSAndroid Build Coastguard Worker if (outAcquireTime != nullptr) {
390*38e8c45fSAndroid Build Coastguard Worker *outAcquireTime = acquireTime;
391*38e8c45fSAndroid Build Coastguard Worker }
392*38e8c45fSAndroid Build Coastguard Worker
393*38e8c45fSAndroid Build Coastguard Worker getFrameTimestampFence(outGpuCompositionDoneTime,
394*38e8c45fSAndroid Build Coastguard Worker events->gpuCompositionDoneFence,
395*38e8c45fSAndroid Build Coastguard Worker events->hasGpuCompositionDoneInfo());
396*38e8c45fSAndroid Build Coastguard Worker getFrameTimestampFence(outDisplayPresentTime, events->displayPresentFence,
397*38e8c45fSAndroid Build Coastguard Worker events->hasDisplayPresentInfo());
398*38e8c45fSAndroid Build Coastguard Worker getFrameTimestampFence(outReleaseTime, events->releaseFence,
399*38e8c45fSAndroid Build Coastguard Worker events->hasReleaseInfo());
400*38e8c45fSAndroid Build Coastguard Worker
401*38e8c45fSAndroid Build Coastguard Worker // Fix up the GPU completion fence at this layer -- eglGetFrameTimestampsANDROID() expects
402*38e8c45fSAndroid Build Coastguard Worker // that EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID > EGL_RENDERING_COMPLETE_TIME_ANDROID.
403*38e8c45fSAndroid Build Coastguard Worker // This is typically true, but SurfaceFlinger may opt to cache prior GPU composition results,
404*38e8c45fSAndroid Build Coastguard Worker // which breaks that assumption, so zero out GPU composition time.
405*38e8c45fSAndroid Build Coastguard Worker if (outGpuCompositionDoneTime != nullptr
406*38e8c45fSAndroid Build Coastguard Worker && *outGpuCompositionDoneTime > 0 && (acquireTime > 0 || firstRefreshStartTime > 0)
407*38e8c45fSAndroid Build Coastguard Worker && *outGpuCompositionDoneTime <= std::max(acquireTime, firstRefreshStartTime)) {
408*38e8c45fSAndroid Build Coastguard Worker *outGpuCompositionDoneTime = 0;
409*38e8c45fSAndroid Build Coastguard Worker }
410*38e8c45fSAndroid Build Coastguard Worker
411*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
412*38e8c45fSAndroid Build Coastguard Worker }
413*38e8c45fSAndroid Build Coastguard Worker
414*38e8c45fSAndroid Build Coastguard Worker // Deprecated(b/242763577): to be removed, this method should not be used
415*38e8c45fSAndroid Build Coastguard Worker // The reason this method still exists here is to support compiled vndk
416*38e8c45fSAndroid Build Coastguard Worker // Surface support should not be tied to the display
417*38e8c45fSAndroid Build Coastguard Worker // Return true since most displays should have this support
getWideColorSupport(bool * supported)418*38e8c45fSAndroid Build Coastguard Worker status_t Surface::getWideColorSupport(bool* supported) {
419*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
420*38e8c45fSAndroid Build Coastguard Worker
421*38e8c45fSAndroid Build Coastguard Worker *supported = true;
422*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
423*38e8c45fSAndroid Build Coastguard Worker }
424*38e8c45fSAndroid Build Coastguard Worker
425*38e8c45fSAndroid Build Coastguard Worker // Deprecated(b/242763577): to be removed, this method should not be used
426*38e8c45fSAndroid Build Coastguard Worker // The reason this method still exists here is to support compiled vndk
427*38e8c45fSAndroid Build Coastguard Worker // Surface support should not be tied to the display
428*38e8c45fSAndroid Build Coastguard Worker // Return true since most displays should have this support
getHdrSupport(bool * supported)429*38e8c45fSAndroid Build Coastguard Worker status_t Surface::getHdrSupport(bool* supported) {
430*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
431*38e8c45fSAndroid Build Coastguard Worker
432*38e8c45fSAndroid Build Coastguard Worker *supported = true;
433*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
434*38e8c45fSAndroid Build Coastguard Worker }
435*38e8c45fSAndroid Build Coastguard Worker
hook_setSwapInterval(ANativeWindow * window,int interval)436*38e8c45fSAndroid Build Coastguard Worker int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
437*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
438*38e8c45fSAndroid Build Coastguard Worker return c->setSwapInterval(interval);
439*38e8c45fSAndroid Build Coastguard Worker }
440*38e8c45fSAndroid Build Coastguard Worker
hook_dequeueBuffer(ANativeWindow * window,ANativeWindowBuffer ** buffer,int * fenceFd)441*38e8c45fSAndroid Build Coastguard Worker int Surface::hook_dequeueBuffer(ANativeWindow* window,
442*38e8c45fSAndroid Build Coastguard Worker ANativeWindowBuffer** buffer, int* fenceFd) {
443*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
444*38e8c45fSAndroid Build Coastguard Worker {
445*38e8c45fSAndroid Build Coastguard Worker std::shared_lock<std::shared_mutex> lock(c->mInterceptorMutex);
446*38e8c45fSAndroid Build Coastguard Worker if (c->mDequeueInterceptor != nullptr) {
447*38e8c45fSAndroid Build Coastguard Worker auto interceptor = c->mDequeueInterceptor;
448*38e8c45fSAndroid Build Coastguard Worker auto data = c->mDequeueInterceptorData;
449*38e8c45fSAndroid Build Coastguard Worker return interceptor(window, Surface::dequeueBufferInternal, data, buffer, fenceFd);
450*38e8c45fSAndroid Build Coastguard Worker }
451*38e8c45fSAndroid Build Coastguard Worker }
452*38e8c45fSAndroid Build Coastguard Worker return c->dequeueBuffer(buffer, fenceFd);
453*38e8c45fSAndroid Build Coastguard Worker }
454*38e8c45fSAndroid Build Coastguard Worker
dequeueBufferInternal(ANativeWindow * window,ANativeWindowBuffer ** buffer,int * fenceFd)455*38e8c45fSAndroid Build Coastguard Worker int Surface::dequeueBufferInternal(ANativeWindow* window, ANativeWindowBuffer** buffer,
456*38e8c45fSAndroid Build Coastguard Worker int* fenceFd) {
457*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
458*38e8c45fSAndroid Build Coastguard Worker return c->dequeueBuffer(buffer, fenceFd);
459*38e8c45fSAndroid Build Coastguard Worker }
460*38e8c45fSAndroid Build Coastguard Worker
hook_cancelBuffer(ANativeWindow * window,ANativeWindowBuffer * buffer,int fenceFd)461*38e8c45fSAndroid Build Coastguard Worker int Surface::hook_cancelBuffer(ANativeWindow* window,
462*38e8c45fSAndroid Build Coastguard Worker ANativeWindowBuffer* buffer, int fenceFd) {
463*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
464*38e8c45fSAndroid Build Coastguard Worker {
465*38e8c45fSAndroid Build Coastguard Worker std::shared_lock<std::shared_mutex> lock(c->mInterceptorMutex);
466*38e8c45fSAndroid Build Coastguard Worker if (c->mCancelInterceptor != nullptr) {
467*38e8c45fSAndroid Build Coastguard Worker auto interceptor = c->mCancelInterceptor;
468*38e8c45fSAndroid Build Coastguard Worker auto data = c->mCancelInterceptorData;
469*38e8c45fSAndroid Build Coastguard Worker return interceptor(window, Surface::cancelBufferInternal, data, buffer, fenceFd);
470*38e8c45fSAndroid Build Coastguard Worker }
471*38e8c45fSAndroid Build Coastguard Worker }
472*38e8c45fSAndroid Build Coastguard Worker return c->cancelBuffer(buffer, fenceFd);
473*38e8c45fSAndroid Build Coastguard Worker }
474*38e8c45fSAndroid Build Coastguard Worker
cancelBufferInternal(ANativeWindow * window,ANativeWindowBuffer * buffer,int fenceFd)475*38e8c45fSAndroid Build Coastguard Worker int Surface::cancelBufferInternal(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) {
476*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
477*38e8c45fSAndroid Build Coastguard Worker return c->cancelBuffer(buffer, fenceFd);
478*38e8c45fSAndroid Build Coastguard Worker }
479*38e8c45fSAndroid Build Coastguard Worker
hook_queueBuffer(ANativeWindow * window,ANativeWindowBuffer * buffer,int fenceFd)480*38e8c45fSAndroid Build Coastguard Worker int Surface::hook_queueBuffer(ANativeWindow* window,
481*38e8c45fSAndroid Build Coastguard Worker ANativeWindowBuffer* buffer, int fenceFd) {
482*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
483*38e8c45fSAndroid Build Coastguard Worker {
484*38e8c45fSAndroid Build Coastguard Worker std::shared_lock<std::shared_mutex> lock(c->mInterceptorMutex);
485*38e8c45fSAndroid Build Coastguard Worker if (c->mQueueInterceptor != nullptr) {
486*38e8c45fSAndroid Build Coastguard Worker auto interceptor = c->mQueueInterceptor;
487*38e8c45fSAndroid Build Coastguard Worker auto data = c->mQueueInterceptorData;
488*38e8c45fSAndroid Build Coastguard Worker return interceptor(window, Surface::queueBufferInternal, data, buffer, fenceFd);
489*38e8c45fSAndroid Build Coastguard Worker }
490*38e8c45fSAndroid Build Coastguard Worker }
491*38e8c45fSAndroid Build Coastguard Worker return c->queueBuffer(buffer, fenceFd);
492*38e8c45fSAndroid Build Coastguard Worker }
493*38e8c45fSAndroid Build Coastguard Worker
queueBufferInternal(ANativeWindow * window,ANativeWindowBuffer * buffer,int fenceFd)494*38e8c45fSAndroid Build Coastguard Worker int Surface::queueBufferInternal(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) {
495*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
496*38e8c45fSAndroid Build Coastguard Worker return c->queueBuffer(buffer, fenceFd);
497*38e8c45fSAndroid Build Coastguard Worker }
498*38e8c45fSAndroid Build Coastguard Worker
hook_dequeueBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer ** buffer)499*38e8c45fSAndroid Build Coastguard Worker int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
500*38e8c45fSAndroid Build Coastguard Worker ANativeWindowBuffer** buffer) {
501*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
502*38e8c45fSAndroid Build Coastguard Worker ANativeWindowBuffer* buf;
503*38e8c45fSAndroid Build Coastguard Worker int fenceFd = -1;
504*38e8c45fSAndroid Build Coastguard Worker int result = c->dequeueBuffer(&buf, &fenceFd);
505*38e8c45fSAndroid Build Coastguard Worker if (result != OK) {
506*38e8c45fSAndroid Build Coastguard Worker return result;
507*38e8c45fSAndroid Build Coastguard Worker }
508*38e8c45fSAndroid Build Coastguard Worker sp<Fence> fence(new Fence(fenceFd));
509*38e8c45fSAndroid Build Coastguard Worker int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
510*38e8c45fSAndroid Build Coastguard Worker if (waitResult != OK) {
511*38e8c45fSAndroid Build Coastguard Worker ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d",
512*38e8c45fSAndroid Build Coastguard Worker waitResult);
513*38e8c45fSAndroid Build Coastguard Worker c->cancelBuffer(buf, -1);
514*38e8c45fSAndroid Build Coastguard Worker return waitResult;
515*38e8c45fSAndroid Build Coastguard Worker }
516*38e8c45fSAndroid Build Coastguard Worker *buffer = buf;
517*38e8c45fSAndroid Build Coastguard Worker return result;
518*38e8c45fSAndroid Build Coastguard Worker }
519*38e8c45fSAndroid Build Coastguard Worker
hook_cancelBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer * buffer)520*38e8c45fSAndroid Build Coastguard Worker int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
521*38e8c45fSAndroid Build Coastguard Worker ANativeWindowBuffer* buffer) {
522*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
523*38e8c45fSAndroid Build Coastguard Worker return c->cancelBuffer(buffer, -1);
524*38e8c45fSAndroid Build Coastguard Worker }
525*38e8c45fSAndroid Build Coastguard Worker
hook_lockBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer * buffer)526*38e8c45fSAndroid Build Coastguard Worker int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
527*38e8c45fSAndroid Build Coastguard Worker ANativeWindowBuffer* buffer) {
528*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
529*38e8c45fSAndroid Build Coastguard Worker return c->lockBuffer_DEPRECATED(buffer);
530*38e8c45fSAndroid Build Coastguard Worker }
531*38e8c45fSAndroid Build Coastguard Worker
hook_queueBuffer_DEPRECATED(ANativeWindow * window,ANativeWindowBuffer * buffer)532*38e8c45fSAndroid Build Coastguard Worker int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
533*38e8c45fSAndroid Build Coastguard Worker ANativeWindowBuffer* buffer) {
534*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
535*38e8c45fSAndroid Build Coastguard Worker return c->queueBuffer(buffer, -1);
536*38e8c45fSAndroid Build Coastguard Worker }
537*38e8c45fSAndroid Build Coastguard Worker
hook_perform(ANativeWindow * window,int operation,...)538*38e8c45fSAndroid Build Coastguard Worker int Surface::hook_perform(ANativeWindow* window, int operation, ...) {
539*38e8c45fSAndroid Build Coastguard Worker va_list args;
540*38e8c45fSAndroid Build Coastguard Worker va_start(args, operation);
541*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
542*38e8c45fSAndroid Build Coastguard Worker int result;
543*38e8c45fSAndroid Build Coastguard Worker // Don't acquire shared ownership of the interceptor mutex if we're going to
544*38e8c45fSAndroid Build Coastguard Worker // do interceptor registration, as otherwise we'll deadlock on acquiring
545*38e8c45fSAndroid Build Coastguard Worker // exclusive ownership.
546*38e8c45fSAndroid Build Coastguard Worker if (!isInterceptorRegistrationOp(operation)) {
547*38e8c45fSAndroid Build Coastguard Worker std::shared_lock<std::shared_mutex> lock(c->mInterceptorMutex);
548*38e8c45fSAndroid Build Coastguard Worker if (c->mPerformInterceptor != nullptr) {
549*38e8c45fSAndroid Build Coastguard Worker result = c->mPerformInterceptor(window, Surface::performInternal,
550*38e8c45fSAndroid Build Coastguard Worker c->mPerformInterceptorData, operation, args);
551*38e8c45fSAndroid Build Coastguard Worker va_end(args);
552*38e8c45fSAndroid Build Coastguard Worker return result;
553*38e8c45fSAndroid Build Coastguard Worker }
554*38e8c45fSAndroid Build Coastguard Worker }
555*38e8c45fSAndroid Build Coastguard Worker result = c->perform(operation, args);
556*38e8c45fSAndroid Build Coastguard Worker va_end(args);
557*38e8c45fSAndroid Build Coastguard Worker return result;
558*38e8c45fSAndroid Build Coastguard Worker }
559*38e8c45fSAndroid Build Coastguard Worker
performInternal(ANativeWindow * window,int operation,va_list args)560*38e8c45fSAndroid Build Coastguard Worker int Surface::performInternal(ANativeWindow* window, int operation, va_list args) {
561*38e8c45fSAndroid Build Coastguard Worker Surface* c = getSelf(window);
562*38e8c45fSAndroid Build Coastguard Worker return c->perform(operation, args);
563*38e8c45fSAndroid Build Coastguard Worker }
564*38e8c45fSAndroid Build Coastguard Worker
hook_query(const ANativeWindow * window,int what,int * value)565*38e8c45fSAndroid Build Coastguard Worker int Surface::hook_query(const ANativeWindow* window, int what, int* value) {
566*38e8c45fSAndroid Build Coastguard Worker const Surface* c = getSelf(window);
567*38e8c45fSAndroid Build Coastguard Worker {
568*38e8c45fSAndroid Build Coastguard Worker std::shared_lock<std::shared_mutex> lock(c->mInterceptorMutex);
569*38e8c45fSAndroid Build Coastguard Worker if (c->mQueryInterceptor != nullptr) {
570*38e8c45fSAndroid Build Coastguard Worker auto interceptor = c->mQueryInterceptor;
571*38e8c45fSAndroid Build Coastguard Worker auto data = c->mQueryInterceptorData;
572*38e8c45fSAndroid Build Coastguard Worker return interceptor(window, Surface::queryInternal, data, what, value);
573*38e8c45fSAndroid Build Coastguard Worker }
574*38e8c45fSAndroid Build Coastguard Worker }
575*38e8c45fSAndroid Build Coastguard Worker return c->query(what, value);
576*38e8c45fSAndroid Build Coastguard Worker }
577*38e8c45fSAndroid Build Coastguard Worker
queryInternal(const ANativeWindow * window,int what,int * value)578*38e8c45fSAndroid Build Coastguard Worker int Surface::queryInternal(const ANativeWindow* window, int what, int* value) {
579*38e8c45fSAndroid Build Coastguard Worker const Surface* c = getSelf(window);
580*38e8c45fSAndroid Build Coastguard Worker return c->query(what, value);
581*38e8c45fSAndroid Build Coastguard Worker }
582*38e8c45fSAndroid Build Coastguard Worker
setSwapInterval(int interval)583*38e8c45fSAndroid Build Coastguard Worker int Surface::setSwapInterval(int interval) {
584*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
585*38e8c45fSAndroid Build Coastguard Worker // EGL specification states:
586*38e8c45fSAndroid Build Coastguard Worker // interval is silently clamped to minimum and maximum implementation
587*38e8c45fSAndroid Build Coastguard Worker // dependent values before being stored.
588*38e8c45fSAndroid Build Coastguard Worker
589*38e8c45fSAndroid Build Coastguard Worker if (interval < minSwapInterval)
590*38e8c45fSAndroid Build Coastguard Worker interval = minSwapInterval;
591*38e8c45fSAndroid Build Coastguard Worker
592*38e8c45fSAndroid Build Coastguard Worker if (interval > maxSwapInterval)
593*38e8c45fSAndroid Build Coastguard Worker interval = maxSwapInterval;
594*38e8c45fSAndroid Build Coastguard Worker
595*38e8c45fSAndroid Build Coastguard Worker const bool wasSwapIntervalZero = mSwapIntervalZero;
596*38e8c45fSAndroid Build Coastguard Worker mSwapIntervalZero = (interval == 0);
597*38e8c45fSAndroid Build Coastguard Worker
598*38e8c45fSAndroid Build Coastguard Worker if (mSwapIntervalZero != wasSwapIntervalZero) {
599*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->setAsyncMode(mSwapIntervalZero);
600*38e8c45fSAndroid Build Coastguard Worker }
601*38e8c45fSAndroid Build Coastguard Worker
602*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
603*38e8c45fSAndroid Build Coastguard Worker }
604*38e8c45fSAndroid Build Coastguard Worker
getDequeueBufferInputLocked(IGraphicBufferProducer::DequeueBufferInput * dequeueInput)605*38e8c45fSAndroid Build Coastguard Worker void Surface::getDequeueBufferInputLocked(
606*38e8c45fSAndroid Build Coastguard Worker IGraphicBufferProducer::DequeueBufferInput* dequeueInput) {
607*38e8c45fSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(dequeueInput == nullptr, "input is null");
608*38e8c45fSAndroid Build Coastguard Worker
609*38e8c45fSAndroid Build Coastguard Worker dequeueInput->width = mReqWidth ? mReqWidth : mUserWidth;
610*38e8c45fSAndroid Build Coastguard Worker dequeueInput->height = mReqHeight ? mReqHeight : mUserHeight;
611*38e8c45fSAndroid Build Coastguard Worker
612*38e8c45fSAndroid Build Coastguard Worker dequeueInput->format = mReqFormat;
613*38e8c45fSAndroid Build Coastguard Worker dequeueInput->usage = mReqUsage;
614*38e8c45fSAndroid Build Coastguard Worker
615*38e8c45fSAndroid Build Coastguard Worker dequeueInput->getTimestamps = mEnableFrameTimestamps;
616*38e8c45fSAndroid Build Coastguard Worker }
617*38e8c45fSAndroid Build Coastguard Worker
dequeueBuffer(android_native_buffer_t ** buffer,int * fenceFd)618*38e8c45fSAndroid Build Coastguard Worker int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
619*38e8c45fSAndroid Build Coastguard Worker ATRACE_FORMAT("dequeueBuffer - %s", getDebugName());
620*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::dequeueBuffer");
621*38e8c45fSAndroid Build Coastguard Worker
622*38e8c45fSAndroid Build Coastguard Worker IGraphicBufferProducer::DequeueBufferInput dqInput;
623*38e8c45fSAndroid Build Coastguard Worker {
624*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
625*38e8c45fSAndroid Build Coastguard Worker if (mReportRemovedBuffers) {
626*38e8c45fSAndroid Build Coastguard Worker mRemovedBuffers.clear();
627*38e8c45fSAndroid Build Coastguard Worker }
628*38e8c45fSAndroid Build Coastguard Worker
629*38e8c45fSAndroid Build Coastguard Worker getDequeueBufferInputLocked(&dqInput);
630*38e8c45fSAndroid Build Coastguard Worker
631*38e8c45fSAndroid Build Coastguard Worker if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot !=
632*38e8c45fSAndroid Build Coastguard Worker BufferItem::INVALID_BUFFER_SLOT) {
633*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer>& gbuf(mSlots[mSharedBufferSlot].buffer);
634*38e8c45fSAndroid Build Coastguard Worker if (gbuf != nullptr) {
635*38e8c45fSAndroid Build Coastguard Worker *buffer = gbuf.get();
636*38e8c45fSAndroid Build Coastguard Worker *fenceFd = -1;
637*38e8c45fSAndroid Build Coastguard Worker return OK;
638*38e8c45fSAndroid Build Coastguard Worker }
639*38e8c45fSAndroid Build Coastguard Worker }
640*38e8c45fSAndroid Build Coastguard Worker } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer
641*38e8c45fSAndroid Build Coastguard Worker
642*38e8c45fSAndroid Build Coastguard Worker int buf = -1;
643*38e8c45fSAndroid Build Coastguard Worker sp<Fence> fence;
644*38e8c45fSAndroid Build Coastguard Worker nsecs_t startTime = systemTime();
645*38e8c45fSAndroid Build Coastguard Worker
646*38e8c45fSAndroid Build Coastguard Worker FrameEventHistoryDelta frameTimestamps;
647*38e8c45fSAndroid Build Coastguard Worker status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, dqInput.width,
648*38e8c45fSAndroid Build Coastguard Worker dqInput.height, dqInput.format,
649*38e8c45fSAndroid Build Coastguard Worker dqInput.usage, &mBufferAge,
650*38e8c45fSAndroid Build Coastguard Worker dqInput.getTimestamps ?
651*38e8c45fSAndroid Build Coastguard Worker &frameTimestamps : nullptr);
652*38e8c45fSAndroid Build Coastguard Worker mLastDequeueDuration = systemTime() - startTime;
653*38e8c45fSAndroid Build Coastguard Worker
654*38e8c45fSAndroid Build Coastguard Worker if (result < 0) {
655*38e8c45fSAndroid Build Coastguard Worker ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer"
656*38e8c45fSAndroid Build Coastguard Worker "(%d, %d, %d, %#" PRIx64 ") failed: %d",
657*38e8c45fSAndroid Build Coastguard Worker dqInput.width, dqInput.height, dqInput.format, dqInput.usage, result);
658*38e8c45fSAndroid Build Coastguard Worker return result;
659*38e8c45fSAndroid Build Coastguard Worker }
660*38e8c45fSAndroid Build Coastguard Worker
661*38e8c45fSAndroid Build Coastguard Worker if (buf < 0 || buf >= NUM_BUFFER_SLOTS) {
662*38e8c45fSAndroid Build Coastguard Worker ALOGE("dequeueBuffer: IGraphicBufferProducer returned invalid slot number %d", buf);
663*38e8c45fSAndroid Build Coastguard Worker android_errorWriteLog(0x534e4554, "36991414"); // SafetyNet logging
664*38e8c45fSAndroid Build Coastguard Worker return FAILED_TRANSACTION;
665*38e8c45fSAndroid Build Coastguard Worker }
666*38e8c45fSAndroid Build Coastguard Worker
667*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
668*38e8c45fSAndroid Build Coastguard Worker
669*38e8c45fSAndroid Build Coastguard Worker // Write this while holding the mutex
670*38e8c45fSAndroid Build Coastguard Worker mLastDequeueStartTime = startTime;
671*38e8c45fSAndroid Build Coastguard Worker
672*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
673*38e8c45fSAndroid Build Coastguard Worker
674*38e8c45fSAndroid Build Coastguard Worker // this should never happen
675*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(fence == nullptr, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);
676*38e8c45fSAndroid Build Coastguard Worker
677*38e8c45fSAndroid Build Coastguard Worker if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
678*38e8c45fSAndroid Build Coastguard Worker static gui::FenceMonitor hwcReleaseThread("HWC release");
679*38e8c45fSAndroid Build Coastguard Worker hwcReleaseThread.queueFence(fence);
680*38e8c45fSAndroid Build Coastguard Worker }
681*38e8c45fSAndroid Build Coastguard Worker
682*38e8c45fSAndroid Build Coastguard Worker if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
683*38e8c45fSAndroid Build Coastguard Worker freeAllBuffers();
684*38e8c45fSAndroid Build Coastguard Worker }
685*38e8c45fSAndroid Build Coastguard Worker
686*38e8c45fSAndroid Build Coastguard Worker if (dqInput.getTimestamps) {
687*38e8c45fSAndroid Build Coastguard Worker mFrameEventHistory->applyDelta(frameTimestamps);
688*38e8c45fSAndroid Build Coastguard Worker }
689*38e8c45fSAndroid Build Coastguard Worker
690*38e8c45fSAndroid Build Coastguard Worker if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) {
691*38e8c45fSAndroid Build Coastguard Worker if (mReportRemovedBuffers && (gbuf != nullptr)) {
692*38e8c45fSAndroid Build Coastguard Worker mRemovedBuffers.push_back(gbuf);
693*38e8c45fSAndroid Build Coastguard Worker }
694*38e8c45fSAndroid Build Coastguard Worker result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
695*38e8c45fSAndroid Build Coastguard Worker if (result != NO_ERROR) {
696*38e8c45fSAndroid Build Coastguard Worker ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
697*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->cancelBuffer(buf, fence);
698*38e8c45fSAndroid Build Coastguard Worker return result;
699*38e8c45fSAndroid Build Coastguard Worker }
700*38e8c45fSAndroid Build Coastguard Worker }
701*38e8c45fSAndroid Build Coastguard Worker
702*38e8c45fSAndroid Build Coastguard Worker if (fence->isValid()) {
703*38e8c45fSAndroid Build Coastguard Worker *fenceFd = fence->dup();
704*38e8c45fSAndroid Build Coastguard Worker if (*fenceFd == -1) {
705*38e8c45fSAndroid Build Coastguard Worker ALOGE("dequeueBuffer: error duping fence: %d", errno);
706*38e8c45fSAndroid Build Coastguard Worker // dup() should never fail; something is badly wrong. Soldier on
707*38e8c45fSAndroid Build Coastguard Worker // and hope for the best; the worst that should happen is some
708*38e8c45fSAndroid Build Coastguard Worker // visible corruption that lasts until the next frame.
709*38e8c45fSAndroid Build Coastguard Worker }
710*38e8c45fSAndroid Build Coastguard Worker } else {
711*38e8c45fSAndroid Build Coastguard Worker *fenceFd = -1;
712*38e8c45fSAndroid Build Coastguard Worker }
713*38e8c45fSAndroid Build Coastguard Worker
714*38e8c45fSAndroid Build Coastguard Worker *buffer = gbuf.get();
715*38e8c45fSAndroid Build Coastguard Worker
716*38e8c45fSAndroid Build Coastguard Worker if (mSharedBufferMode && mAutoRefresh) {
717*38e8c45fSAndroid Build Coastguard Worker mSharedBufferSlot = buf;
718*38e8c45fSAndroid Build Coastguard Worker mSharedBufferHasBeenQueued = false;
719*38e8c45fSAndroid Build Coastguard Worker } else if (mSharedBufferSlot == buf) {
720*38e8c45fSAndroid Build Coastguard Worker mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
721*38e8c45fSAndroid Build Coastguard Worker mSharedBufferHasBeenQueued = false;
722*38e8c45fSAndroid Build Coastguard Worker }
723*38e8c45fSAndroid Build Coastguard Worker
724*38e8c45fSAndroid Build Coastguard Worker mDequeuedSlots.insert(buf);
725*38e8c45fSAndroid Build Coastguard Worker
726*38e8c45fSAndroid Build Coastguard Worker return OK;
727*38e8c45fSAndroid Build Coastguard Worker }
728*38e8c45fSAndroid Build Coastguard Worker
729*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
730*38e8c45fSAndroid Build Coastguard Worker
dequeueBuffer(sp<GraphicBuffer> * buffer,sp<Fence> * outFence)731*38e8c45fSAndroid Build Coastguard Worker status_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer, sp<Fence>* outFence) {
732*38e8c45fSAndroid Build Coastguard Worker if (buffer == nullptr || outFence == nullptr) {
733*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
734*38e8c45fSAndroid Build Coastguard Worker }
735*38e8c45fSAndroid Build Coastguard Worker
736*38e8c45fSAndroid Build Coastguard Worker android_native_buffer_t* anb;
737*38e8c45fSAndroid Build Coastguard Worker int fd = -1;
738*38e8c45fSAndroid Build Coastguard Worker status_t res = dequeueBuffer(&anb, &fd);
739*38e8c45fSAndroid Build Coastguard Worker *buffer = GraphicBuffer::from(anb);
740*38e8c45fSAndroid Build Coastguard Worker *outFence = sp<Fence>::make(fd);
741*38e8c45fSAndroid Build Coastguard Worker return res;
742*38e8c45fSAndroid Build Coastguard Worker }
743*38e8c45fSAndroid Build Coastguard Worker
queueBuffer(const sp<GraphicBuffer> & buffer,const sp<Fence> & fd,SurfaceQueueBufferOutput * output)744*38e8c45fSAndroid Build Coastguard Worker status_t Surface::queueBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& fd,
745*38e8c45fSAndroid Build Coastguard Worker SurfaceQueueBufferOutput* output) {
746*38e8c45fSAndroid Build Coastguard Worker if (buffer == nullptr) {
747*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
748*38e8c45fSAndroid Build Coastguard Worker }
749*38e8c45fSAndroid Build Coastguard Worker return queueBuffer(buffer.get(), fd ? fd->get() : -1, output);
750*38e8c45fSAndroid Build Coastguard Worker }
751*38e8c45fSAndroid Build Coastguard Worker
detachBuffer(const sp<GraphicBuffer> & buffer)752*38e8c45fSAndroid Build Coastguard Worker status_t Surface::detachBuffer(const sp<GraphicBuffer>& buffer) {
753*38e8c45fSAndroid Build Coastguard Worker if (nullptr == buffer) {
754*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
755*38e8c45fSAndroid Build Coastguard Worker }
756*38e8c45fSAndroid Build Coastguard Worker
757*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
758*38e8c45fSAndroid Build Coastguard Worker
759*38e8c45fSAndroid Build Coastguard Worker uint64_t bufferId = buffer->getId();
760*38e8c45fSAndroid Build Coastguard Worker for (int slot = 0; slot < Surface::NUM_BUFFER_SLOTS; ++slot) {
761*38e8c45fSAndroid Build Coastguard Worker auto& bufferSlot = mSlots[slot];
762*38e8c45fSAndroid Build Coastguard Worker if (bufferSlot.buffer != nullptr && bufferSlot.buffer->getId() == bufferId) {
763*38e8c45fSAndroid Build Coastguard Worker bufferSlot.buffer = nullptr;
764*38e8c45fSAndroid Build Coastguard Worker bufferSlot.dirtyRegion = Region::INVALID_REGION;
765*38e8c45fSAndroid Build Coastguard Worker return mGraphicBufferProducer->detachBuffer(slot);
766*38e8c45fSAndroid Build Coastguard Worker }
767*38e8c45fSAndroid Build Coastguard Worker }
768*38e8c45fSAndroid Build Coastguard Worker
769*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
770*38e8c45fSAndroid Build Coastguard Worker }
771*38e8c45fSAndroid Build Coastguard Worker
772*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
773*38e8c45fSAndroid Build Coastguard Worker
dequeueBuffers(std::vector<BatchBuffer> * buffers)774*38e8c45fSAndroid Build Coastguard Worker int Surface::dequeueBuffers(std::vector<BatchBuffer>* buffers) {
775*38e8c45fSAndroid Build Coastguard Worker using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
776*38e8c45fSAndroid Build Coastguard Worker using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;
777*38e8c45fSAndroid Build Coastguard Worker using CancelBufferInput = IGraphicBufferProducer::CancelBufferInput;
778*38e8c45fSAndroid Build Coastguard Worker using RequestBufferOutput = IGraphicBufferProducer::RequestBufferOutput;
779*38e8c45fSAndroid Build Coastguard Worker
780*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
781*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::dequeueBuffers");
782*38e8c45fSAndroid Build Coastguard Worker
783*38e8c45fSAndroid Build Coastguard Worker if (buffers->size() == 0) {
784*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: must dequeue at least 1 buffer!", __FUNCTION__);
785*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
786*38e8c45fSAndroid Build Coastguard Worker }
787*38e8c45fSAndroid Build Coastguard Worker
788*38e8c45fSAndroid Build Coastguard Worker if (mSharedBufferMode) {
789*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: batch operation is not supported in shared buffer mode!",
790*38e8c45fSAndroid Build Coastguard Worker __FUNCTION__);
791*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
792*38e8c45fSAndroid Build Coastguard Worker }
793*38e8c45fSAndroid Build Coastguard Worker
794*38e8c45fSAndroid Build Coastguard Worker size_t numBufferRequested = buffers->size();
795*38e8c45fSAndroid Build Coastguard Worker DequeueBufferInput input;
796*38e8c45fSAndroid Build Coastguard Worker
797*38e8c45fSAndroid Build Coastguard Worker {
798*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
799*38e8c45fSAndroid Build Coastguard Worker if (mReportRemovedBuffers) {
800*38e8c45fSAndroid Build Coastguard Worker mRemovedBuffers.clear();
801*38e8c45fSAndroid Build Coastguard Worker }
802*38e8c45fSAndroid Build Coastguard Worker
803*38e8c45fSAndroid Build Coastguard Worker getDequeueBufferInputLocked(&input);
804*38e8c45fSAndroid Build Coastguard Worker } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffers
805*38e8c45fSAndroid Build Coastguard Worker
806*38e8c45fSAndroid Build Coastguard Worker std::vector<DequeueBufferInput> dequeueInput(numBufferRequested, input);
807*38e8c45fSAndroid Build Coastguard Worker std::vector<DequeueBufferOutput> dequeueOutput;
808*38e8c45fSAndroid Build Coastguard Worker
809*38e8c45fSAndroid Build Coastguard Worker nsecs_t startTime = systemTime();
810*38e8c45fSAndroid Build Coastguard Worker
811*38e8c45fSAndroid Build Coastguard Worker status_t result = mGraphicBufferProducer->dequeueBuffers(dequeueInput, &dequeueOutput);
812*38e8c45fSAndroid Build Coastguard Worker
813*38e8c45fSAndroid Build Coastguard Worker mLastDequeueDuration = systemTime() - startTime;
814*38e8c45fSAndroid Build Coastguard Worker
815*38e8c45fSAndroid Build Coastguard Worker if (result < 0) {
816*38e8c45fSAndroid Build Coastguard Worker ALOGV("%s: IGraphicBufferProducer::dequeueBuffers"
817*38e8c45fSAndroid Build Coastguard Worker "(%d, %d, %d, %#" PRIx64 ") failed: %d",
818*38e8c45fSAndroid Build Coastguard Worker __FUNCTION__, input.width, input.height, input.format, input.usage, result);
819*38e8c45fSAndroid Build Coastguard Worker return result;
820*38e8c45fSAndroid Build Coastguard Worker }
821*38e8c45fSAndroid Build Coastguard Worker
822*38e8c45fSAndroid Build Coastguard Worker std::vector<CancelBufferInput> cancelBufferInputs;
823*38e8c45fSAndroid Build Coastguard Worker cancelBufferInputs.reserve(numBufferRequested);
824*38e8c45fSAndroid Build Coastguard Worker std::vector<status_t> cancelBufferOutputs;
825*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < numBufferRequested; i++) {
826*38e8c45fSAndroid Build Coastguard Worker if (dequeueOutput[i].result >= 0) {
827*38e8c45fSAndroid Build Coastguard Worker CancelBufferInput& input = cancelBufferInputs.emplace_back();
828*38e8c45fSAndroid Build Coastguard Worker input.slot = dequeueOutput[i].slot;
829*38e8c45fSAndroid Build Coastguard Worker input.fence = dequeueOutput[i].fence;
830*38e8c45fSAndroid Build Coastguard Worker }
831*38e8c45fSAndroid Build Coastguard Worker }
832*38e8c45fSAndroid Build Coastguard Worker
833*38e8c45fSAndroid Build Coastguard Worker for (const auto& output : dequeueOutput) {
834*38e8c45fSAndroid Build Coastguard Worker if (output.result < 0) {
835*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->cancelBuffers(cancelBufferInputs, &cancelBufferOutputs);
836*38e8c45fSAndroid Build Coastguard Worker ALOGV("%s: IGraphicBufferProducer::dequeueBuffers"
837*38e8c45fSAndroid Build Coastguard Worker "(%d, %d, %d, %#" PRIx64 ") failed: %d",
838*38e8c45fSAndroid Build Coastguard Worker __FUNCTION__, input.width, input.height, input.format, input.usage,
839*38e8c45fSAndroid Build Coastguard Worker output.result);
840*38e8c45fSAndroid Build Coastguard Worker return output.result;
841*38e8c45fSAndroid Build Coastguard Worker }
842*38e8c45fSAndroid Build Coastguard Worker
843*38e8c45fSAndroid Build Coastguard Worker if (output.slot < 0 || output.slot >= NUM_BUFFER_SLOTS) {
844*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->cancelBuffers(cancelBufferInputs, &cancelBufferOutputs);
845*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: IGraphicBufferProducer returned invalid slot number %d",
846*38e8c45fSAndroid Build Coastguard Worker __FUNCTION__, output.slot);
847*38e8c45fSAndroid Build Coastguard Worker android_errorWriteLog(0x534e4554, "36991414"); // SafetyNet logging
848*38e8c45fSAndroid Build Coastguard Worker return FAILED_TRANSACTION;
849*38e8c45fSAndroid Build Coastguard Worker }
850*38e8c45fSAndroid Build Coastguard Worker
851*38e8c45fSAndroid Build Coastguard Worker if (input.getTimestamps && !output.timestamps.has_value()) {
852*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->cancelBuffers(cancelBufferInputs, &cancelBufferOutputs);
853*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: no frame timestamp returns!", __FUNCTION__);
854*38e8c45fSAndroid Build Coastguard Worker return FAILED_TRANSACTION;
855*38e8c45fSAndroid Build Coastguard Worker }
856*38e8c45fSAndroid Build Coastguard Worker
857*38e8c45fSAndroid Build Coastguard Worker // this should never happen
858*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(output.fence == nullptr,
859*38e8c45fSAndroid Build Coastguard Worker "%s: received null Fence! slot=%d", __FUNCTION__, output.slot);
860*38e8c45fSAndroid Build Coastguard Worker }
861*38e8c45fSAndroid Build Coastguard Worker
862*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
863*38e8c45fSAndroid Build Coastguard Worker
864*38e8c45fSAndroid Build Coastguard Worker // Write this while holding the mutex
865*38e8c45fSAndroid Build Coastguard Worker mLastDequeueStartTime = startTime;
866*38e8c45fSAndroid Build Coastguard Worker
867*38e8c45fSAndroid Build Coastguard Worker std::vector<int32_t> requestBufferSlots;
868*38e8c45fSAndroid Build Coastguard Worker requestBufferSlots.reserve(numBufferRequested);
869*38e8c45fSAndroid Build Coastguard Worker // handle release all buffers and request buffers
870*38e8c45fSAndroid Build Coastguard Worker for (const auto& output : dequeueOutput) {
871*38e8c45fSAndroid Build Coastguard Worker if (output.result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
872*38e8c45fSAndroid Build Coastguard Worker ALOGV("%s: RELEASE_ALL_BUFFERS during batch operation", __FUNCTION__);
873*38e8c45fSAndroid Build Coastguard Worker freeAllBuffers();
874*38e8c45fSAndroid Build Coastguard Worker break;
875*38e8c45fSAndroid Build Coastguard Worker }
876*38e8c45fSAndroid Build Coastguard Worker }
877*38e8c45fSAndroid Build Coastguard Worker
878*38e8c45fSAndroid Build Coastguard Worker for (const auto& output : dequeueOutput) {
879*38e8c45fSAndroid Build Coastguard Worker // Collect slots that needs requesting buffer
880*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer>& gbuf(mSlots[output.slot].buffer);
881*38e8c45fSAndroid Build Coastguard Worker if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) {
882*38e8c45fSAndroid Build Coastguard Worker if (mReportRemovedBuffers && (gbuf != nullptr)) {
883*38e8c45fSAndroid Build Coastguard Worker mRemovedBuffers.push_back(gbuf);
884*38e8c45fSAndroid Build Coastguard Worker }
885*38e8c45fSAndroid Build Coastguard Worker requestBufferSlots.push_back(output.slot);
886*38e8c45fSAndroid Build Coastguard Worker }
887*38e8c45fSAndroid Build Coastguard Worker }
888*38e8c45fSAndroid Build Coastguard Worker
889*38e8c45fSAndroid Build Coastguard Worker // Batch request Buffer
890*38e8c45fSAndroid Build Coastguard Worker std::vector<RequestBufferOutput> reqBufferOutput;
891*38e8c45fSAndroid Build Coastguard Worker if (requestBufferSlots.size() > 0) {
892*38e8c45fSAndroid Build Coastguard Worker result = mGraphicBufferProducer->requestBuffers(requestBufferSlots, &reqBufferOutput);
893*38e8c45fSAndroid Build Coastguard Worker if (result != NO_ERROR) {
894*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: IGraphicBufferProducer::requestBuffers failed: %d",
895*38e8c45fSAndroid Build Coastguard Worker __FUNCTION__, result);
896*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->cancelBuffers(cancelBufferInputs, &cancelBufferOutputs);
897*38e8c45fSAndroid Build Coastguard Worker return result;
898*38e8c45fSAndroid Build Coastguard Worker }
899*38e8c45fSAndroid Build Coastguard Worker
900*38e8c45fSAndroid Build Coastguard Worker // Check if we have any single failure
901*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < requestBufferSlots.size(); i++) {
902*38e8c45fSAndroid Build Coastguard Worker if (reqBufferOutput[i].result != OK) {
903*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: IGraphicBufferProducer::requestBuffers failed at %zu-th buffer, slot %d",
904*38e8c45fSAndroid Build Coastguard Worker __FUNCTION__, i, requestBufferSlots[i]);
905*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->cancelBuffers(cancelBufferInputs, &cancelBufferOutputs);
906*38e8c45fSAndroid Build Coastguard Worker return reqBufferOutput[i].result;
907*38e8c45fSAndroid Build Coastguard Worker }
908*38e8c45fSAndroid Build Coastguard Worker }
909*38e8c45fSAndroid Build Coastguard Worker
910*38e8c45fSAndroid Build Coastguard Worker // Fill request buffer results to mSlots
911*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < requestBufferSlots.size(); i++) {
912*38e8c45fSAndroid Build Coastguard Worker mSlots[requestBufferSlots[i]].buffer = reqBufferOutput[i].buffer;
913*38e8c45fSAndroid Build Coastguard Worker }
914*38e8c45fSAndroid Build Coastguard Worker }
915*38e8c45fSAndroid Build Coastguard Worker
916*38e8c45fSAndroid Build Coastguard Worker for (size_t batchIdx = 0; batchIdx < numBufferRequested; batchIdx++) {
917*38e8c45fSAndroid Build Coastguard Worker const auto& output = dequeueOutput[batchIdx];
918*38e8c45fSAndroid Build Coastguard Worker int slot = output.slot;
919*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer>& gbuf(mSlots[slot].buffer);
920*38e8c45fSAndroid Build Coastguard Worker
921*38e8c45fSAndroid Build Coastguard Worker if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
922*38e8c45fSAndroid Build Coastguard Worker static gui::FenceMonitor hwcReleaseThread("HWC release");
923*38e8c45fSAndroid Build Coastguard Worker hwcReleaseThread.queueFence(output.fence);
924*38e8c45fSAndroid Build Coastguard Worker }
925*38e8c45fSAndroid Build Coastguard Worker
926*38e8c45fSAndroid Build Coastguard Worker if (input.getTimestamps) {
927*38e8c45fSAndroid Build Coastguard Worker mFrameEventHistory->applyDelta(output.timestamps.value());
928*38e8c45fSAndroid Build Coastguard Worker }
929*38e8c45fSAndroid Build Coastguard Worker
930*38e8c45fSAndroid Build Coastguard Worker if (output.fence->isValid()) {
931*38e8c45fSAndroid Build Coastguard Worker buffers->at(batchIdx).fenceFd = output.fence->dup();
932*38e8c45fSAndroid Build Coastguard Worker if (buffers->at(batchIdx).fenceFd == -1) {
933*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: error duping fence: %d", __FUNCTION__, errno);
934*38e8c45fSAndroid Build Coastguard Worker // dup() should never fail; something is badly wrong. Soldier on
935*38e8c45fSAndroid Build Coastguard Worker // and hope for the best; the worst that should happen is some
936*38e8c45fSAndroid Build Coastguard Worker // visible corruption that lasts until the next frame.
937*38e8c45fSAndroid Build Coastguard Worker }
938*38e8c45fSAndroid Build Coastguard Worker } else {
939*38e8c45fSAndroid Build Coastguard Worker buffers->at(batchIdx).fenceFd = -1;
940*38e8c45fSAndroid Build Coastguard Worker }
941*38e8c45fSAndroid Build Coastguard Worker
942*38e8c45fSAndroid Build Coastguard Worker buffers->at(batchIdx).buffer = gbuf.get();
943*38e8c45fSAndroid Build Coastguard Worker mDequeuedSlots.insert(slot);
944*38e8c45fSAndroid Build Coastguard Worker }
945*38e8c45fSAndroid Build Coastguard Worker return OK;
946*38e8c45fSAndroid Build Coastguard Worker }
947*38e8c45fSAndroid Build Coastguard Worker
cancelBuffer(android_native_buffer_t * buffer,int fenceFd)948*38e8c45fSAndroid Build Coastguard Worker int Surface::cancelBuffer(android_native_buffer_t* buffer,
949*38e8c45fSAndroid Build Coastguard Worker int fenceFd) {
950*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
951*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::cancelBuffer");
952*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
953*38e8c45fSAndroid Build Coastguard Worker int i = getSlotFromBufferLocked(buffer);
954*38e8c45fSAndroid Build Coastguard Worker if (i < 0) {
955*38e8c45fSAndroid Build Coastguard Worker if (fenceFd >= 0) {
956*38e8c45fSAndroid Build Coastguard Worker close(fenceFd);
957*38e8c45fSAndroid Build Coastguard Worker }
958*38e8c45fSAndroid Build Coastguard Worker return i;
959*38e8c45fSAndroid Build Coastguard Worker }
960*38e8c45fSAndroid Build Coastguard Worker if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
961*38e8c45fSAndroid Build Coastguard Worker if (fenceFd >= 0) {
962*38e8c45fSAndroid Build Coastguard Worker close(fenceFd);
963*38e8c45fSAndroid Build Coastguard Worker }
964*38e8c45fSAndroid Build Coastguard Worker return OK;
965*38e8c45fSAndroid Build Coastguard Worker }
966*38e8c45fSAndroid Build Coastguard Worker sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
967*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->cancelBuffer(i, fence);
968*38e8c45fSAndroid Build Coastguard Worker
969*38e8c45fSAndroid Build Coastguard Worker if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
970*38e8c45fSAndroid Build Coastguard Worker mSharedBufferHasBeenQueued = true;
971*38e8c45fSAndroid Build Coastguard Worker }
972*38e8c45fSAndroid Build Coastguard Worker
973*38e8c45fSAndroid Build Coastguard Worker mDequeuedSlots.erase(i);
974*38e8c45fSAndroid Build Coastguard Worker
975*38e8c45fSAndroid Build Coastguard Worker return OK;
976*38e8c45fSAndroid Build Coastguard Worker }
977*38e8c45fSAndroid Build Coastguard Worker
cancelBuffers(const std::vector<BatchBuffer> & buffers)978*38e8c45fSAndroid Build Coastguard Worker int Surface::cancelBuffers(const std::vector<BatchBuffer>& buffers) {
979*38e8c45fSAndroid Build Coastguard Worker using CancelBufferInput = IGraphicBufferProducer::CancelBufferInput;
980*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
981*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::cancelBuffers");
982*38e8c45fSAndroid Build Coastguard Worker
983*38e8c45fSAndroid Build Coastguard Worker if (mSharedBufferMode) {
984*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: batch operation is not supported in shared buffer mode!",
985*38e8c45fSAndroid Build Coastguard Worker __FUNCTION__);
986*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
987*38e8c45fSAndroid Build Coastguard Worker }
988*38e8c45fSAndroid Build Coastguard Worker
989*38e8c45fSAndroid Build Coastguard Worker size_t numBuffers = buffers.size();
990*38e8c45fSAndroid Build Coastguard Worker std::vector<CancelBufferInput> cancelBufferInputs(numBuffers);
991*38e8c45fSAndroid Build Coastguard Worker std::vector<status_t> cancelBufferOutputs;
992*38e8c45fSAndroid Build Coastguard Worker size_t numBuffersCancelled = 0;
993*38e8c45fSAndroid Build Coastguard Worker int badSlotResult = 0;
994*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < numBuffers; i++) {
995*38e8c45fSAndroid Build Coastguard Worker int slot = getSlotFromBufferLocked(buffers[i].buffer);
996*38e8c45fSAndroid Build Coastguard Worker int fenceFd = buffers[i].fenceFd;
997*38e8c45fSAndroid Build Coastguard Worker if (slot < 0) {
998*38e8c45fSAndroid Build Coastguard Worker if (fenceFd >= 0) {
999*38e8c45fSAndroid Build Coastguard Worker close(fenceFd);
1000*38e8c45fSAndroid Build Coastguard Worker }
1001*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: cannot find slot number for cancelled buffer", __FUNCTION__);
1002*38e8c45fSAndroid Build Coastguard Worker badSlotResult = slot;
1003*38e8c45fSAndroid Build Coastguard Worker } else {
1004*38e8c45fSAndroid Build Coastguard Worker sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
1005*38e8c45fSAndroid Build Coastguard Worker cancelBufferInputs[numBuffersCancelled].slot = slot;
1006*38e8c45fSAndroid Build Coastguard Worker cancelBufferInputs[numBuffersCancelled++].fence = fence;
1007*38e8c45fSAndroid Build Coastguard Worker }
1008*38e8c45fSAndroid Build Coastguard Worker }
1009*38e8c45fSAndroid Build Coastguard Worker cancelBufferInputs.resize(numBuffersCancelled);
1010*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->cancelBuffers(cancelBufferInputs, &cancelBufferOutputs);
1011*38e8c45fSAndroid Build Coastguard Worker
1012*38e8c45fSAndroid Build Coastguard Worker
1013*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < numBuffersCancelled; i++) {
1014*38e8c45fSAndroid Build Coastguard Worker mDequeuedSlots.erase(cancelBufferInputs[i].slot);
1015*38e8c45fSAndroid Build Coastguard Worker }
1016*38e8c45fSAndroid Build Coastguard Worker
1017*38e8c45fSAndroid Build Coastguard Worker if (badSlotResult != 0) {
1018*38e8c45fSAndroid Build Coastguard Worker return badSlotResult;
1019*38e8c45fSAndroid Build Coastguard Worker }
1020*38e8c45fSAndroid Build Coastguard Worker return OK;
1021*38e8c45fSAndroid Build Coastguard Worker }
1022*38e8c45fSAndroid Build Coastguard Worker
getSlotFromBufferLocked(android_native_buffer_t * buffer) const1023*38e8c45fSAndroid Build Coastguard Worker int Surface::getSlotFromBufferLocked(
1024*38e8c45fSAndroid Build Coastguard Worker android_native_buffer_t* buffer) const {
1025*38e8c45fSAndroid Build Coastguard Worker if (buffer == nullptr) {
1026*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: input buffer is null!", __FUNCTION__);
1027*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
1028*38e8c45fSAndroid Build Coastguard Worker }
1029*38e8c45fSAndroid Build Coastguard Worker
1030*38e8c45fSAndroid Build Coastguard Worker for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
1031*38e8c45fSAndroid Build Coastguard Worker if (mSlots[i].buffer != nullptr &&
1032*38e8c45fSAndroid Build Coastguard Worker mSlots[i].buffer->handle == buffer->handle) {
1033*38e8c45fSAndroid Build Coastguard Worker return i;
1034*38e8c45fSAndroid Build Coastguard Worker }
1035*38e8c45fSAndroid Build Coastguard Worker }
1036*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: unknown buffer: %p", __FUNCTION__, buffer->handle);
1037*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
1038*38e8c45fSAndroid Build Coastguard Worker }
1039*38e8c45fSAndroid Build Coastguard Worker
lockBuffer_DEPRECATED(android_native_buffer_t * buffer)1040*38e8c45fSAndroid Build Coastguard Worker int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) {
1041*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::lockBuffer");
1042*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
1043*38e8c45fSAndroid Build Coastguard Worker return OK;
1044*38e8c45fSAndroid Build Coastguard Worker }
1045*38e8c45fSAndroid Build Coastguard Worker
getQueueBufferInputLocked(android_native_buffer_t * buffer,int fenceFd,nsecs_t timestamp,IGraphicBufferProducer::QueueBufferInput * out)1046*38e8c45fSAndroid Build Coastguard Worker void Surface::getQueueBufferInputLocked(android_native_buffer_t* buffer, int fenceFd,
1047*38e8c45fSAndroid Build Coastguard Worker nsecs_t timestamp, IGraphicBufferProducer::QueueBufferInput* out) {
1048*38e8c45fSAndroid Build Coastguard Worker bool isAutoTimestamp = false;
1049*38e8c45fSAndroid Build Coastguard Worker
1050*38e8c45fSAndroid Build Coastguard Worker if (timestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
1051*38e8c45fSAndroid Build Coastguard Worker timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
1052*38e8c45fSAndroid Build Coastguard Worker isAutoTimestamp = true;
1053*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
1054*38e8c45fSAndroid Build Coastguard Worker timestamp / 1000000.0);
1055*38e8c45fSAndroid Build Coastguard Worker }
1056*38e8c45fSAndroid Build Coastguard Worker
1057*38e8c45fSAndroid Build Coastguard Worker // Make sure the crop rectangle is entirely inside the buffer.
1058*38e8c45fSAndroid Build Coastguard Worker Rect crop(Rect::EMPTY_RECT);
1059*38e8c45fSAndroid Build Coastguard Worker mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
1060*38e8c45fSAndroid Build Coastguard Worker
1061*38e8c45fSAndroid Build Coastguard Worker sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
1062*38e8c45fSAndroid Build Coastguard Worker IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
1063*38e8c45fSAndroid Build Coastguard Worker static_cast<android_dataspace>(mDataSpace), crop, mScalingMode,
1064*38e8c45fSAndroid Build Coastguard Worker mTransform ^ mStickyTransform, fence, mStickyTransform,
1065*38e8c45fSAndroid Build Coastguard Worker mEnableFrameTimestamps);
1066*38e8c45fSAndroid Build Coastguard Worker
1067*38e8c45fSAndroid Build Coastguard Worker // we should send HDR metadata as needed if this becomes a bottleneck
1068*38e8c45fSAndroid Build Coastguard Worker input.setHdrMetadata(mHdrMetadata);
1069*38e8c45fSAndroid Build Coastguard Worker
1070*38e8c45fSAndroid Build Coastguard Worker if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) {
1071*38e8c45fSAndroid Build Coastguard Worker input.setSurfaceDamage(Region::INVALID_REGION);
1072*38e8c45fSAndroid Build Coastguard Worker } else {
1073*38e8c45fSAndroid Build Coastguard Worker // Here we do two things:
1074*38e8c45fSAndroid Build Coastguard Worker // 1) The surface damage was specified using the OpenGL ES convention of
1075*38e8c45fSAndroid Build Coastguard Worker // the origin being in the bottom-left corner. Here we flip to the
1076*38e8c45fSAndroid Build Coastguard Worker // convention that the rest of the system uses (top-left corner) by
1077*38e8c45fSAndroid Build Coastguard Worker // subtracting all top/bottom coordinates from the buffer height.
1078*38e8c45fSAndroid Build Coastguard Worker // 2) If the buffer is coming in rotated (for example, because the EGL
1079*38e8c45fSAndroid Build Coastguard Worker // implementation is reacting to the transform hint coming back from
1080*38e8c45fSAndroid Build Coastguard Worker // SurfaceFlinger), the surface damage needs to be rotated the
1081*38e8c45fSAndroid Build Coastguard Worker // opposite direction, since it was generated assuming an unrotated
1082*38e8c45fSAndroid Build Coastguard Worker // buffer (the app doesn't know that the EGL implementation is
1083*38e8c45fSAndroid Build Coastguard Worker // reacting to the transform hint behind its back). The
1084*38e8c45fSAndroid Build Coastguard Worker // transformations in the switch statement below apply those
1085*38e8c45fSAndroid Build Coastguard Worker // complementary rotations (e.g., if 90 degrees, rotate 270 degrees).
1086*38e8c45fSAndroid Build Coastguard Worker
1087*38e8c45fSAndroid Build Coastguard Worker int width = buffer->width;
1088*38e8c45fSAndroid Build Coastguard Worker int height = buffer->height;
1089*38e8c45fSAndroid Build Coastguard Worker bool rotated90 = (mTransform ^ mStickyTransform) &
1090*38e8c45fSAndroid Build Coastguard Worker NATIVE_WINDOW_TRANSFORM_ROT_90;
1091*38e8c45fSAndroid Build Coastguard Worker if (rotated90) {
1092*38e8c45fSAndroid Build Coastguard Worker std::swap(width, height);
1093*38e8c45fSAndroid Build Coastguard Worker }
1094*38e8c45fSAndroid Build Coastguard Worker
1095*38e8c45fSAndroid Build Coastguard Worker Region flippedRegion;
1096*38e8c45fSAndroid Build Coastguard Worker for (auto rect : mDirtyRegion) {
1097*38e8c45fSAndroid Build Coastguard Worker int left = rect.left;
1098*38e8c45fSAndroid Build Coastguard Worker int right = rect.right;
1099*38e8c45fSAndroid Build Coastguard Worker int top = height - rect.bottom; // Flip from OpenGL convention
1100*38e8c45fSAndroid Build Coastguard Worker int bottom = height - rect.top; // Flip from OpenGL convention
1101*38e8c45fSAndroid Build Coastguard Worker switch (mTransform ^ mStickyTransform) {
1102*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_TRANSFORM_ROT_90: {
1103*38e8c45fSAndroid Build Coastguard Worker // Rotate 270 degrees
1104*38e8c45fSAndroid Build Coastguard Worker Rect flippedRect{top, width - right, bottom, width - left};
1105*38e8c45fSAndroid Build Coastguard Worker flippedRegion.orSelf(flippedRect);
1106*38e8c45fSAndroid Build Coastguard Worker break;
1107*38e8c45fSAndroid Build Coastguard Worker }
1108*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_TRANSFORM_ROT_180: {
1109*38e8c45fSAndroid Build Coastguard Worker // Rotate 180 degrees
1110*38e8c45fSAndroid Build Coastguard Worker Rect flippedRect{width - right, height - bottom,
1111*38e8c45fSAndroid Build Coastguard Worker width - left, height - top};
1112*38e8c45fSAndroid Build Coastguard Worker flippedRegion.orSelf(flippedRect);
1113*38e8c45fSAndroid Build Coastguard Worker break;
1114*38e8c45fSAndroid Build Coastguard Worker }
1115*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_TRANSFORM_ROT_270: {
1116*38e8c45fSAndroid Build Coastguard Worker // Rotate 90 degrees
1117*38e8c45fSAndroid Build Coastguard Worker Rect flippedRect{height - bottom, left,
1118*38e8c45fSAndroid Build Coastguard Worker height - top, right};
1119*38e8c45fSAndroid Build Coastguard Worker flippedRegion.orSelf(flippedRect);
1120*38e8c45fSAndroid Build Coastguard Worker break;
1121*38e8c45fSAndroid Build Coastguard Worker }
1122*38e8c45fSAndroid Build Coastguard Worker default: {
1123*38e8c45fSAndroid Build Coastguard Worker Rect flippedRect{left, top, right, bottom};
1124*38e8c45fSAndroid Build Coastguard Worker flippedRegion.orSelf(flippedRect);
1125*38e8c45fSAndroid Build Coastguard Worker break;
1126*38e8c45fSAndroid Build Coastguard Worker }
1127*38e8c45fSAndroid Build Coastguard Worker }
1128*38e8c45fSAndroid Build Coastguard Worker }
1129*38e8c45fSAndroid Build Coastguard Worker
1130*38e8c45fSAndroid Build Coastguard Worker input.setSurfaceDamage(flippedRegion);
1131*38e8c45fSAndroid Build Coastguard Worker }
1132*38e8c45fSAndroid Build Coastguard Worker *out = input;
1133*38e8c45fSAndroid Build Coastguard Worker }
1134*38e8c45fSAndroid Build Coastguard Worker
applyGrallocMetadataLocked(android_native_buffer_t * buffer,const IGraphicBufferProducer::QueueBufferInput & queueBufferInput)1135*38e8c45fSAndroid Build Coastguard Worker void Surface::applyGrallocMetadataLocked(
1136*38e8c45fSAndroid Build Coastguard Worker android_native_buffer_t* buffer,
1137*38e8c45fSAndroid Build Coastguard Worker const IGraphicBufferProducer::QueueBufferInput& queueBufferInput) {
1138*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
1139*38e8c45fSAndroid Build Coastguard Worker auto& mapper = GraphicBufferMapper::get();
1140*38e8c45fSAndroid Build Coastguard Worker mapper.setDataspace(buffer->handle, static_cast<ui::Dataspace>(queueBufferInput.dataSpace));
1141*38e8c45fSAndroid Build Coastguard Worker if (mHdrMetadataIsSet & HdrMetadata::SMPTE2086)
1142*38e8c45fSAndroid Build Coastguard Worker mapper.setSmpte2086(buffer->handle, queueBufferInput.getHdrMetadata().getSmpte2086());
1143*38e8c45fSAndroid Build Coastguard Worker if (mHdrMetadataIsSet & HdrMetadata::CTA861_3)
1144*38e8c45fSAndroid Build Coastguard Worker mapper.setCta861_3(buffer->handle, queueBufferInput.getHdrMetadata().getCta8613());
1145*38e8c45fSAndroid Build Coastguard Worker if (mHdrMetadataIsSet & HdrMetadata::HDR10PLUS)
1146*38e8c45fSAndroid Build Coastguard Worker mapper.setSmpte2094_40(buffer->handle, queueBufferInput.getHdrMetadata().getHdr10Plus());
1147*38e8c45fSAndroid Build Coastguard Worker }
1148*38e8c45fSAndroid Build Coastguard Worker
onBufferQueuedLocked(int slot,sp<Fence> fence,const IGraphicBufferProducer::QueueBufferOutput & output)1149*38e8c45fSAndroid Build Coastguard Worker void Surface::onBufferQueuedLocked(int slot, sp<Fence> fence,
1150*38e8c45fSAndroid Build Coastguard Worker const IGraphicBufferProducer::QueueBufferOutput& output) {
1151*38e8c45fSAndroid Build Coastguard Worker mDequeuedSlots.erase(slot);
1152*38e8c45fSAndroid Build Coastguard Worker
1153*38e8c45fSAndroid Build Coastguard Worker if (mEnableFrameTimestamps) {
1154*38e8c45fSAndroid Build Coastguard Worker mFrameEventHistory->applyDelta(output.frameTimestamps);
1155*38e8c45fSAndroid Build Coastguard Worker // Update timestamps with the local acquire fence.
1156*38e8c45fSAndroid Build Coastguard Worker // The consumer doesn't send it back to prevent us from having two
1157*38e8c45fSAndroid Build Coastguard Worker // file descriptors of the same fence.
1158*38e8c45fSAndroid Build Coastguard Worker mFrameEventHistory->updateAcquireFence(mNextFrameNumber,
1159*38e8c45fSAndroid Build Coastguard Worker std::make_shared<FenceTime>(fence));
1160*38e8c45fSAndroid Build Coastguard Worker
1161*38e8c45fSAndroid Build Coastguard Worker // Cache timestamps of signaled fences so we can close their file
1162*38e8c45fSAndroid Build Coastguard Worker // descriptors.
1163*38e8c45fSAndroid Build Coastguard Worker mFrameEventHistory->updateSignalTimes();
1164*38e8c45fSAndroid Build Coastguard Worker }
1165*38e8c45fSAndroid Build Coastguard Worker
1166*38e8c45fSAndroid Build Coastguard Worker mLastFrameNumber = mNextFrameNumber;
1167*38e8c45fSAndroid Build Coastguard Worker
1168*38e8c45fSAndroid Build Coastguard Worker mDefaultWidth = output.width;
1169*38e8c45fSAndroid Build Coastguard Worker mDefaultHeight = output.height;
1170*38e8c45fSAndroid Build Coastguard Worker mNextFrameNumber = output.nextFrameNumber;
1171*38e8c45fSAndroid Build Coastguard Worker
1172*38e8c45fSAndroid Build Coastguard Worker // Ignore transform hint if sticky transform is set or transform to display inverse flag is
1173*38e8c45fSAndroid Build Coastguard Worker // set.
1174*38e8c45fSAndroid Build Coastguard Worker if (mStickyTransform == 0 && !transformToDisplayInverse()) {
1175*38e8c45fSAndroid Build Coastguard Worker mTransformHint = output.transformHint;
1176*38e8c45fSAndroid Build Coastguard Worker }
1177*38e8c45fSAndroid Build Coastguard Worker
1178*38e8c45fSAndroid Build Coastguard Worker mConsumerRunningBehind = (output.numPendingBuffers >= 2);
1179*38e8c45fSAndroid Build Coastguard Worker
1180*38e8c45fSAndroid Build Coastguard Worker if (!mConnectedToCpu) {
1181*38e8c45fSAndroid Build Coastguard Worker // Clear surface damage back to full-buffer
1182*38e8c45fSAndroid Build Coastguard Worker mDirtyRegion = Region::INVALID_REGION;
1183*38e8c45fSAndroid Build Coastguard Worker }
1184*38e8c45fSAndroid Build Coastguard Worker
1185*38e8c45fSAndroid Build Coastguard Worker if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == slot) {
1186*38e8c45fSAndroid Build Coastguard Worker mSharedBufferHasBeenQueued = true;
1187*38e8c45fSAndroid Build Coastguard Worker }
1188*38e8c45fSAndroid Build Coastguard Worker
1189*38e8c45fSAndroid Build Coastguard Worker mQueueBufferCondition.broadcast();
1190*38e8c45fSAndroid Build Coastguard Worker
1191*38e8c45fSAndroid Build Coastguard Worker if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
1192*38e8c45fSAndroid Build Coastguard Worker static gui::FenceMonitor gpuCompletionThread("GPU completion");
1193*38e8c45fSAndroid Build Coastguard Worker gpuCompletionThread.queueFence(fence);
1194*38e8c45fSAndroid Build Coastguard Worker }
1195*38e8c45fSAndroid Build Coastguard Worker }
1196*38e8c45fSAndroid Build Coastguard Worker
1197*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
1198*38e8c45fSAndroid Build Coastguard Worker
queueBuffer(android_native_buffer_t * buffer,int fenceFd,SurfaceQueueBufferOutput * surfaceOutput)1199*38e8c45fSAndroid Build Coastguard Worker int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd,
1200*38e8c45fSAndroid Build Coastguard Worker SurfaceQueueBufferOutput* surfaceOutput) {
1201*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
1202*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::queueBuffer");
1203*38e8c45fSAndroid Build Coastguard Worker
1204*38e8c45fSAndroid Build Coastguard Worker IGraphicBufferProducer::QueueBufferOutput output;
1205*38e8c45fSAndroid Build Coastguard Worker IGraphicBufferProducer::QueueBufferInput input;
1206*38e8c45fSAndroid Build Coastguard Worker int slot;
1207*38e8c45fSAndroid Build Coastguard Worker sp<Fence> fence;
1208*38e8c45fSAndroid Build Coastguard Worker {
1209*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
1210*38e8c45fSAndroid Build Coastguard Worker
1211*38e8c45fSAndroid Build Coastguard Worker slot = getSlotFromBufferLocked(buffer);
1212*38e8c45fSAndroid Build Coastguard Worker if (slot < 0) {
1213*38e8c45fSAndroid Build Coastguard Worker if (fenceFd >= 0) {
1214*38e8c45fSAndroid Build Coastguard Worker close(fenceFd);
1215*38e8c45fSAndroid Build Coastguard Worker }
1216*38e8c45fSAndroid Build Coastguard Worker return slot;
1217*38e8c45fSAndroid Build Coastguard Worker }
1218*38e8c45fSAndroid Build Coastguard Worker if (mSharedBufferSlot == slot && mSharedBufferHasBeenQueued) {
1219*38e8c45fSAndroid Build Coastguard Worker if (fenceFd >= 0) {
1220*38e8c45fSAndroid Build Coastguard Worker close(fenceFd);
1221*38e8c45fSAndroid Build Coastguard Worker }
1222*38e8c45fSAndroid Build Coastguard Worker return OK;
1223*38e8c45fSAndroid Build Coastguard Worker }
1224*38e8c45fSAndroid Build Coastguard Worker
1225*38e8c45fSAndroid Build Coastguard Worker getQueueBufferInputLocked(buffer, fenceFd, mTimestamp, &input);
1226*38e8c45fSAndroid Build Coastguard Worker applyGrallocMetadataLocked(buffer, input);
1227*38e8c45fSAndroid Build Coastguard Worker fence = input.fence;
1228*38e8c45fSAndroid Build Coastguard Worker }
1229*38e8c45fSAndroid Build Coastguard Worker nsecs_t now = systemTime();
1230*38e8c45fSAndroid Build Coastguard Worker // Drop the lock temporarily while we touch the underlying producer. In the case of a local
1231*38e8c45fSAndroid Build Coastguard Worker // BufferQueue, the following should be allowable:
1232*38e8c45fSAndroid Build Coastguard Worker //
1233*38e8c45fSAndroid Build Coastguard Worker // Surface::queueBuffer
1234*38e8c45fSAndroid Build Coastguard Worker // -> IConsumerListener::onFrameAvailable callback triggers automatically
1235*38e8c45fSAndroid Build Coastguard Worker // -> implementation calls IGraphicBufferConsumer::acquire/release immediately
1236*38e8c45fSAndroid Build Coastguard Worker // -> SurfaceListener::onBufferRelesed callback triggers automatically
1237*38e8c45fSAndroid Build Coastguard Worker // -> implementation calls Surface::dequeueBuffer
1238*38e8c45fSAndroid Build Coastguard Worker status_t err = mGraphicBufferProducer->queueBuffer(slot, input, &output);
1239*38e8c45fSAndroid Build Coastguard Worker {
1240*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
1241*38e8c45fSAndroid Build Coastguard Worker
1242*38e8c45fSAndroid Build Coastguard Worker mLastQueueDuration = systemTime() - now;
1243*38e8c45fSAndroid Build Coastguard Worker if (err != OK) {
1244*38e8c45fSAndroid Build Coastguard Worker ALOGE("queueBuffer: error queuing buffer, %d", err);
1245*38e8c45fSAndroid Build Coastguard Worker }
1246*38e8c45fSAndroid Build Coastguard Worker
1247*38e8c45fSAndroid Build Coastguard Worker onBufferQueuedLocked(slot, fence, output);
1248*38e8c45fSAndroid Build Coastguard Worker }
1249*38e8c45fSAndroid Build Coastguard Worker
1250*38e8c45fSAndroid Build Coastguard Worker if (surfaceOutput != nullptr) {
1251*38e8c45fSAndroid Build Coastguard Worker *surfaceOutput = {.bufferReplaced = output.bufferReplaced};
1252*38e8c45fSAndroid Build Coastguard Worker }
1253*38e8c45fSAndroid Build Coastguard Worker
1254*38e8c45fSAndroid Build Coastguard Worker return err;
1255*38e8c45fSAndroid Build Coastguard Worker }
1256*38e8c45fSAndroid Build Coastguard Worker
1257*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
queueBuffers(const std::vector<BatchQueuedBuffer> & buffers,std::vector<SurfaceQueueBufferOutput> * queueBufferOutputs)1258*38e8c45fSAndroid Build Coastguard Worker int Surface::queueBuffers(const std::vector<BatchQueuedBuffer>& buffers,
1259*38e8c45fSAndroid Build Coastguard Worker std::vector<SurfaceQueueBufferOutput>* queueBufferOutputs)
1260*38e8c45fSAndroid Build Coastguard Worker #else
1261*38e8c45fSAndroid Build Coastguard Worker int Surface::queueBuffers(const std::vector<BatchQueuedBuffer>& buffers)
1262*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
1263*38e8c45fSAndroid Build Coastguard Worker {
1264*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
1265*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::queueBuffers");
1266*38e8c45fSAndroid Build Coastguard Worker
1267*38e8c45fSAndroid Build Coastguard Worker size_t numBuffers = buffers.size();
1268*38e8c45fSAndroid Build Coastguard Worker std::vector<IGraphicBufferProducer::QueueBufferInput> igbpQueueBufferInputs(numBuffers);
1269*38e8c45fSAndroid Build Coastguard Worker std::vector<IGraphicBufferProducer::QueueBufferOutput> igbpQueueBufferOutputs;
1270*38e8c45fSAndroid Build Coastguard Worker std::vector<int> bufferSlots(numBuffers, -1);
1271*38e8c45fSAndroid Build Coastguard Worker std::vector<sp<Fence>> bufferFences(numBuffers);
1272*38e8c45fSAndroid Build Coastguard Worker
1273*38e8c45fSAndroid Build Coastguard Worker int err;
1274*38e8c45fSAndroid Build Coastguard Worker {
1275*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
1276*38e8c45fSAndroid Build Coastguard Worker
1277*38e8c45fSAndroid Build Coastguard Worker if (mSharedBufferMode) {
1278*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: batched operation is not supported in shared buffer mode", __FUNCTION__);
1279*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
1280*38e8c45fSAndroid Build Coastguard Worker }
1281*38e8c45fSAndroid Build Coastguard Worker
1282*38e8c45fSAndroid Build Coastguard Worker for (size_t batchIdx = 0; batchIdx < numBuffers; batchIdx++) {
1283*38e8c45fSAndroid Build Coastguard Worker int i = getSlotFromBufferLocked(buffers[batchIdx].buffer);
1284*38e8c45fSAndroid Build Coastguard Worker if (i < 0) {
1285*38e8c45fSAndroid Build Coastguard Worker if (buffers[batchIdx].fenceFd >= 0) {
1286*38e8c45fSAndroid Build Coastguard Worker close(buffers[batchIdx].fenceFd);
1287*38e8c45fSAndroid Build Coastguard Worker }
1288*38e8c45fSAndroid Build Coastguard Worker return i;
1289*38e8c45fSAndroid Build Coastguard Worker }
1290*38e8c45fSAndroid Build Coastguard Worker bufferSlots[batchIdx] = i;
1291*38e8c45fSAndroid Build Coastguard Worker
1292*38e8c45fSAndroid Build Coastguard Worker IGraphicBufferProducer::QueueBufferInput input;
1293*38e8c45fSAndroid Build Coastguard Worker getQueueBufferInputLocked(buffers[batchIdx].buffer, buffers[batchIdx].fenceFd,
1294*38e8c45fSAndroid Build Coastguard Worker buffers[batchIdx].timestamp, &input);
1295*38e8c45fSAndroid Build Coastguard Worker input.slot = i;
1296*38e8c45fSAndroid Build Coastguard Worker bufferFences[batchIdx] = input.fence;
1297*38e8c45fSAndroid Build Coastguard Worker igbpQueueBufferInputs[batchIdx] = input;
1298*38e8c45fSAndroid Build Coastguard Worker }
1299*38e8c45fSAndroid Build Coastguard Worker }
1300*38e8c45fSAndroid Build Coastguard Worker nsecs_t now = systemTime();
1301*38e8c45fSAndroid Build Coastguard Worker err = mGraphicBufferProducer->queueBuffers(igbpQueueBufferInputs, &igbpQueueBufferOutputs);
1302*38e8c45fSAndroid Build Coastguard Worker {
1303*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
1304*38e8c45fSAndroid Build Coastguard Worker mLastQueueDuration = systemTime() - now;
1305*38e8c45fSAndroid Build Coastguard Worker if (err != OK) {
1306*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: error queuing buffer, %d", __FUNCTION__, err);
1307*38e8c45fSAndroid Build Coastguard Worker }
1308*38e8c45fSAndroid Build Coastguard Worker
1309*38e8c45fSAndroid Build Coastguard Worker for (size_t batchIdx = 0; batchIdx < numBuffers; batchIdx++) {
1310*38e8c45fSAndroid Build Coastguard Worker onBufferQueuedLocked(bufferSlots[batchIdx], bufferFences[batchIdx],
1311*38e8c45fSAndroid Build Coastguard Worker igbpQueueBufferOutputs[batchIdx]);
1312*38e8c45fSAndroid Build Coastguard Worker }
1313*38e8c45fSAndroid Build Coastguard Worker }
1314*38e8c45fSAndroid Build Coastguard Worker
1315*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
1316*38e8c45fSAndroid Build Coastguard Worker if (queueBufferOutputs != nullptr) {
1317*38e8c45fSAndroid Build Coastguard Worker queueBufferOutputs->clear();
1318*38e8c45fSAndroid Build Coastguard Worker queueBufferOutputs->resize(numBuffers);
1319*38e8c45fSAndroid Build Coastguard Worker for (size_t batchIdx = 0; batchIdx < numBuffers; batchIdx++) {
1320*38e8c45fSAndroid Build Coastguard Worker (*queueBufferOutputs)[batchIdx].bufferReplaced =
1321*38e8c45fSAndroid Build Coastguard Worker igbpQueueBufferOutputs[batchIdx].bufferReplaced;
1322*38e8c45fSAndroid Build Coastguard Worker }
1323*38e8c45fSAndroid Build Coastguard Worker }
1324*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
1325*38e8c45fSAndroid Build Coastguard Worker
1326*38e8c45fSAndroid Build Coastguard Worker return err;
1327*38e8c45fSAndroid Build Coastguard Worker }
1328*38e8c45fSAndroid Build Coastguard Worker
1329*38e8c45fSAndroid Build Coastguard Worker #else
1330*38e8c45fSAndroid Build Coastguard Worker
queueBuffer(android_native_buffer_t * buffer,int fenceFd)1331*38e8c45fSAndroid Build Coastguard Worker int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
1332*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
1333*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::queueBuffer");
1334*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
1335*38e8c45fSAndroid Build Coastguard Worker
1336*38e8c45fSAndroid Build Coastguard Worker int i = getSlotFromBufferLocked(buffer);
1337*38e8c45fSAndroid Build Coastguard Worker if (i < 0) {
1338*38e8c45fSAndroid Build Coastguard Worker if (fenceFd >= 0) {
1339*38e8c45fSAndroid Build Coastguard Worker close(fenceFd);
1340*38e8c45fSAndroid Build Coastguard Worker }
1341*38e8c45fSAndroid Build Coastguard Worker return i;
1342*38e8c45fSAndroid Build Coastguard Worker }
1343*38e8c45fSAndroid Build Coastguard Worker if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
1344*38e8c45fSAndroid Build Coastguard Worker if (fenceFd >= 0) {
1345*38e8c45fSAndroid Build Coastguard Worker close(fenceFd);
1346*38e8c45fSAndroid Build Coastguard Worker }
1347*38e8c45fSAndroid Build Coastguard Worker return OK;
1348*38e8c45fSAndroid Build Coastguard Worker }
1349*38e8c45fSAndroid Build Coastguard Worker
1350*38e8c45fSAndroid Build Coastguard Worker IGraphicBufferProducer::QueueBufferOutput output;
1351*38e8c45fSAndroid Build Coastguard Worker IGraphicBufferProducer::QueueBufferInput input;
1352*38e8c45fSAndroid Build Coastguard Worker getQueueBufferInputLocked(buffer, fenceFd, mTimestamp, &input);
1353*38e8c45fSAndroid Build Coastguard Worker applyGrallocMetadataLocked(buffer, input);
1354*38e8c45fSAndroid Build Coastguard Worker sp<Fence> fence = input.fence;
1355*38e8c45fSAndroid Build Coastguard Worker
1356*38e8c45fSAndroid Build Coastguard Worker nsecs_t now = systemTime();
1357*38e8c45fSAndroid Build Coastguard Worker
1358*38e8c45fSAndroid Build Coastguard Worker status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
1359*38e8c45fSAndroid Build Coastguard Worker mLastQueueDuration = systemTime() - now;
1360*38e8c45fSAndroid Build Coastguard Worker if (err != OK) {
1361*38e8c45fSAndroid Build Coastguard Worker ALOGE("queueBuffer: error queuing buffer, %d", err);
1362*38e8c45fSAndroid Build Coastguard Worker }
1363*38e8c45fSAndroid Build Coastguard Worker
1364*38e8c45fSAndroid Build Coastguard Worker onBufferQueuedLocked(i, fence, output);
1365*38e8c45fSAndroid Build Coastguard Worker return err;
1366*38e8c45fSAndroid Build Coastguard Worker }
1367*38e8c45fSAndroid Build Coastguard Worker
queueBuffers(const std::vector<BatchQueuedBuffer> & buffers)1368*38e8c45fSAndroid Build Coastguard Worker int Surface::queueBuffers(const std::vector<BatchQueuedBuffer>& buffers) {
1369*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
1370*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::queueBuffers");
1371*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
1372*38e8c45fSAndroid Build Coastguard Worker
1373*38e8c45fSAndroid Build Coastguard Worker if (mSharedBufferMode) {
1374*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: batched operation is not supported in shared buffer mode", __FUNCTION__);
1375*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
1376*38e8c45fSAndroid Build Coastguard Worker }
1377*38e8c45fSAndroid Build Coastguard Worker
1378*38e8c45fSAndroid Build Coastguard Worker size_t numBuffers = buffers.size();
1379*38e8c45fSAndroid Build Coastguard Worker std::vector<IGraphicBufferProducer::QueueBufferInput> queueBufferInputs(numBuffers);
1380*38e8c45fSAndroid Build Coastguard Worker std::vector<IGraphicBufferProducer::QueueBufferOutput> queueBufferOutputs;
1381*38e8c45fSAndroid Build Coastguard Worker std::vector<int> bufferSlots(numBuffers, -1);
1382*38e8c45fSAndroid Build Coastguard Worker std::vector<sp<Fence>> bufferFences(numBuffers);
1383*38e8c45fSAndroid Build Coastguard Worker
1384*38e8c45fSAndroid Build Coastguard Worker for (size_t batchIdx = 0; batchIdx < numBuffers; batchIdx++) {
1385*38e8c45fSAndroid Build Coastguard Worker int i = getSlotFromBufferLocked(buffers[batchIdx].buffer);
1386*38e8c45fSAndroid Build Coastguard Worker if (i < 0) {
1387*38e8c45fSAndroid Build Coastguard Worker if (buffers[batchIdx].fenceFd >= 0) {
1388*38e8c45fSAndroid Build Coastguard Worker close(buffers[batchIdx].fenceFd);
1389*38e8c45fSAndroid Build Coastguard Worker }
1390*38e8c45fSAndroid Build Coastguard Worker return i;
1391*38e8c45fSAndroid Build Coastguard Worker }
1392*38e8c45fSAndroid Build Coastguard Worker bufferSlots[batchIdx] = i;
1393*38e8c45fSAndroid Build Coastguard Worker
1394*38e8c45fSAndroid Build Coastguard Worker IGraphicBufferProducer::QueueBufferInput input;
1395*38e8c45fSAndroid Build Coastguard Worker getQueueBufferInputLocked(
1396*38e8c45fSAndroid Build Coastguard Worker buffers[batchIdx].buffer, buffers[batchIdx].fenceFd, buffers[batchIdx].timestamp,
1397*38e8c45fSAndroid Build Coastguard Worker &input);
1398*38e8c45fSAndroid Build Coastguard Worker bufferFences[batchIdx] = input.fence;
1399*38e8c45fSAndroid Build Coastguard Worker queueBufferInputs[batchIdx] = input;
1400*38e8c45fSAndroid Build Coastguard Worker }
1401*38e8c45fSAndroid Build Coastguard Worker
1402*38e8c45fSAndroid Build Coastguard Worker nsecs_t now = systemTime();
1403*38e8c45fSAndroid Build Coastguard Worker status_t err = mGraphicBufferProducer->queueBuffers(queueBufferInputs, &queueBufferOutputs);
1404*38e8c45fSAndroid Build Coastguard Worker mLastQueueDuration = systemTime() - now;
1405*38e8c45fSAndroid Build Coastguard Worker if (err != OK) {
1406*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: error queuing buffer, %d", __FUNCTION__, err);
1407*38e8c45fSAndroid Build Coastguard Worker }
1408*38e8c45fSAndroid Build Coastguard Worker
1409*38e8c45fSAndroid Build Coastguard Worker
1410*38e8c45fSAndroid Build Coastguard Worker for (size_t batchIdx = 0; batchIdx < numBuffers; batchIdx++) {
1411*38e8c45fSAndroid Build Coastguard Worker onBufferQueuedLocked(bufferSlots[batchIdx], bufferFences[batchIdx],
1412*38e8c45fSAndroid Build Coastguard Worker queueBufferOutputs[batchIdx]);
1413*38e8c45fSAndroid Build Coastguard Worker }
1414*38e8c45fSAndroid Build Coastguard Worker
1415*38e8c45fSAndroid Build Coastguard Worker return err;
1416*38e8c45fSAndroid Build Coastguard Worker }
1417*38e8c45fSAndroid Build Coastguard Worker
1418*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
1419*38e8c45fSAndroid Build Coastguard Worker
querySupportedTimestampsLocked() const1420*38e8c45fSAndroid Build Coastguard Worker void Surface::querySupportedTimestampsLocked() const {
1421*38e8c45fSAndroid Build Coastguard Worker // mMutex must be locked when calling this method.
1422*38e8c45fSAndroid Build Coastguard Worker
1423*38e8c45fSAndroid Build Coastguard Worker if (mQueriedSupportedTimestamps) {
1424*38e8c45fSAndroid Build Coastguard Worker return;
1425*38e8c45fSAndroid Build Coastguard Worker }
1426*38e8c45fSAndroid Build Coastguard Worker mQueriedSupportedTimestamps = true;
1427*38e8c45fSAndroid Build Coastguard Worker
1428*38e8c45fSAndroid Build Coastguard Worker std::vector<FrameEvent> supportedFrameTimestamps;
1429*38e8c45fSAndroid Build Coastguard Worker binder::Status status =
1430*38e8c45fSAndroid Build Coastguard Worker composerServiceAIDL()->getSupportedFrameTimestamps(&supportedFrameTimestamps);
1431*38e8c45fSAndroid Build Coastguard Worker
1432*38e8c45fSAndroid Build Coastguard Worker if (!status.isOk()) {
1433*38e8c45fSAndroid Build Coastguard Worker return;
1434*38e8c45fSAndroid Build Coastguard Worker }
1435*38e8c45fSAndroid Build Coastguard Worker
1436*38e8c45fSAndroid Build Coastguard Worker for (auto sft : supportedFrameTimestamps) {
1437*38e8c45fSAndroid Build Coastguard Worker if (sft == FrameEvent::DISPLAY_PRESENT) {
1438*38e8c45fSAndroid Build Coastguard Worker mFrameTimestampsSupportsPresent = true;
1439*38e8c45fSAndroid Build Coastguard Worker }
1440*38e8c45fSAndroid Build Coastguard Worker }
1441*38e8c45fSAndroid Build Coastguard Worker }
1442*38e8c45fSAndroid Build Coastguard Worker
query(int what,int * value) const1443*38e8c45fSAndroid Build Coastguard Worker int Surface::query(int what, int* value) const {
1444*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
1445*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::query");
1446*38e8c45fSAndroid Build Coastguard Worker { // scope for the lock
1447*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
1448*38e8c45fSAndroid Build Coastguard Worker switch (what) {
1449*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_FORMAT:
1450*38e8c45fSAndroid Build Coastguard Worker if (mReqFormat) {
1451*38e8c45fSAndroid Build Coastguard Worker *value = static_cast<int>(mReqFormat);
1452*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1453*38e8c45fSAndroid Build Coastguard Worker }
1454*38e8c45fSAndroid Build Coastguard Worker break;
1455*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
1456*38e8c45fSAndroid Build Coastguard Worker status_t err = mGraphicBufferProducer->query(what, value);
1457*38e8c45fSAndroid Build Coastguard Worker if (err == NO_ERROR) {
1458*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1459*38e8c45fSAndroid Build Coastguard Worker }
1460*38e8c45fSAndroid Build Coastguard Worker sp<gui::ISurfaceComposer> surfaceComposer = composerServiceAIDL();
1461*38e8c45fSAndroid Build Coastguard Worker if (surfaceComposer == nullptr) {
1462*38e8c45fSAndroid Build Coastguard Worker return -EPERM; // likely permissions error
1463*38e8c45fSAndroid Build Coastguard Worker }
1464*38e8c45fSAndroid Build Coastguard Worker // ISurfaceComposer no longer supports authenticateSurfaceTexture
1465*38e8c45fSAndroid Build Coastguard Worker *value = 0;
1466*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1467*38e8c45fSAndroid Build Coastguard Worker }
1468*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_CONCRETE_TYPE:
1469*38e8c45fSAndroid Build Coastguard Worker *value = NATIVE_WINDOW_SURFACE;
1470*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1471*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_DEFAULT_WIDTH:
1472*38e8c45fSAndroid Build Coastguard Worker *value = static_cast<int>(
1473*38e8c45fSAndroid Build Coastguard Worker mUserWidth ? mUserWidth : mDefaultWidth);
1474*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1475*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_DEFAULT_HEIGHT:
1476*38e8c45fSAndroid Build Coastguard Worker *value = static_cast<int>(
1477*38e8c45fSAndroid Build Coastguard Worker mUserHeight ? mUserHeight : mDefaultHeight);
1478*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1479*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_TRANSFORM_HINT:
1480*38e8c45fSAndroid Build Coastguard Worker *value = static_cast<int>(getTransformHint());
1481*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1482*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
1483*38e8c45fSAndroid Build Coastguard Worker status_t err = NO_ERROR;
1484*38e8c45fSAndroid Build Coastguard Worker if (!mConsumerRunningBehind) {
1485*38e8c45fSAndroid Build Coastguard Worker *value = 0;
1486*38e8c45fSAndroid Build Coastguard Worker } else {
1487*38e8c45fSAndroid Build Coastguard Worker err = mGraphicBufferProducer->query(what, value);
1488*38e8c45fSAndroid Build Coastguard Worker if (err == NO_ERROR) {
1489*38e8c45fSAndroid Build Coastguard Worker mConsumerRunningBehind = *value;
1490*38e8c45fSAndroid Build Coastguard Worker }
1491*38e8c45fSAndroid Build Coastguard Worker }
1492*38e8c45fSAndroid Build Coastguard Worker return err;
1493*38e8c45fSAndroid Build Coastguard Worker }
1494*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_BUFFER_AGE: {
1495*38e8c45fSAndroid Build Coastguard Worker if (mBufferAge > INT32_MAX) {
1496*38e8c45fSAndroid Build Coastguard Worker *value = 0;
1497*38e8c45fSAndroid Build Coastguard Worker } else {
1498*38e8c45fSAndroid Build Coastguard Worker *value = static_cast<int32_t>(mBufferAge);
1499*38e8c45fSAndroid Build Coastguard Worker }
1500*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1501*38e8c45fSAndroid Build Coastguard Worker }
1502*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: {
1503*38e8c45fSAndroid Build Coastguard Worker int64_t durationUs = mLastDequeueDuration / 1000;
1504*38e8c45fSAndroid Build Coastguard Worker *value = durationUs > std::numeric_limits<int>::max() ?
1505*38e8c45fSAndroid Build Coastguard Worker std::numeric_limits<int>::max() :
1506*38e8c45fSAndroid Build Coastguard Worker static_cast<int>(durationUs);
1507*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1508*38e8c45fSAndroid Build Coastguard Worker }
1509*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_LAST_QUEUE_DURATION: {
1510*38e8c45fSAndroid Build Coastguard Worker int64_t durationUs = mLastQueueDuration / 1000;
1511*38e8c45fSAndroid Build Coastguard Worker *value = durationUs > std::numeric_limits<int>::max() ?
1512*38e8c45fSAndroid Build Coastguard Worker std::numeric_limits<int>::max() :
1513*38e8c45fSAndroid Build Coastguard Worker static_cast<int>(durationUs);
1514*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1515*38e8c45fSAndroid Build Coastguard Worker }
1516*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT: {
1517*38e8c45fSAndroid Build Coastguard Worker querySupportedTimestampsLocked();
1518*38e8c45fSAndroid Build Coastguard Worker *value = mFrameTimestampsSupportsPresent ? 1 : 0;
1519*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1520*38e8c45fSAndroid Build Coastguard Worker }
1521*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_IS_VALID: {
1522*38e8c45fSAndroid Build Coastguard Worker *value = mGraphicBufferProducer != nullptr ? 1 : 0;
1523*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1524*38e8c45fSAndroid Build Coastguard Worker }
1525*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_DATASPACE: {
1526*38e8c45fSAndroid Build Coastguard Worker *value = static_cast<int>(mDataSpace);
1527*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1528*38e8c45fSAndroid Build Coastguard Worker }
1529*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_MAX_BUFFER_COUNT: {
1530*38e8c45fSAndroid Build Coastguard Worker *value = mMaxBufferCount;
1531*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1532*38e8c45fSAndroid Build Coastguard Worker }
1533*38e8c45fSAndroid Build Coastguard Worker }
1534*38e8c45fSAndroid Build Coastguard Worker }
1535*38e8c45fSAndroid Build Coastguard Worker return mGraphicBufferProducer->query(what, value);
1536*38e8c45fSAndroid Build Coastguard Worker }
1537*38e8c45fSAndroid Build Coastguard Worker
perform(int operation,va_list args)1538*38e8c45fSAndroid Build Coastguard Worker int Surface::perform(int operation, va_list args)
1539*38e8c45fSAndroid Build Coastguard Worker {
1540*38e8c45fSAndroid Build Coastguard Worker int res = NO_ERROR;
1541*38e8c45fSAndroid Build Coastguard Worker switch (operation) {
1542*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_CONNECT:
1543*38e8c45fSAndroid Build Coastguard Worker // deprecated. must return NO_ERROR.
1544*38e8c45fSAndroid Build Coastguard Worker break;
1545*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_DISCONNECT:
1546*38e8c45fSAndroid Build Coastguard Worker // deprecated. must return NO_ERROR.
1547*38e8c45fSAndroid Build Coastguard Worker break;
1548*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_USAGE:
1549*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetUsage(args);
1550*38e8c45fSAndroid Build Coastguard Worker break;
1551*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_CROP:
1552*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetCrop(args);
1553*38e8c45fSAndroid Build Coastguard Worker break;
1554*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFER_COUNT:
1555*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetBufferCount(args);
1556*38e8c45fSAndroid Build Coastguard Worker break;
1557*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
1558*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetBuffersGeometry(args);
1559*38e8c45fSAndroid Build Coastguard Worker break;
1560*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
1561*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetBuffersTransform(args);
1562*38e8c45fSAndroid Build Coastguard Worker break;
1563*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM:
1564*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetBuffersStickyTransform(args);
1565*38e8c45fSAndroid Build Coastguard Worker break;
1566*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
1567*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetBuffersTimestamp(args);
1568*38e8c45fSAndroid Build Coastguard Worker break;
1569*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
1570*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetBuffersDimensions(args);
1571*38e8c45fSAndroid Build Coastguard Worker break;
1572*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
1573*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetBuffersUserDimensions(args);
1574*38e8c45fSAndroid Build Coastguard Worker break;
1575*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
1576*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetBuffersFormat(args);
1577*38e8c45fSAndroid Build Coastguard Worker break;
1578*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_LOCK:
1579*38e8c45fSAndroid Build Coastguard Worker res = dispatchLock(args);
1580*38e8c45fSAndroid Build Coastguard Worker break;
1581*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_UNLOCK_AND_POST:
1582*38e8c45fSAndroid Build Coastguard Worker res = dispatchUnlockAndPost(args);
1583*38e8c45fSAndroid Build Coastguard Worker break;
1584*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_SCALING_MODE:
1585*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetScalingMode(args);
1586*38e8c45fSAndroid Build Coastguard Worker break;
1587*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_API_CONNECT:
1588*38e8c45fSAndroid Build Coastguard Worker res = dispatchConnect(args);
1589*38e8c45fSAndroid Build Coastguard Worker break;
1590*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_API_DISCONNECT:
1591*38e8c45fSAndroid Build Coastguard Worker res = dispatchDisconnect(args);
1592*38e8c45fSAndroid Build Coastguard Worker break;
1593*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_SIDEBAND_STREAM:
1594*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetSidebandStream(args);
1595*38e8c45fSAndroid Build Coastguard Worker break;
1596*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
1597*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetBuffersDataSpace(args);
1598*38e8c45fSAndroid Build Coastguard Worker break;
1599*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA:
1600*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetBuffersSmpte2086Metadata(args);
1601*38e8c45fSAndroid Build Coastguard Worker break;
1602*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA:
1603*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetBuffersCta8613Metadata(args);
1604*38e8c45fSAndroid Build Coastguard Worker break;
1605*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA:
1606*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetBuffersHdr10PlusMetadata(args);
1607*38e8c45fSAndroid Build Coastguard Worker break;
1608*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
1609*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetSurfaceDamage(args);
1610*38e8c45fSAndroid Build Coastguard Worker break;
1611*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE:
1612*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetSharedBufferMode(args);
1613*38e8c45fSAndroid Build Coastguard Worker break;
1614*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_AUTO_REFRESH:
1615*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetAutoRefresh(args);
1616*38e8c45fSAndroid Build Coastguard Worker break;
1617*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION:
1618*38e8c45fSAndroid Build Coastguard Worker res = dispatchGetDisplayRefreshCycleDuration(args);
1619*38e8c45fSAndroid Build Coastguard Worker break;
1620*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_GET_NEXT_FRAME_ID:
1621*38e8c45fSAndroid Build Coastguard Worker res = dispatchGetNextFrameId(args);
1622*38e8c45fSAndroid Build Coastguard Worker break;
1623*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS:
1624*38e8c45fSAndroid Build Coastguard Worker res = dispatchEnableFrameTimestamps(args);
1625*38e8c45fSAndroid Build Coastguard Worker break;
1626*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_GET_COMPOSITOR_TIMING:
1627*38e8c45fSAndroid Build Coastguard Worker res = dispatchGetCompositorTiming(args);
1628*38e8c45fSAndroid Build Coastguard Worker break;
1629*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS:
1630*38e8c45fSAndroid Build Coastguard Worker res = dispatchGetFrameTimestamps(args);
1631*38e8c45fSAndroid Build Coastguard Worker break;
1632*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT:
1633*38e8c45fSAndroid Build Coastguard Worker res = dispatchGetWideColorSupport(args);
1634*38e8c45fSAndroid Build Coastguard Worker break;
1635*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_GET_HDR_SUPPORT:
1636*38e8c45fSAndroid Build Coastguard Worker res = dispatchGetHdrSupport(args);
1637*38e8c45fSAndroid Build Coastguard Worker break;
1638*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_USAGE64:
1639*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetUsage64(args);
1640*38e8c45fSAndroid Build Coastguard Worker break;
1641*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_GET_CONSUMER_USAGE64:
1642*38e8c45fSAndroid Build Coastguard Worker res = dispatchGetConsumerUsage64(args);
1643*38e8c45fSAndroid Build Coastguard Worker break;
1644*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_AUTO_PREROTATION:
1645*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetAutoPrerotation(args);
1646*38e8c45fSAndroid Build Coastguard Worker break;
1647*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_GET_LAST_DEQUEUE_START:
1648*38e8c45fSAndroid Build Coastguard Worker res = dispatchGetLastDequeueStartTime(args);
1649*38e8c45fSAndroid Build Coastguard Worker break;
1650*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT:
1651*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetDequeueTimeout(args);
1652*38e8c45fSAndroid Build Coastguard Worker break;
1653*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_GET_LAST_DEQUEUE_DURATION:
1654*38e8c45fSAndroid Build Coastguard Worker res = dispatchGetLastDequeueDuration(args);
1655*38e8c45fSAndroid Build Coastguard Worker break;
1656*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_GET_LAST_QUEUE_DURATION:
1657*38e8c45fSAndroid Build Coastguard Worker res = dispatchGetLastQueueDuration(args);
1658*38e8c45fSAndroid Build Coastguard Worker break;
1659*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_FRAME_RATE:
1660*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetFrameRate(args);
1661*38e8c45fSAndroid Build Coastguard Worker break;
1662*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_CANCEL_INTERCEPTOR:
1663*38e8c45fSAndroid Build Coastguard Worker res = dispatchAddCancelInterceptor(args);
1664*38e8c45fSAndroid Build Coastguard Worker break;
1665*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_DEQUEUE_INTERCEPTOR:
1666*38e8c45fSAndroid Build Coastguard Worker res = dispatchAddDequeueInterceptor(args);
1667*38e8c45fSAndroid Build Coastguard Worker break;
1668*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR:
1669*38e8c45fSAndroid Build Coastguard Worker res = dispatchAddPerformInterceptor(args);
1670*38e8c45fSAndroid Build Coastguard Worker break;
1671*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR:
1672*38e8c45fSAndroid Build Coastguard Worker res = dispatchAddQueueInterceptor(args);
1673*38e8c45fSAndroid Build Coastguard Worker break;
1674*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_QUERY_INTERCEPTOR:
1675*38e8c45fSAndroid Build Coastguard Worker res = dispatchAddQueryInterceptor(args);
1676*38e8c45fSAndroid Build Coastguard Worker break;
1677*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_ALLOCATE_BUFFERS:
1678*38e8c45fSAndroid Build Coastguard Worker allocateBuffers();
1679*38e8c45fSAndroid Build Coastguard Worker res = NO_ERROR;
1680*38e8c45fSAndroid Build Coastguard Worker break;
1681*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER:
1682*38e8c45fSAndroid Build Coastguard Worker res = dispatchGetLastQueuedBuffer(args);
1683*38e8c45fSAndroid Build Coastguard Worker break;
1684*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER2:
1685*38e8c45fSAndroid Build Coastguard Worker res = dispatchGetLastQueuedBuffer2(args);
1686*38e8c45fSAndroid Build Coastguard Worker break;
1687*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO:
1688*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetFrameTimelineInfo(args);
1689*38e8c45fSAndroid Build Coastguard Worker break;
1690*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_ADDITIONAL_OPTIONS:
1691*38e8c45fSAndroid Build Coastguard Worker res = dispatchSetAdditionalOptions(args);
1692*38e8c45fSAndroid Build Coastguard Worker break;
1693*38e8c45fSAndroid Build Coastguard Worker default:
1694*38e8c45fSAndroid Build Coastguard Worker res = NAME_NOT_FOUND;
1695*38e8c45fSAndroid Build Coastguard Worker break;
1696*38e8c45fSAndroid Build Coastguard Worker }
1697*38e8c45fSAndroid Build Coastguard Worker return res;
1698*38e8c45fSAndroid Build Coastguard Worker }
1699*38e8c45fSAndroid Build Coastguard Worker
dispatchConnect(va_list args)1700*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchConnect(va_list args) {
1701*38e8c45fSAndroid Build Coastguard Worker int api = va_arg(args, int);
1702*38e8c45fSAndroid Build Coastguard Worker return connect(api);
1703*38e8c45fSAndroid Build Coastguard Worker }
1704*38e8c45fSAndroid Build Coastguard Worker
dispatchDisconnect(va_list args)1705*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchDisconnect(va_list args) {
1706*38e8c45fSAndroid Build Coastguard Worker int api = va_arg(args, int);
1707*38e8c45fSAndroid Build Coastguard Worker return disconnect(api);
1708*38e8c45fSAndroid Build Coastguard Worker }
1709*38e8c45fSAndroid Build Coastguard Worker
dispatchSetUsage(va_list args)1710*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetUsage(va_list args) {
1711*38e8c45fSAndroid Build Coastguard Worker uint64_t usage = va_arg(args, uint32_t);
1712*38e8c45fSAndroid Build Coastguard Worker return setUsage(usage);
1713*38e8c45fSAndroid Build Coastguard Worker }
1714*38e8c45fSAndroid Build Coastguard Worker
dispatchSetUsage64(va_list args)1715*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetUsage64(va_list args) {
1716*38e8c45fSAndroid Build Coastguard Worker uint64_t usage = va_arg(args, uint64_t);
1717*38e8c45fSAndroid Build Coastguard Worker return setUsage(usage);
1718*38e8c45fSAndroid Build Coastguard Worker }
1719*38e8c45fSAndroid Build Coastguard Worker
dispatchSetCrop(va_list args)1720*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetCrop(va_list args) {
1721*38e8c45fSAndroid Build Coastguard Worker android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
1722*38e8c45fSAndroid Build Coastguard Worker return setCrop(reinterpret_cast<Rect const*>(rect));
1723*38e8c45fSAndroid Build Coastguard Worker }
1724*38e8c45fSAndroid Build Coastguard Worker
dispatchSetBufferCount(va_list args)1725*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetBufferCount(va_list args) {
1726*38e8c45fSAndroid Build Coastguard Worker size_t bufferCount = va_arg(args, size_t);
1727*38e8c45fSAndroid Build Coastguard Worker return setBufferCount(static_cast<int32_t>(bufferCount));
1728*38e8c45fSAndroid Build Coastguard Worker }
1729*38e8c45fSAndroid Build Coastguard Worker
dispatchSetBuffersGeometry(va_list args)1730*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetBuffersGeometry(va_list args) {
1731*38e8c45fSAndroid Build Coastguard Worker uint32_t width = va_arg(args, uint32_t);
1732*38e8c45fSAndroid Build Coastguard Worker uint32_t height = va_arg(args, uint32_t);
1733*38e8c45fSAndroid Build Coastguard Worker PixelFormat format = va_arg(args, PixelFormat);
1734*38e8c45fSAndroid Build Coastguard Worker int err = setBuffersDimensions(width, height);
1735*38e8c45fSAndroid Build Coastguard Worker if (err != 0) {
1736*38e8c45fSAndroid Build Coastguard Worker return err;
1737*38e8c45fSAndroid Build Coastguard Worker }
1738*38e8c45fSAndroid Build Coastguard Worker return setBuffersFormat(format);
1739*38e8c45fSAndroid Build Coastguard Worker }
1740*38e8c45fSAndroid Build Coastguard Worker
dispatchSetBuffersDimensions(va_list args)1741*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetBuffersDimensions(va_list args) {
1742*38e8c45fSAndroid Build Coastguard Worker uint32_t width = va_arg(args, uint32_t);
1743*38e8c45fSAndroid Build Coastguard Worker uint32_t height = va_arg(args, uint32_t);
1744*38e8c45fSAndroid Build Coastguard Worker return setBuffersDimensions(width, height);
1745*38e8c45fSAndroid Build Coastguard Worker }
1746*38e8c45fSAndroid Build Coastguard Worker
dispatchSetBuffersUserDimensions(va_list args)1747*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetBuffersUserDimensions(va_list args) {
1748*38e8c45fSAndroid Build Coastguard Worker uint32_t width = va_arg(args, uint32_t);
1749*38e8c45fSAndroid Build Coastguard Worker uint32_t height = va_arg(args, uint32_t);
1750*38e8c45fSAndroid Build Coastguard Worker return setBuffersUserDimensions(width, height);
1751*38e8c45fSAndroid Build Coastguard Worker }
1752*38e8c45fSAndroid Build Coastguard Worker
dispatchSetBuffersFormat(va_list args)1753*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetBuffersFormat(va_list args) {
1754*38e8c45fSAndroid Build Coastguard Worker PixelFormat format = va_arg(args, PixelFormat);
1755*38e8c45fSAndroid Build Coastguard Worker return setBuffersFormat(format);
1756*38e8c45fSAndroid Build Coastguard Worker }
1757*38e8c45fSAndroid Build Coastguard Worker
dispatchSetScalingMode(va_list args)1758*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetScalingMode(va_list args) {
1759*38e8c45fSAndroid Build Coastguard Worker int mode = va_arg(args, int);
1760*38e8c45fSAndroid Build Coastguard Worker return setScalingMode(mode);
1761*38e8c45fSAndroid Build Coastguard Worker }
1762*38e8c45fSAndroid Build Coastguard Worker
dispatchSetBuffersTransform(va_list args)1763*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetBuffersTransform(va_list args) {
1764*38e8c45fSAndroid Build Coastguard Worker uint32_t transform = va_arg(args, uint32_t);
1765*38e8c45fSAndroid Build Coastguard Worker return setBuffersTransform(transform);
1766*38e8c45fSAndroid Build Coastguard Worker }
1767*38e8c45fSAndroid Build Coastguard Worker
dispatchSetBuffersStickyTransform(va_list args)1768*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetBuffersStickyTransform(va_list args) {
1769*38e8c45fSAndroid Build Coastguard Worker uint32_t transform = va_arg(args, uint32_t);
1770*38e8c45fSAndroid Build Coastguard Worker return setBuffersStickyTransform(transform);
1771*38e8c45fSAndroid Build Coastguard Worker }
1772*38e8c45fSAndroid Build Coastguard Worker
dispatchSetBuffersTimestamp(va_list args)1773*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetBuffersTimestamp(va_list args) {
1774*38e8c45fSAndroid Build Coastguard Worker int64_t timestamp = va_arg(args, int64_t);
1775*38e8c45fSAndroid Build Coastguard Worker return setBuffersTimestamp(timestamp);
1776*38e8c45fSAndroid Build Coastguard Worker }
1777*38e8c45fSAndroid Build Coastguard Worker
dispatchLock(va_list args)1778*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchLock(va_list args) {
1779*38e8c45fSAndroid Build Coastguard Worker ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
1780*38e8c45fSAndroid Build Coastguard Worker ARect* inOutDirtyBounds = va_arg(args, ARect*);
1781*38e8c45fSAndroid Build Coastguard Worker return lock(outBuffer, inOutDirtyBounds);
1782*38e8c45fSAndroid Build Coastguard Worker }
1783*38e8c45fSAndroid Build Coastguard Worker
dispatchUnlockAndPost(va_list args)1784*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) {
1785*38e8c45fSAndroid Build Coastguard Worker return unlockAndPost();
1786*38e8c45fSAndroid Build Coastguard Worker }
1787*38e8c45fSAndroid Build Coastguard Worker
dispatchSetSidebandStream(va_list args)1788*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetSidebandStream(va_list args) {
1789*38e8c45fSAndroid Build Coastguard Worker native_handle_t* sH = va_arg(args, native_handle_t*);
1790*38e8c45fSAndroid Build Coastguard Worker sp<NativeHandle> sidebandHandle = NativeHandle::create(sH, false);
1791*38e8c45fSAndroid Build Coastguard Worker setSidebandStream(sidebandHandle);
1792*38e8c45fSAndroid Build Coastguard Worker return OK;
1793*38e8c45fSAndroid Build Coastguard Worker }
1794*38e8c45fSAndroid Build Coastguard Worker
dispatchSetBuffersDataSpace(va_list args)1795*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetBuffersDataSpace(va_list args) {
1796*38e8c45fSAndroid Build Coastguard Worker Dataspace dataspace = static_cast<Dataspace>(va_arg(args, int));
1797*38e8c45fSAndroid Build Coastguard Worker return setBuffersDataSpace(dataspace);
1798*38e8c45fSAndroid Build Coastguard Worker }
1799*38e8c45fSAndroid Build Coastguard Worker
dispatchSetBuffersSmpte2086Metadata(va_list args)1800*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetBuffersSmpte2086Metadata(va_list args) {
1801*38e8c45fSAndroid Build Coastguard Worker const android_smpte2086_metadata* metadata =
1802*38e8c45fSAndroid Build Coastguard Worker va_arg(args, const android_smpte2086_metadata*);
1803*38e8c45fSAndroid Build Coastguard Worker return setBuffersSmpte2086Metadata(metadata);
1804*38e8c45fSAndroid Build Coastguard Worker }
1805*38e8c45fSAndroid Build Coastguard Worker
dispatchSetBuffersCta8613Metadata(va_list args)1806*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetBuffersCta8613Metadata(va_list args) {
1807*38e8c45fSAndroid Build Coastguard Worker const android_cta861_3_metadata* metadata =
1808*38e8c45fSAndroid Build Coastguard Worker va_arg(args, const android_cta861_3_metadata*);
1809*38e8c45fSAndroid Build Coastguard Worker return setBuffersCta8613Metadata(metadata);
1810*38e8c45fSAndroid Build Coastguard Worker }
1811*38e8c45fSAndroid Build Coastguard Worker
dispatchSetBuffersHdr10PlusMetadata(va_list args)1812*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetBuffersHdr10PlusMetadata(va_list args) {
1813*38e8c45fSAndroid Build Coastguard Worker const size_t size = va_arg(args, size_t);
1814*38e8c45fSAndroid Build Coastguard Worker const uint8_t* metadata = va_arg(args, const uint8_t*);
1815*38e8c45fSAndroid Build Coastguard Worker return setBuffersHdr10PlusMetadata(size, metadata);
1816*38e8c45fSAndroid Build Coastguard Worker }
1817*38e8c45fSAndroid Build Coastguard Worker
dispatchSetSurfaceDamage(va_list args)1818*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetSurfaceDamage(va_list args) {
1819*38e8c45fSAndroid Build Coastguard Worker android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
1820*38e8c45fSAndroid Build Coastguard Worker size_t numRects = va_arg(args, size_t);
1821*38e8c45fSAndroid Build Coastguard Worker setSurfaceDamage(rects, numRects);
1822*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1823*38e8c45fSAndroid Build Coastguard Worker }
1824*38e8c45fSAndroid Build Coastguard Worker
dispatchSetSharedBufferMode(va_list args)1825*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetSharedBufferMode(va_list args) {
1826*38e8c45fSAndroid Build Coastguard Worker bool sharedBufferMode = va_arg(args, int);
1827*38e8c45fSAndroid Build Coastguard Worker return setSharedBufferMode(sharedBufferMode);
1828*38e8c45fSAndroid Build Coastguard Worker }
1829*38e8c45fSAndroid Build Coastguard Worker
dispatchSetAutoRefresh(va_list args)1830*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetAutoRefresh(va_list args) {
1831*38e8c45fSAndroid Build Coastguard Worker bool autoRefresh = va_arg(args, int);
1832*38e8c45fSAndroid Build Coastguard Worker return setAutoRefresh(autoRefresh);
1833*38e8c45fSAndroid Build Coastguard Worker }
1834*38e8c45fSAndroid Build Coastguard Worker
dispatchGetDisplayRefreshCycleDuration(va_list args)1835*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchGetDisplayRefreshCycleDuration(va_list args) {
1836*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outRefreshDuration = va_arg(args, int64_t*);
1837*38e8c45fSAndroid Build Coastguard Worker return getDisplayRefreshCycleDuration(outRefreshDuration);
1838*38e8c45fSAndroid Build Coastguard Worker }
1839*38e8c45fSAndroid Build Coastguard Worker
dispatchGetNextFrameId(va_list args)1840*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchGetNextFrameId(va_list args) {
1841*38e8c45fSAndroid Build Coastguard Worker uint64_t* nextFrameId = va_arg(args, uint64_t*);
1842*38e8c45fSAndroid Build Coastguard Worker *nextFrameId = getNextFrameNumber();
1843*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1844*38e8c45fSAndroid Build Coastguard Worker }
1845*38e8c45fSAndroid Build Coastguard Worker
dispatchEnableFrameTimestamps(va_list args)1846*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchEnableFrameTimestamps(va_list args) {
1847*38e8c45fSAndroid Build Coastguard Worker bool enable = va_arg(args, int);
1848*38e8c45fSAndroid Build Coastguard Worker enableFrameTimestamps(enable);
1849*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1850*38e8c45fSAndroid Build Coastguard Worker }
1851*38e8c45fSAndroid Build Coastguard Worker
dispatchGetCompositorTiming(va_list args)1852*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchGetCompositorTiming(va_list args) {
1853*38e8c45fSAndroid Build Coastguard Worker nsecs_t* compositeDeadline = va_arg(args, int64_t*);
1854*38e8c45fSAndroid Build Coastguard Worker nsecs_t* compositeInterval = va_arg(args, int64_t*);
1855*38e8c45fSAndroid Build Coastguard Worker nsecs_t* compositeToPresentLatency = va_arg(args, int64_t*);
1856*38e8c45fSAndroid Build Coastguard Worker return getCompositorTiming(compositeDeadline, compositeInterval,
1857*38e8c45fSAndroid Build Coastguard Worker compositeToPresentLatency);
1858*38e8c45fSAndroid Build Coastguard Worker }
1859*38e8c45fSAndroid Build Coastguard Worker
dispatchGetFrameTimestamps(va_list args)1860*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchGetFrameTimestamps(va_list args) {
1861*38e8c45fSAndroid Build Coastguard Worker uint64_t frameId = va_arg(args, uint64_t);
1862*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outRequestedPresentTime = va_arg(args, int64_t*);
1863*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outAcquireTime = va_arg(args, int64_t*);
1864*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outLatchTime = va_arg(args, int64_t*);
1865*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outFirstRefreshStartTime = va_arg(args, int64_t*);
1866*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outLastRefreshStartTime = va_arg(args, int64_t*);
1867*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outGpuCompositionDoneTime = va_arg(args, int64_t*);
1868*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outDisplayPresentTime = va_arg(args, int64_t*);
1869*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outDequeueReadyTime = va_arg(args, int64_t*);
1870*38e8c45fSAndroid Build Coastguard Worker nsecs_t* outReleaseTime = va_arg(args, int64_t*);
1871*38e8c45fSAndroid Build Coastguard Worker return getFrameTimestamps(frameId,
1872*38e8c45fSAndroid Build Coastguard Worker outRequestedPresentTime, outAcquireTime, outLatchTime,
1873*38e8c45fSAndroid Build Coastguard Worker outFirstRefreshStartTime, outLastRefreshStartTime,
1874*38e8c45fSAndroid Build Coastguard Worker outGpuCompositionDoneTime, outDisplayPresentTime,
1875*38e8c45fSAndroid Build Coastguard Worker outDequeueReadyTime, outReleaseTime);
1876*38e8c45fSAndroid Build Coastguard Worker }
1877*38e8c45fSAndroid Build Coastguard Worker
dispatchGetWideColorSupport(va_list args)1878*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchGetWideColorSupport(va_list args) {
1879*38e8c45fSAndroid Build Coastguard Worker bool* outSupport = va_arg(args, bool*);
1880*38e8c45fSAndroid Build Coastguard Worker return getWideColorSupport(outSupport);
1881*38e8c45fSAndroid Build Coastguard Worker }
1882*38e8c45fSAndroid Build Coastguard Worker
dispatchGetHdrSupport(va_list args)1883*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchGetHdrSupport(va_list args) {
1884*38e8c45fSAndroid Build Coastguard Worker bool* outSupport = va_arg(args, bool*);
1885*38e8c45fSAndroid Build Coastguard Worker return getHdrSupport(outSupport);
1886*38e8c45fSAndroid Build Coastguard Worker }
1887*38e8c45fSAndroid Build Coastguard Worker
dispatchGetConsumerUsage64(va_list args)1888*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchGetConsumerUsage64(va_list args) {
1889*38e8c45fSAndroid Build Coastguard Worker uint64_t* usage = va_arg(args, uint64_t*);
1890*38e8c45fSAndroid Build Coastguard Worker return getConsumerUsage(usage);
1891*38e8c45fSAndroid Build Coastguard Worker }
1892*38e8c45fSAndroid Build Coastguard Worker
dispatchSetAutoPrerotation(va_list args)1893*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetAutoPrerotation(va_list args) {
1894*38e8c45fSAndroid Build Coastguard Worker bool autoPrerotation = va_arg(args, int);
1895*38e8c45fSAndroid Build Coastguard Worker return setAutoPrerotation(autoPrerotation);
1896*38e8c45fSAndroid Build Coastguard Worker }
1897*38e8c45fSAndroid Build Coastguard Worker
dispatchGetLastDequeueStartTime(va_list args)1898*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchGetLastDequeueStartTime(va_list args) {
1899*38e8c45fSAndroid Build Coastguard Worker int64_t* lastDequeueStartTime = va_arg(args, int64_t*);
1900*38e8c45fSAndroid Build Coastguard Worker *lastDequeueStartTime = mLastDequeueStartTime;
1901*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1902*38e8c45fSAndroid Build Coastguard Worker }
1903*38e8c45fSAndroid Build Coastguard Worker
dispatchSetDequeueTimeout(va_list args)1904*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetDequeueTimeout(va_list args) {
1905*38e8c45fSAndroid Build Coastguard Worker nsecs_t timeout = va_arg(args, int64_t);
1906*38e8c45fSAndroid Build Coastguard Worker return setDequeueTimeout(timeout);
1907*38e8c45fSAndroid Build Coastguard Worker }
1908*38e8c45fSAndroid Build Coastguard Worker
dispatchGetLastDequeueDuration(va_list args)1909*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchGetLastDequeueDuration(va_list args) {
1910*38e8c45fSAndroid Build Coastguard Worker int64_t* lastDequeueDuration = va_arg(args, int64_t*);
1911*38e8c45fSAndroid Build Coastguard Worker *lastDequeueDuration = mLastDequeueDuration;
1912*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1913*38e8c45fSAndroid Build Coastguard Worker }
1914*38e8c45fSAndroid Build Coastguard Worker
dispatchGetLastQueueDuration(va_list args)1915*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchGetLastQueueDuration(va_list args) {
1916*38e8c45fSAndroid Build Coastguard Worker int64_t* lastQueueDuration = va_arg(args, int64_t*);
1917*38e8c45fSAndroid Build Coastguard Worker *lastQueueDuration = mLastQueueDuration;
1918*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1919*38e8c45fSAndroid Build Coastguard Worker }
1920*38e8c45fSAndroid Build Coastguard Worker
dispatchSetFrameRate(va_list args)1921*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetFrameRate(va_list args) {
1922*38e8c45fSAndroid Build Coastguard Worker float frameRate = static_cast<float>(va_arg(args, double));
1923*38e8c45fSAndroid Build Coastguard Worker int8_t compatibility = static_cast<int8_t>(va_arg(args, int));
1924*38e8c45fSAndroid Build Coastguard Worker int8_t changeFrameRateStrategy = static_cast<int8_t>(va_arg(args, int));
1925*38e8c45fSAndroid Build Coastguard Worker return setFrameRate(frameRate, compatibility, changeFrameRateStrategy);
1926*38e8c45fSAndroid Build Coastguard Worker }
1927*38e8c45fSAndroid Build Coastguard Worker
dispatchAddCancelInterceptor(va_list args)1928*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchAddCancelInterceptor(va_list args) {
1929*38e8c45fSAndroid Build Coastguard Worker ANativeWindow_cancelBufferInterceptor interceptor =
1930*38e8c45fSAndroid Build Coastguard Worker va_arg(args, ANativeWindow_cancelBufferInterceptor);
1931*38e8c45fSAndroid Build Coastguard Worker void* data = va_arg(args, void*);
1932*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::shared_mutex> lock(mInterceptorMutex);
1933*38e8c45fSAndroid Build Coastguard Worker mCancelInterceptor = interceptor;
1934*38e8c45fSAndroid Build Coastguard Worker mCancelInterceptorData = data;
1935*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1936*38e8c45fSAndroid Build Coastguard Worker }
1937*38e8c45fSAndroid Build Coastguard Worker
dispatchAddDequeueInterceptor(va_list args)1938*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchAddDequeueInterceptor(va_list args) {
1939*38e8c45fSAndroid Build Coastguard Worker ANativeWindow_dequeueBufferInterceptor interceptor =
1940*38e8c45fSAndroid Build Coastguard Worker va_arg(args, ANativeWindow_dequeueBufferInterceptor);
1941*38e8c45fSAndroid Build Coastguard Worker void* data = va_arg(args, void*);
1942*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::shared_mutex> lock(mInterceptorMutex);
1943*38e8c45fSAndroid Build Coastguard Worker mDequeueInterceptor = interceptor;
1944*38e8c45fSAndroid Build Coastguard Worker mDequeueInterceptorData = data;
1945*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1946*38e8c45fSAndroid Build Coastguard Worker }
1947*38e8c45fSAndroid Build Coastguard Worker
dispatchAddPerformInterceptor(va_list args)1948*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchAddPerformInterceptor(va_list args) {
1949*38e8c45fSAndroid Build Coastguard Worker ANativeWindow_performInterceptor interceptor = va_arg(args, ANativeWindow_performInterceptor);
1950*38e8c45fSAndroid Build Coastguard Worker void* data = va_arg(args, void*);
1951*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::shared_mutex> lock(mInterceptorMutex);
1952*38e8c45fSAndroid Build Coastguard Worker mPerformInterceptor = interceptor;
1953*38e8c45fSAndroid Build Coastguard Worker mPerformInterceptorData = data;
1954*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1955*38e8c45fSAndroid Build Coastguard Worker }
1956*38e8c45fSAndroid Build Coastguard Worker
dispatchAddQueueInterceptor(va_list args)1957*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchAddQueueInterceptor(va_list args) {
1958*38e8c45fSAndroid Build Coastguard Worker ANativeWindow_queueBufferInterceptor interceptor =
1959*38e8c45fSAndroid Build Coastguard Worker va_arg(args, ANativeWindow_queueBufferInterceptor);
1960*38e8c45fSAndroid Build Coastguard Worker void* data = va_arg(args, void*);
1961*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::shared_mutex> lock(mInterceptorMutex);
1962*38e8c45fSAndroid Build Coastguard Worker mQueueInterceptor = interceptor;
1963*38e8c45fSAndroid Build Coastguard Worker mQueueInterceptorData = data;
1964*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1965*38e8c45fSAndroid Build Coastguard Worker }
1966*38e8c45fSAndroid Build Coastguard Worker
dispatchAddQueryInterceptor(va_list args)1967*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchAddQueryInterceptor(va_list args) {
1968*38e8c45fSAndroid Build Coastguard Worker ANativeWindow_queryInterceptor interceptor = va_arg(args, ANativeWindow_queryInterceptor);
1969*38e8c45fSAndroid Build Coastguard Worker void* data = va_arg(args, void*);
1970*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::shared_mutex> lock(mInterceptorMutex);
1971*38e8c45fSAndroid Build Coastguard Worker mQueryInterceptor = interceptor;
1972*38e8c45fSAndroid Build Coastguard Worker mQueryInterceptorData = data;
1973*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
1974*38e8c45fSAndroid Build Coastguard Worker }
1975*38e8c45fSAndroid Build Coastguard Worker
dispatchGetLastQueuedBuffer(va_list args)1976*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchGetLastQueuedBuffer(va_list args) {
1977*38e8c45fSAndroid Build Coastguard Worker AHardwareBuffer** buffer = va_arg(args, AHardwareBuffer**);
1978*38e8c45fSAndroid Build Coastguard Worker int* fence = va_arg(args, int*);
1979*38e8c45fSAndroid Build Coastguard Worker float* matrix = va_arg(args, float*);
1980*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer> graphicBuffer;
1981*38e8c45fSAndroid Build Coastguard Worker sp<Fence> spFence;
1982*38e8c45fSAndroid Build Coastguard Worker
1983*38e8c45fSAndroid Build Coastguard Worker int result = mGraphicBufferProducer->getLastQueuedBuffer(&graphicBuffer, &spFence, matrix);
1984*38e8c45fSAndroid Build Coastguard Worker
1985*38e8c45fSAndroid Build Coastguard Worker if (graphicBuffer != nullptr) {
1986*38e8c45fSAndroid Build Coastguard Worker *buffer = graphicBuffer->toAHardwareBuffer();
1987*38e8c45fSAndroid Build Coastguard Worker AHardwareBuffer_acquire(*buffer);
1988*38e8c45fSAndroid Build Coastguard Worker } else {
1989*38e8c45fSAndroid Build Coastguard Worker *buffer = nullptr;
1990*38e8c45fSAndroid Build Coastguard Worker }
1991*38e8c45fSAndroid Build Coastguard Worker
1992*38e8c45fSAndroid Build Coastguard Worker if (spFence != nullptr) {
1993*38e8c45fSAndroid Build Coastguard Worker *fence = spFence->dup();
1994*38e8c45fSAndroid Build Coastguard Worker } else {
1995*38e8c45fSAndroid Build Coastguard Worker *fence = -1;
1996*38e8c45fSAndroid Build Coastguard Worker }
1997*38e8c45fSAndroid Build Coastguard Worker return result;
1998*38e8c45fSAndroid Build Coastguard Worker }
1999*38e8c45fSAndroid Build Coastguard Worker
dispatchGetLastQueuedBuffer2(va_list args)2000*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchGetLastQueuedBuffer2(va_list args) {
2001*38e8c45fSAndroid Build Coastguard Worker AHardwareBuffer** buffer = va_arg(args, AHardwareBuffer**);
2002*38e8c45fSAndroid Build Coastguard Worker int* fence = va_arg(args, int*);
2003*38e8c45fSAndroid Build Coastguard Worker ARect* crop = va_arg(args, ARect*);
2004*38e8c45fSAndroid Build Coastguard Worker uint32_t* transform = va_arg(args, uint32_t*);
2005*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer> graphicBuffer;
2006*38e8c45fSAndroid Build Coastguard Worker sp<Fence> spFence;
2007*38e8c45fSAndroid Build Coastguard Worker
2008*38e8c45fSAndroid Build Coastguard Worker Rect r;
2009*38e8c45fSAndroid Build Coastguard Worker int result =
2010*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->getLastQueuedBuffer(&graphicBuffer, &spFence, &r, transform);
2011*38e8c45fSAndroid Build Coastguard Worker
2012*38e8c45fSAndroid Build Coastguard Worker if (graphicBuffer != nullptr) {
2013*38e8c45fSAndroid Build Coastguard Worker *buffer = graphicBuffer->toAHardwareBuffer();
2014*38e8c45fSAndroid Build Coastguard Worker AHardwareBuffer_acquire(*buffer);
2015*38e8c45fSAndroid Build Coastguard Worker
2016*38e8c45fSAndroid Build Coastguard Worker // Avoid setting crop* unless buffer is valid (matches IGBP behavior)
2017*38e8c45fSAndroid Build Coastguard Worker crop->left = r.left;
2018*38e8c45fSAndroid Build Coastguard Worker crop->top = r.top;
2019*38e8c45fSAndroid Build Coastguard Worker crop->right = r.right;
2020*38e8c45fSAndroid Build Coastguard Worker crop->bottom = r.bottom;
2021*38e8c45fSAndroid Build Coastguard Worker } else {
2022*38e8c45fSAndroid Build Coastguard Worker *buffer = nullptr;
2023*38e8c45fSAndroid Build Coastguard Worker }
2024*38e8c45fSAndroid Build Coastguard Worker
2025*38e8c45fSAndroid Build Coastguard Worker if (spFence != nullptr) {
2026*38e8c45fSAndroid Build Coastguard Worker *fence = spFence->dup();
2027*38e8c45fSAndroid Build Coastguard Worker } else {
2028*38e8c45fSAndroid Build Coastguard Worker *fence = -1;
2029*38e8c45fSAndroid Build Coastguard Worker }
2030*38e8c45fSAndroid Build Coastguard Worker return result;
2031*38e8c45fSAndroid Build Coastguard Worker }
2032*38e8c45fSAndroid Build Coastguard Worker
dispatchSetFrameTimelineInfo(va_list args)2033*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetFrameTimelineInfo(va_list args) {
2034*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2035*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::%s", __func__);
2036*38e8c45fSAndroid Build Coastguard Worker
2037*38e8c45fSAndroid Build Coastguard Worker const auto nativeWindowFtlInfo = static_cast<ANativeWindowFrameTimelineInfo>(
2038*38e8c45fSAndroid Build Coastguard Worker va_arg(args, ANativeWindowFrameTimelineInfo));
2039*38e8c45fSAndroid Build Coastguard Worker
2040*38e8c45fSAndroid Build Coastguard Worker FrameTimelineInfo ftlInfo;
2041*38e8c45fSAndroid Build Coastguard Worker ftlInfo.vsyncId = nativeWindowFtlInfo.frameTimelineVsyncId;
2042*38e8c45fSAndroid Build Coastguard Worker ftlInfo.inputEventId = nativeWindowFtlInfo.inputEventId;
2043*38e8c45fSAndroid Build Coastguard Worker ftlInfo.startTimeNanos = nativeWindowFtlInfo.startTimeNanos;
2044*38e8c45fSAndroid Build Coastguard Worker ftlInfo.useForRefreshRateSelection = nativeWindowFtlInfo.useForRefreshRateSelection;
2045*38e8c45fSAndroid Build Coastguard Worker ftlInfo.skippedFrameVsyncId = nativeWindowFtlInfo.skippedFrameVsyncId;
2046*38e8c45fSAndroid Build Coastguard Worker ftlInfo.skippedFrameStartTimeNanos = nativeWindowFtlInfo.skippedFrameStartTimeNanos;
2047*38e8c45fSAndroid Build Coastguard Worker
2048*38e8c45fSAndroid Build Coastguard Worker return setFrameTimelineInfo(nativeWindowFtlInfo.frameNumber, ftlInfo);
2049*38e8c45fSAndroid Build Coastguard Worker }
2050*38e8c45fSAndroid Build Coastguard Worker
dispatchSetAdditionalOptions(va_list args)2051*38e8c45fSAndroid Build Coastguard Worker int Surface::dispatchSetAdditionalOptions(va_list args) {
2052*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2053*38e8c45fSAndroid Build Coastguard Worker
2054*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE)
2055*38e8c45fSAndroid Build Coastguard Worker const AHardwareBufferLongOptions* opts = va_arg(args, const AHardwareBufferLongOptions*);
2056*38e8c45fSAndroid Build Coastguard Worker const size_t optsSize = va_arg(args, size_t);
2057*38e8c45fSAndroid Build Coastguard Worker std::vector<gui::AdditionalOptions> convertedOpts;
2058*38e8c45fSAndroid Build Coastguard Worker convertedOpts.reserve(optsSize);
2059*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < optsSize; i++) {
2060*38e8c45fSAndroid Build Coastguard Worker convertedOpts.emplace_back(opts[i].name, opts[i].value);
2061*38e8c45fSAndroid Build Coastguard Worker }
2062*38e8c45fSAndroid Build Coastguard Worker return setAdditionalOptions(convertedOpts);
2063*38e8c45fSAndroid Build Coastguard Worker #else
2064*38e8c45fSAndroid Build Coastguard Worker (void)args;
2065*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
2066*38e8c45fSAndroid Build Coastguard Worker #endif
2067*38e8c45fSAndroid Build Coastguard Worker }
2068*38e8c45fSAndroid Build Coastguard Worker
transformToDisplayInverse() const2069*38e8c45fSAndroid Build Coastguard Worker bool Surface::transformToDisplayInverse() const {
2070*38e8c45fSAndroid Build Coastguard Worker return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) ==
2071*38e8c45fSAndroid Build Coastguard Worker NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
2072*38e8c45fSAndroid Build Coastguard Worker }
2073*38e8c45fSAndroid Build Coastguard Worker
connect(int api)2074*38e8c45fSAndroid Build Coastguard Worker int Surface::connect(int api) {
2075*38e8c45fSAndroid Build Coastguard Worker static sp<SurfaceListener> listener = new StubSurfaceListener();
2076*38e8c45fSAndroid Build Coastguard Worker return connect(api, listener);
2077*38e8c45fSAndroid Build Coastguard Worker }
2078*38e8c45fSAndroid Build Coastguard Worker
connect(int api,const sp<SurfaceListener> & listener,bool reportBufferRemoval)2079*38e8c45fSAndroid Build Coastguard Worker int Surface::connect(int api, const sp<SurfaceListener>& listener, bool reportBufferRemoval) {
2080*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2081*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::connect");
2082*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2083*38e8c45fSAndroid Build Coastguard Worker IGraphicBufferProducer::QueueBufferOutput output;
2084*38e8c45fSAndroid Build Coastguard Worker mReportRemovedBuffers = reportBufferRemoval;
2085*38e8c45fSAndroid Build Coastguard Worker
2086*38e8c45fSAndroid Build Coastguard Worker if (listener != nullptr) {
2087*38e8c45fSAndroid Build Coastguard Worker mListenerProxy = new ProducerListenerProxy(this, listener);
2088*38e8c45fSAndroid Build Coastguard Worker }
2089*38e8c45fSAndroid Build Coastguard Worker
2090*38e8c45fSAndroid Build Coastguard Worker int err =
2091*38e8c45fSAndroid Build Coastguard Worker mGraphicBufferProducer->connect(mListenerProxy, api, mProducerControlledByApp, &output);
2092*38e8c45fSAndroid Build Coastguard Worker if (err == NO_ERROR) {
2093*38e8c45fSAndroid Build Coastguard Worker mDefaultWidth = output.width;
2094*38e8c45fSAndroid Build Coastguard Worker mDefaultHeight = output.height;
2095*38e8c45fSAndroid Build Coastguard Worker mNextFrameNumber = output.nextFrameNumber;
2096*38e8c45fSAndroid Build Coastguard Worker mMaxBufferCount = output.maxBufferCount;
2097*38e8c45fSAndroid Build Coastguard Worker
2098*38e8c45fSAndroid Build Coastguard Worker // Ignore transform hint if sticky transform is set or transform to display inverse flag is
2099*38e8c45fSAndroid Build Coastguard Worker // set. Transform hint should be ignored if the client is expected to always submit buffers
2100*38e8c45fSAndroid Build Coastguard Worker // in the same orientation.
2101*38e8c45fSAndroid Build Coastguard Worker if (mStickyTransform == 0 && !transformToDisplayInverse()) {
2102*38e8c45fSAndroid Build Coastguard Worker mTransformHint = output.transformHint;
2103*38e8c45fSAndroid Build Coastguard Worker }
2104*38e8c45fSAndroid Build Coastguard Worker
2105*38e8c45fSAndroid Build Coastguard Worker mConsumerRunningBehind = (output.numPendingBuffers >= 2);
2106*38e8c45fSAndroid Build Coastguard Worker
2107*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
2108*38e8c45fSAndroid Build Coastguard Worker if (listener && listener->needsDeathNotify()) {
2109*38e8c45fSAndroid Build Coastguard Worker mSurfaceDeathListener = sp<ProducerDeathListenerProxy>::make(listener);
2110*38e8c45fSAndroid Build Coastguard Worker IInterface::asBinder(mGraphicBufferProducer)->linkToDeath(mSurfaceDeathListener);
2111*38e8c45fSAndroid Build Coastguard Worker }
2112*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
2113*38e8c45fSAndroid Build Coastguard Worker }
2114*38e8c45fSAndroid Build Coastguard Worker if (!err && api == NATIVE_WINDOW_API_CPU) {
2115*38e8c45fSAndroid Build Coastguard Worker mConnectedToCpu = true;
2116*38e8c45fSAndroid Build Coastguard Worker // Clear the dirty region in case we're switching from a non-CPU API
2117*38e8c45fSAndroid Build Coastguard Worker mDirtyRegion.clear();
2118*38e8c45fSAndroid Build Coastguard Worker } else if (!err) {
2119*38e8c45fSAndroid Build Coastguard Worker // Initialize the dirty region for tracking surface damage
2120*38e8c45fSAndroid Build Coastguard Worker mDirtyRegion = Region::INVALID_REGION;
2121*38e8c45fSAndroid Build Coastguard Worker }
2122*38e8c45fSAndroid Build Coastguard Worker
2123*38e8c45fSAndroid Build Coastguard Worker return err;
2124*38e8c45fSAndroid Build Coastguard Worker }
2125*38e8c45fSAndroid Build Coastguard Worker
disconnect(int api,IGraphicBufferProducer::DisconnectMode mode)2126*38e8c45fSAndroid Build Coastguard Worker int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) {
2127*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2128*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::disconnect");
2129*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2130*38e8c45fSAndroid Build Coastguard Worker mRemovedBuffers.clear();
2131*38e8c45fSAndroid Build Coastguard Worker mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
2132*38e8c45fSAndroid Build Coastguard Worker mSharedBufferHasBeenQueued = false;
2133*38e8c45fSAndroid Build Coastguard Worker freeAllBuffers();
2134*38e8c45fSAndroid Build Coastguard Worker int err = mGraphicBufferProducer->disconnect(api, mode);
2135*38e8c45fSAndroid Build Coastguard Worker if (!err) {
2136*38e8c45fSAndroid Build Coastguard Worker mReqFormat = 0;
2137*38e8c45fSAndroid Build Coastguard Worker mReqWidth = 0;
2138*38e8c45fSAndroid Build Coastguard Worker mReqHeight = 0;
2139*38e8c45fSAndroid Build Coastguard Worker mReqUsage = 0;
2140*38e8c45fSAndroid Build Coastguard Worker mCrop.clear();
2141*38e8c45fSAndroid Build Coastguard Worker mDataSpace = Dataspace::UNKNOWN;
2142*38e8c45fSAndroid Build Coastguard Worker mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
2143*38e8c45fSAndroid Build Coastguard Worker mTransform = 0;
2144*38e8c45fSAndroid Build Coastguard Worker mStickyTransform = 0;
2145*38e8c45fSAndroid Build Coastguard Worker mAutoPrerotation = false;
2146*38e8c45fSAndroid Build Coastguard Worker mEnableFrameTimestamps = false;
2147*38e8c45fSAndroid Build Coastguard Worker mMaxBufferCount = NUM_BUFFER_SLOTS;
2148*38e8c45fSAndroid Build Coastguard Worker
2149*38e8c45fSAndroid Build Coastguard Worker if (api == NATIVE_WINDOW_API_CPU) {
2150*38e8c45fSAndroid Build Coastguard Worker mConnectedToCpu = false;
2151*38e8c45fSAndroid Build Coastguard Worker }
2152*38e8c45fSAndroid Build Coastguard Worker }
2153*38e8c45fSAndroid Build Coastguard Worker
2154*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
2155*38e8c45fSAndroid Build Coastguard Worker if (mSurfaceDeathListener != nullptr) {
2156*38e8c45fSAndroid Build Coastguard Worker IInterface::asBinder(mGraphicBufferProducer)->unlinkToDeath(mSurfaceDeathListener);
2157*38e8c45fSAndroid Build Coastguard Worker mSurfaceDeathListener = nullptr;
2158*38e8c45fSAndroid Build Coastguard Worker }
2159*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
2160*38e8c45fSAndroid Build Coastguard Worker
2161*38e8c45fSAndroid Build Coastguard Worker return err;
2162*38e8c45fSAndroid Build Coastguard Worker }
2163*38e8c45fSAndroid Build Coastguard Worker
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)2164*38e8c45fSAndroid Build Coastguard Worker int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
2165*38e8c45fSAndroid Build Coastguard Worker sp<Fence>* outFence) {
2166*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2167*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::detachNextBuffer");
2168*38e8c45fSAndroid Build Coastguard Worker
2169*38e8c45fSAndroid Build Coastguard Worker if (outBuffer == nullptr || outFence == nullptr) {
2170*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
2171*38e8c45fSAndroid Build Coastguard Worker }
2172*38e8c45fSAndroid Build Coastguard Worker
2173*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2174*38e8c45fSAndroid Build Coastguard Worker if (mReportRemovedBuffers) {
2175*38e8c45fSAndroid Build Coastguard Worker mRemovedBuffers.clear();
2176*38e8c45fSAndroid Build Coastguard Worker }
2177*38e8c45fSAndroid Build Coastguard Worker
2178*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer> buffer(nullptr);
2179*38e8c45fSAndroid Build Coastguard Worker sp<Fence> fence(nullptr);
2180*38e8c45fSAndroid Build Coastguard Worker status_t result = mGraphicBufferProducer->detachNextBuffer(
2181*38e8c45fSAndroid Build Coastguard Worker &buffer, &fence);
2182*38e8c45fSAndroid Build Coastguard Worker if (result != NO_ERROR) {
2183*38e8c45fSAndroid Build Coastguard Worker return result;
2184*38e8c45fSAndroid Build Coastguard Worker }
2185*38e8c45fSAndroid Build Coastguard Worker
2186*38e8c45fSAndroid Build Coastguard Worker *outBuffer = buffer;
2187*38e8c45fSAndroid Build Coastguard Worker if (fence != nullptr && fence->isValid()) {
2188*38e8c45fSAndroid Build Coastguard Worker *outFence = fence;
2189*38e8c45fSAndroid Build Coastguard Worker } else {
2190*38e8c45fSAndroid Build Coastguard Worker *outFence = Fence::NO_FENCE;
2191*38e8c45fSAndroid Build Coastguard Worker }
2192*38e8c45fSAndroid Build Coastguard Worker
2193*38e8c45fSAndroid Build Coastguard Worker for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
2194*38e8c45fSAndroid Build Coastguard Worker if (mSlots[i].buffer != nullptr &&
2195*38e8c45fSAndroid Build Coastguard Worker mSlots[i].buffer->getId() == buffer->getId()) {
2196*38e8c45fSAndroid Build Coastguard Worker if (mReportRemovedBuffers) {
2197*38e8c45fSAndroid Build Coastguard Worker mRemovedBuffers.push_back(mSlots[i].buffer);
2198*38e8c45fSAndroid Build Coastguard Worker }
2199*38e8c45fSAndroid Build Coastguard Worker mSlots[i].buffer = nullptr;
2200*38e8c45fSAndroid Build Coastguard Worker }
2201*38e8c45fSAndroid Build Coastguard Worker }
2202*38e8c45fSAndroid Build Coastguard Worker
2203*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2204*38e8c45fSAndroid Build Coastguard Worker }
2205*38e8c45fSAndroid Build Coastguard Worker
attachBuffer(ANativeWindowBuffer * buffer)2206*38e8c45fSAndroid Build Coastguard Worker int Surface::attachBuffer(ANativeWindowBuffer* buffer)
2207*38e8c45fSAndroid Build Coastguard Worker {
2208*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2209*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::attachBuffer");
2210*38e8c45fSAndroid Build Coastguard Worker
2211*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2212*38e8c45fSAndroid Build Coastguard Worker if (mReportRemovedBuffers) {
2213*38e8c45fSAndroid Build Coastguard Worker mRemovedBuffers.clear();
2214*38e8c45fSAndroid Build Coastguard Worker }
2215*38e8c45fSAndroid Build Coastguard Worker
2216*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
2217*38e8c45fSAndroid Build Coastguard Worker uint32_t priorGeneration = graphicBuffer->mGenerationNumber;
2218*38e8c45fSAndroid Build Coastguard Worker graphicBuffer->mGenerationNumber = mGenerationNumber;
2219*38e8c45fSAndroid Build Coastguard Worker int32_t attachedSlot = -1;
2220*38e8c45fSAndroid Build Coastguard Worker status_t result = mGraphicBufferProducer->attachBuffer(&attachedSlot, graphicBuffer);
2221*38e8c45fSAndroid Build Coastguard Worker if (result != NO_ERROR) {
2222*38e8c45fSAndroid Build Coastguard Worker ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result);
2223*38e8c45fSAndroid Build Coastguard Worker graphicBuffer->mGenerationNumber = priorGeneration;
2224*38e8c45fSAndroid Build Coastguard Worker return result;
2225*38e8c45fSAndroid Build Coastguard Worker }
2226*38e8c45fSAndroid Build Coastguard Worker if (mReportRemovedBuffers && (mSlots[attachedSlot].buffer != nullptr)) {
2227*38e8c45fSAndroid Build Coastguard Worker mRemovedBuffers.push_back(mSlots[attachedSlot].buffer);
2228*38e8c45fSAndroid Build Coastguard Worker }
2229*38e8c45fSAndroid Build Coastguard Worker mSlots[attachedSlot].buffer = graphicBuffer;
2230*38e8c45fSAndroid Build Coastguard Worker mDequeuedSlots.insert(attachedSlot);
2231*38e8c45fSAndroid Build Coastguard Worker
2232*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2233*38e8c45fSAndroid Build Coastguard Worker }
2234*38e8c45fSAndroid Build Coastguard Worker
setUsage(uint64_t reqUsage)2235*38e8c45fSAndroid Build Coastguard Worker int Surface::setUsage(uint64_t reqUsage)
2236*38e8c45fSAndroid Build Coastguard Worker {
2237*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setUsage");
2238*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2239*38e8c45fSAndroid Build Coastguard Worker if (reqUsage != mReqUsage) {
2240*38e8c45fSAndroid Build Coastguard Worker mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
2241*38e8c45fSAndroid Build Coastguard Worker }
2242*38e8c45fSAndroid Build Coastguard Worker mReqUsage = reqUsage;
2243*38e8c45fSAndroid Build Coastguard Worker return OK;
2244*38e8c45fSAndroid Build Coastguard Worker }
2245*38e8c45fSAndroid Build Coastguard Worker
setCrop(Rect const * rect)2246*38e8c45fSAndroid Build Coastguard Worker int Surface::setCrop(Rect const* rect)
2247*38e8c45fSAndroid Build Coastguard Worker {
2248*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2249*38e8c45fSAndroid Build Coastguard Worker
2250*38e8c45fSAndroid Build Coastguard Worker Rect realRect(Rect::EMPTY_RECT);
2251*38e8c45fSAndroid Build Coastguard Worker if (rect == nullptr || rect->isEmpty()) {
2252*38e8c45fSAndroid Build Coastguard Worker realRect.clear();
2253*38e8c45fSAndroid Build Coastguard Worker } else {
2254*38e8c45fSAndroid Build Coastguard Worker realRect = *rect;
2255*38e8c45fSAndroid Build Coastguard Worker }
2256*38e8c45fSAndroid Build Coastguard Worker
2257*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setCrop rect=[%d %d %d %d]",
2258*38e8c45fSAndroid Build Coastguard Worker realRect.left, realRect.top, realRect.right, realRect.bottom);
2259*38e8c45fSAndroid Build Coastguard Worker
2260*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2261*38e8c45fSAndroid Build Coastguard Worker mCrop = realRect;
2262*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2263*38e8c45fSAndroid Build Coastguard Worker }
2264*38e8c45fSAndroid Build Coastguard Worker
setBufferCount(int bufferCount)2265*38e8c45fSAndroid Build Coastguard Worker int Surface::setBufferCount(int bufferCount)
2266*38e8c45fSAndroid Build Coastguard Worker {
2267*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2268*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setBufferCount");
2269*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2270*38e8c45fSAndroid Build Coastguard Worker
2271*38e8c45fSAndroid Build Coastguard Worker status_t err = NO_ERROR;
2272*38e8c45fSAndroid Build Coastguard Worker if (bufferCount == 0) {
2273*38e8c45fSAndroid Build Coastguard Worker err = mGraphicBufferProducer->setMaxDequeuedBufferCount(1);
2274*38e8c45fSAndroid Build Coastguard Worker } else {
2275*38e8c45fSAndroid Build Coastguard Worker int minUndequeuedBuffers = 0;
2276*38e8c45fSAndroid Build Coastguard Worker err = mGraphicBufferProducer->query(
2277*38e8c45fSAndroid Build Coastguard Worker NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers);
2278*38e8c45fSAndroid Build Coastguard Worker if (err == NO_ERROR) {
2279*38e8c45fSAndroid Build Coastguard Worker err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
2280*38e8c45fSAndroid Build Coastguard Worker bufferCount - minUndequeuedBuffers);
2281*38e8c45fSAndroid Build Coastguard Worker }
2282*38e8c45fSAndroid Build Coastguard Worker }
2283*38e8c45fSAndroid Build Coastguard Worker
2284*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
2285*38e8c45fSAndroid Build Coastguard Worker bufferCount, strerror(-err));
2286*38e8c45fSAndroid Build Coastguard Worker
2287*38e8c45fSAndroid Build Coastguard Worker return err;
2288*38e8c45fSAndroid Build Coastguard Worker }
2289*38e8c45fSAndroid Build Coastguard Worker
setMaxDequeuedBufferCount(int maxDequeuedBuffers)2290*38e8c45fSAndroid Build Coastguard Worker int Surface::setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
2291*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2292*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setMaxDequeuedBufferCount");
2293*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2294*38e8c45fSAndroid Build Coastguard Worker
2295*38e8c45fSAndroid Build Coastguard Worker status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
2296*38e8c45fSAndroid Build Coastguard Worker maxDequeuedBuffers);
2297*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(err, "IGraphicBufferProducer::setMaxDequeuedBufferCount(%d) "
2298*38e8c45fSAndroid Build Coastguard Worker "returned %s", maxDequeuedBuffers, strerror(-err));
2299*38e8c45fSAndroid Build Coastguard Worker
2300*38e8c45fSAndroid Build Coastguard Worker return err;
2301*38e8c45fSAndroid Build Coastguard Worker }
2302*38e8c45fSAndroid Build Coastguard Worker
setAsyncMode(bool async)2303*38e8c45fSAndroid Build Coastguard Worker int Surface::setAsyncMode(bool async) {
2304*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2305*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setAsyncMode");
2306*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2307*38e8c45fSAndroid Build Coastguard Worker
2308*38e8c45fSAndroid Build Coastguard Worker status_t err = mGraphicBufferProducer->setAsyncMode(async);
2309*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(err, "IGraphicBufferProducer::setAsyncMode(%d) returned %s",
2310*38e8c45fSAndroid Build Coastguard Worker async, strerror(-err));
2311*38e8c45fSAndroid Build Coastguard Worker
2312*38e8c45fSAndroid Build Coastguard Worker return err;
2313*38e8c45fSAndroid Build Coastguard Worker }
2314*38e8c45fSAndroid Build Coastguard Worker
setSharedBufferMode(bool sharedBufferMode)2315*38e8c45fSAndroid Build Coastguard Worker int Surface::setSharedBufferMode(bool sharedBufferMode) {
2316*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2317*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setSharedBufferMode (%d)", sharedBufferMode);
2318*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2319*38e8c45fSAndroid Build Coastguard Worker
2320*38e8c45fSAndroid Build Coastguard Worker status_t err = mGraphicBufferProducer->setSharedBufferMode(
2321*38e8c45fSAndroid Build Coastguard Worker sharedBufferMode);
2322*38e8c45fSAndroid Build Coastguard Worker if (err == NO_ERROR) {
2323*38e8c45fSAndroid Build Coastguard Worker mSharedBufferMode = sharedBufferMode;
2324*38e8c45fSAndroid Build Coastguard Worker }
2325*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(err, "IGraphicBufferProducer::setSharedBufferMode(%d) returned"
2326*38e8c45fSAndroid Build Coastguard Worker "%s", sharedBufferMode, strerror(-err));
2327*38e8c45fSAndroid Build Coastguard Worker
2328*38e8c45fSAndroid Build Coastguard Worker return err;
2329*38e8c45fSAndroid Build Coastguard Worker }
2330*38e8c45fSAndroid Build Coastguard Worker
setAutoRefresh(bool autoRefresh)2331*38e8c45fSAndroid Build Coastguard Worker int Surface::setAutoRefresh(bool autoRefresh) {
2332*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2333*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setAutoRefresh (%d)", autoRefresh);
2334*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2335*38e8c45fSAndroid Build Coastguard Worker
2336*38e8c45fSAndroid Build Coastguard Worker status_t err = mGraphicBufferProducer->setAutoRefresh(autoRefresh);
2337*38e8c45fSAndroid Build Coastguard Worker if (err == NO_ERROR) {
2338*38e8c45fSAndroid Build Coastguard Worker mAutoRefresh = autoRefresh;
2339*38e8c45fSAndroid Build Coastguard Worker }
2340*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(err, "IGraphicBufferProducer::setAutoRefresh(%d) returned %s",
2341*38e8c45fSAndroid Build Coastguard Worker autoRefresh, strerror(-err));
2342*38e8c45fSAndroid Build Coastguard Worker return err;
2343*38e8c45fSAndroid Build Coastguard Worker }
2344*38e8c45fSAndroid Build Coastguard Worker
setBuffersDimensions(uint32_t width,uint32_t height)2345*38e8c45fSAndroid Build Coastguard Worker int Surface::setBuffersDimensions(uint32_t width, uint32_t height)
2346*38e8c45fSAndroid Build Coastguard Worker {
2347*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2348*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setBuffersDimensions");
2349*38e8c45fSAndroid Build Coastguard Worker
2350*38e8c45fSAndroid Build Coastguard Worker if ((width && !height) || (!width && height))
2351*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
2352*38e8c45fSAndroid Build Coastguard Worker
2353*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2354*38e8c45fSAndroid Build Coastguard Worker if (width != mReqWidth || height != mReqHeight) {
2355*38e8c45fSAndroid Build Coastguard Worker mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
2356*38e8c45fSAndroid Build Coastguard Worker }
2357*38e8c45fSAndroid Build Coastguard Worker mReqWidth = width;
2358*38e8c45fSAndroid Build Coastguard Worker mReqHeight = height;
2359*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2360*38e8c45fSAndroid Build Coastguard Worker }
2361*38e8c45fSAndroid Build Coastguard Worker
setBuffersUserDimensions(uint32_t width,uint32_t height)2362*38e8c45fSAndroid Build Coastguard Worker int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height)
2363*38e8c45fSAndroid Build Coastguard Worker {
2364*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2365*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setBuffersUserDimensions");
2366*38e8c45fSAndroid Build Coastguard Worker
2367*38e8c45fSAndroid Build Coastguard Worker if ((width && !height) || (!width && height))
2368*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
2369*38e8c45fSAndroid Build Coastguard Worker
2370*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2371*38e8c45fSAndroid Build Coastguard Worker if (width != mUserWidth || height != mUserHeight) {
2372*38e8c45fSAndroid Build Coastguard Worker mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
2373*38e8c45fSAndroid Build Coastguard Worker }
2374*38e8c45fSAndroid Build Coastguard Worker mUserWidth = width;
2375*38e8c45fSAndroid Build Coastguard Worker mUserHeight = height;
2376*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2377*38e8c45fSAndroid Build Coastguard Worker }
2378*38e8c45fSAndroid Build Coastguard Worker
setBuffersFormat(PixelFormat format)2379*38e8c45fSAndroid Build Coastguard Worker int Surface::setBuffersFormat(PixelFormat format)
2380*38e8c45fSAndroid Build Coastguard Worker {
2381*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setBuffersFormat");
2382*38e8c45fSAndroid Build Coastguard Worker
2383*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2384*38e8c45fSAndroid Build Coastguard Worker if (format != mReqFormat) {
2385*38e8c45fSAndroid Build Coastguard Worker mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
2386*38e8c45fSAndroid Build Coastguard Worker }
2387*38e8c45fSAndroid Build Coastguard Worker mReqFormat = format;
2388*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2389*38e8c45fSAndroid Build Coastguard Worker }
2390*38e8c45fSAndroid Build Coastguard Worker
setScalingMode(int mode)2391*38e8c45fSAndroid Build Coastguard Worker int Surface::setScalingMode(int mode)
2392*38e8c45fSAndroid Build Coastguard Worker {
2393*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2394*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setScalingMode(%d)", mode);
2395*38e8c45fSAndroid Build Coastguard Worker
2396*38e8c45fSAndroid Build Coastguard Worker switch (mode) {
2397*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SCALING_MODE_FREEZE:
2398*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
2399*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
2400*38e8c45fSAndroid Build Coastguard Worker case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
2401*38e8c45fSAndroid Build Coastguard Worker break;
2402*38e8c45fSAndroid Build Coastguard Worker default:
2403*38e8c45fSAndroid Build Coastguard Worker ALOGE("unknown scaling mode: %d", mode);
2404*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
2405*38e8c45fSAndroid Build Coastguard Worker }
2406*38e8c45fSAndroid Build Coastguard Worker
2407*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2408*38e8c45fSAndroid Build Coastguard Worker mScalingMode = mode;
2409*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2410*38e8c45fSAndroid Build Coastguard Worker }
2411*38e8c45fSAndroid Build Coastguard Worker
setBuffersTransform(uint32_t transform)2412*38e8c45fSAndroid Build Coastguard Worker int Surface::setBuffersTransform(uint32_t transform)
2413*38e8c45fSAndroid Build Coastguard Worker {
2414*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2415*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setBuffersTransform");
2416*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2417*38e8c45fSAndroid Build Coastguard Worker // Ensure NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY is sticky. If the client sets the flag, do not
2418*38e8c45fSAndroid Build Coastguard Worker // override it until the surface is disconnected. This is a temporary workaround for camera
2419*38e8c45fSAndroid Build Coastguard Worker // until they switch to using Buffer State Layers. Currently if client sets the buffer transform
2420*38e8c45fSAndroid Build Coastguard Worker // it may be overriden by the buffer producer when the producer sets the buffer transform.
2421*38e8c45fSAndroid Build Coastguard Worker if (transformToDisplayInverse()) {
2422*38e8c45fSAndroid Build Coastguard Worker transform |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
2423*38e8c45fSAndroid Build Coastguard Worker }
2424*38e8c45fSAndroid Build Coastguard Worker mTransform = transform;
2425*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2426*38e8c45fSAndroid Build Coastguard Worker }
2427*38e8c45fSAndroid Build Coastguard Worker
setBuffersStickyTransform(uint32_t transform)2428*38e8c45fSAndroid Build Coastguard Worker int Surface::setBuffersStickyTransform(uint32_t transform)
2429*38e8c45fSAndroid Build Coastguard Worker {
2430*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2431*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setBuffersStickyTransform");
2432*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2433*38e8c45fSAndroid Build Coastguard Worker mStickyTransform = transform;
2434*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2435*38e8c45fSAndroid Build Coastguard Worker }
2436*38e8c45fSAndroid Build Coastguard Worker
setBuffersTimestamp(int64_t timestamp)2437*38e8c45fSAndroid Build Coastguard Worker int Surface::setBuffersTimestamp(int64_t timestamp)
2438*38e8c45fSAndroid Build Coastguard Worker {
2439*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setBuffersTimestamp");
2440*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2441*38e8c45fSAndroid Build Coastguard Worker mTimestamp = timestamp;
2442*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2443*38e8c45fSAndroid Build Coastguard Worker }
2444*38e8c45fSAndroid Build Coastguard Worker
setBuffersDataSpace(Dataspace dataSpace)2445*38e8c45fSAndroid Build Coastguard Worker int Surface::setBuffersDataSpace(Dataspace dataSpace)
2446*38e8c45fSAndroid Build Coastguard Worker {
2447*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setBuffersDataSpace");
2448*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2449*38e8c45fSAndroid Build Coastguard Worker mDataSpace = dataSpace;
2450*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2451*38e8c45fSAndroid Build Coastguard Worker }
2452*38e8c45fSAndroid Build Coastguard Worker
setBuffersSmpte2086Metadata(const android_smpte2086_metadata * metadata)2453*38e8c45fSAndroid Build Coastguard Worker int Surface::setBuffersSmpte2086Metadata(const android_smpte2086_metadata* metadata) {
2454*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setBuffersSmpte2086Metadata");
2455*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2456*38e8c45fSAndroid Build Coastguard Worker mHdrMetadataIsSet |= HdrMetadata::SMPTE2086;
2457*38e8c45fSAndroid Build Coastguard Worker if (metadata) {
2458*38e8c45fSAndroid Build Coastguard Worker mHdrMetadata.smpte2086 = *metadata;
2459*38e8c45fSAndroid Build Coastguard Worker mHdrMetadata.validTypes |= HdrMetadata::SMPTE2086;
2460*38e8c45fSAndroid Build Coastguard Worker } else {
2461*38e8c45fSAndroid Build Coastguard Worker mHdrMetadata.validTypes &= ~HdrMetadata::SMPTE2086;
2462*38e8c45fSAndroid Build Coastguard Worker }
2463*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2464*38e8c45fSAndroid Build Coastguard Worker }
2465*38e8c45fSAndroid Build Coastguard Worker
setBuffersCta8613Metadata(const android_cta861_3_metadata * metadata)2466*38e8c45fSAndroid Build Coastguard Worker int Surface::setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata) {
2467*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setBuffersCta8613Metadata");
2468*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2469*38e8c45fSAndroid Build Coastguard Worker mHdrMetadataIsSet |= HdrMetadata::CTA861_3;
2470*38e8c45fSAndroid Build Coastguard Worker if (metadata) {
2471*38e8c45fSAndroid Build Coastguard Worker mHdrMetadata.cta8613 = *metadata;
2472*38e8c45fSAndroid Build Coastguard Worker mHdrMetadata.validTypes |= HdrMetadata::CTA861_3;
2473*38e8c45fSAndroid Build Coastguard Worker } else {
2474*38e8c45fSAndroid Build Coastguard Worker mHdrMetadata.validTypes &= ~HdrMetadata::CTA861_3;
2475*38e8c45fSAndroid Build Coastguard Worker }
2476*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2477*38e8c45fSAndroid Build Coastguard Worker }
2478*38e8c45fSAndroid Build Coastguard Worker
setBuffersHdr10PlusMetadata(const size_t size,const uint8_t * metadata)2479*38e8c45fSAndroid Build Coastguard Worker int Surface::setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata) {
2480*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setBuffersBlobMetadata");
2481*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2482*38e8c45fSAndroid Build Coastguard Worker mHdrMetadataIsSet |= HdrMetadata::HDR10PLUS;
2483*38e8c45fSAndroid Build Coastguard Worker if (size > 0) {
2484*38e8c45fSAndroid Build Coastguard Worker mHdrMetadata.hdr10plus.assign(metadata, metadata + size);
2485*38e8c45fSAndroid Build Coastguard Worker mHdrMetadata.validTypes |= HdrMetadata::HDR10PLUS;
2486*38e8c45fSAndroid Build Coastguard Worker } else {
2487*38e8c45fSAndroid Build Coastguard Worker mHdrMetadata.validTypes &= ~HdrMetadata::HDR10PLUS;
2488*38e8c45fSAndroid Build Coastguard Worker mHdrMetadata.hdr10plus.clear();
2489*38e8c45fSAndroid Build Coastguard Worker }
2490*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2491*38e8c45fSAndroid Build Coastguard Worker }
2492*38e8c45fSAndroid Build Coastguard Worker
getBuffersDataSpace()2493*38e8c45fSAndroid Build Coastguard Worker Dataspace Surface::getBuffersDataSpace() {
2494*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::getBuffersDataSpace");
2495*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2496*38e8c45fSAndroid Build Coastguard Worker return mDataSpace;
2497*38e8c45fSAndroid Build Coastguard Worker }
2498*38e8c45fSAndroid Build Coastguard Worker
freeAllBuffers()2499*38e8c45fSAndroid Build Coastguard Worker void Surface::freeAllBuffers() {
2500*38e8c45fSAndroid Build Coastguard Worker if (!mDequeuedSlots.empty()) {
2501*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: %zu buffers were freed while being dequeued!",
2502*38e8c45fSAndroid Build Coastguard Worker __FUNCTION__, mDequeuedSlots.size());
2503*38e8c45fSAndroid Build Coastguard Worker }
2504*38e8c45fSAndroid Build Coastguard Worker for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
2505*38e8c45fSAndroid Build Coastguard Worker mSlots[i].buffer = nullptr;
2506*38e8c45fSAndroid Build Coastguard Worker }
2507*38e8c45fSAndroid Build Coastguard Worker }
2508*38e8c45fSAndroid Build Coastguard Worker
getAndFlushBuffersFromSlots(const std::vector<int32_t> & slots,std::vector<sp<GraphicBuffer>> * outBuffers)2509*38e8c45fSAndroid Build Coastguard Worker status_t Surface::getAndFlushBuffersFromSlots(const std::vector<int32_t>& slots,
2510*38e8c45fSAndroid Build Coastguard Worker std::vector<sp<GraphicBuffer>>* outBuffers) {
2511*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::getAndFlushBuffersFromSlots");
2512*38e8c45fSAndroid Build Coastguard Worker for (int32_t i : slots) {
2513*38e8c45fSAndroid Build Coastguard Worker if (i < 0 || i >= NUM_BUFFER_SLOTS) {
2514*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: Invalid slotIndex: %d", __FUNCTION__, i);
2515*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
2516*38e8c45fSAndroid Build Coastguard Worker }
2517*38e8c45fSAndroid Build Coastguard Worker }
2518*38e8c45fSAndroid Build Coastguard Worker
2519*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2520*38e8c45fSAndroid Build Coastguard Worker for (int32_t i : slots) {
2521*38e8c45fSAndroid Build Coastguard Worker if (mSlots[i].buffer == nullptr) {
2522*38e8c45fSAndroid Build Coastguard Worker ALOGW("%s: Discarded slot %d doesn't contain buffer!", __FUNCTION__, i);
2523*38e8c45fSAndroid Build Coastguard Worker continue;
2524*38e8c45fSAndroid Build Coastguard Worker }
2525*38e8c45fSAndroid Build Coastguard Worker // Don't flush currently dequeued buffers
2526*38e8c45fSAndroid Build Coastguard Worker if (mDequeuedSlots.count(i) > 0) {
2527*38e8c45fSAndroid Build Coastguard Worker continue;
2528*38e8c45fSAndroid Build Coastguard Worker }
2529*38e8c45fSAndroid Build Coastguard Worker outBuffers->push_back(mSlots[i].buffer);
2530*38e8c45fSAndroid Build Coastguard Worker mSlots[i].buffer = nullptr;
2531*38e8c45fSAndroid Build Coastguard Worker }
2532*38e8c45fSAndroid Build Coastguard Worker return OK;
2533*38e8c45fSAndroid Build Coastguard Worker }
2534*38e8c45fSAndroid Build Coastguard Worker
setSurfaceDamage(android_native_rect_t * rects,size_t numRects)2535*38e8c45fSAndroid Build Coastguard Worker void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) {
2536*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2537*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setSurfaceDamage");
2538*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2539*38e8c45fSAndroid Build Coastguard Worker
2540*38e8c45fSAndroid Build Coastguard Worker if (mConnectedToCpu || numRects == 0) {
2541*38e8c45fSAndroid Build Coastguard Worker mDirtyRegion = Region::INVALID_REGION;
2542*38e8c45fSAndroid Build Coastguard Worker return;
2543*38e8c45fSAndroid Build Coastguard Worker }
2544*38e8c45fSAndroid Build Coastguard Worker
2545*38e8c45fSAndroid Build Coastguard Worker mDirtyRegion.clear();
2546*38e8c45fSAndroid Build Coastguard Worker for (size_t r = 0; r < numRects; ++r) {
2547*38e8c45fSAndroid Build Coastguard Worker // We intentionally flip top and bottom here, since because they're
2548*38e8c45fSAndroid Build Coastguard Worker // specified with a bottom-left origin, top > bottom, which fails
2549*38e8c45fSAndroid Build Coastguard Worker // validation in the Region class. We will fix this up when we flip to a
2550*38e8c45fSAndroid Build Coastguard Worker // top-left origin in queueBuffer.
2551*38e8c45fSAndroid Build Coastguard Worker Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top);
2552*38e8c45fSAndroid Build Coastguard Worker mDirtyRegion.orSelf(rect);
2553*38e8c45fSAndroid Build Coastguard Worker }
2554*38e8c45fSAndroid Build Coastguard Worker }
2555*38e8c45fSAndroid Build Coastguard Worker
2556*38e8c45fSAndroid Build Coastguard Worker // ----------------------------------------------------------------------
2557*38e8c45fSAndroid Build Coastguard Worker // the lock/unlock APIs must be used from the same thread
2558*38e8c45fSAndroid Build Coastguard Worker
copyBlt(const sp<GraphicBuffer> & dst,const sp<GraphicBuffer> & src,const Region & reg,int * dstFenceFd)2559*38e8c45fSAndroid Build Coastguard Worker static status_t copyBlt(
2560*38e8c45fSAndroid Build Coastguard Worker const sp<GraphicBuffer>& dst,
2561*38e8c45fSAndroid Build Coastguard Worker const sp<GraphicBuffer>& src,
2562*38e8c45fSAndroid Build Coastguard Worker const Region& reg,
2563*38e8c45fSAndroid Build Coastguard Worker int *dstFenceFd)
2564*38e8c45fSAndroid Build Coastguard Worker {
2565*38e8c45fSAndroid Build Coastguard Worker if (dst->getId() == src->getId())
2566*38e8c45fSAndroid Build Coastguard Worker return OK;
2567*38e8c45fSAndroid Build Coastguard Worker
2568*38e8c45fSAndroid Build Coastguard Worker // src and dst with, height and format must be identical. no verification
2569*38e8c45fSAndroid Build Coastguard Worker // is done here.
2570*38e8c45fSAndroid Build Coastguard Worker status_t err;
2571*38e8c45fSAndroid Build Coastguard Worker uint8_t* src_bits = nullptr;
2572*38e8c45fSAndroid Build Coastguard Worker err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(),
2573*38e8c45fSAndroid Build Coastguard Worker reinterpret_cast<void**>(&src_bits));
2574*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
2575*38e8c45fSAndroid Build Coastguard Worker
2576*38e8c45fSAndroid Build Coastguard Worker uint8_t* dst_bits = nullptr;
2577*38e8c45fSAndroid Build Coastguard Worker err = dst->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(),
2578*38e8c45fSAndroid Build Coastguard Worker reinterpret_cast<void**>(&dst_bits), *dstFenceFd);
2579*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
2580*38e8c45fSAndroid Build Coastguard Worker *dstFenceFd = -1;
2581*38e8c45fSAndroid Build Coastguard Worker
2582*38e8c45fSAndroid Build Coastguard Worker Region::const_iterator head(reg.begin());
2583*38e8c45fSAndroid Build Coastguard Worker Region::const_iterator tail(reg.end());
2584*38e8c45fSAndroid Build Coastguard Worker if (head != tail && src_bits && dst_bits) {
2585*38e8c45fSAndroid Build Coastguard Worker const size_t bpp = bytesPerPixel(src->format);
2586*38e8c45fSAndroid Build Coastguard Worker const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp;
2587*38e8c45fSAndroid Build Coastguard Worker const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp;
2588*38e8c45fSAndroid Build Coastguard Worker
2589*38e8c45fSAndroid Build Coastguard Worker while (head != tail) {
2590*38e8c45fSAndroid Build Coastguard Worker const Rect& r(*head++);
2591*38e8c45fSAndroid Build Coastguard Worker int32_t h = r.height();
2592*38e8c45fSAndroid Build Coastguard Worker if (h <= 0) continue;
2593*38e8c45fSAndroid Build Coastguard Worker size_t size = static_cast<uint32_t>(r.width()) * bpp;
2594*38e8c45fSAndroid Build Coastguard Worker uint8_t const * s = src_bits +
2595*38e8c45fSAndroid Build Coastguard Worker static_cast<uint32_t>(r.left + src->stride * r.top) * bpp;
2596*38e8c45fSAndroid Build Coastguard Worker uint8_t * d = dst_bits +
2597*38e8c45fSAndroid Build Coastguard Worker static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp;
2598*38e8c45fSAndroid Build Coastguard Worker if (dbpr==sbpr && size==sbpr) {
2599*38e8c45fSAndroid Build Coastguard Worker size *= static_cast<size_t>(h);
2600*38e8c45fSAndroid Build Coastguard Worker h = 1;
2601*38e8c45fSAndroid Build Coastguard Worker }
2602*38e8c45fSAndroid Build Coastguard Worker do {
2603*38e8c45fSAndroid Build Coastguard Worker memcpy(d, s, size);
2604*38e8c45fSAndroid Build Coastguard Worker d += dbpr;
2605*38e8c45fSAndroid Build Coastguard Worker s += sbpr;
2606*38e8c45fSAndroid Build Coastguard Worker } while (--h > 0);
2607*38e8c45fSAndroid Build Coastguard Worker }
2608*38e8c45fSAndroid Build Coastguard Worker }
2609*38e8c45fSAndroid Build Coastguard Worker
2610*38e8c45fSAndroid Build Coastguard Worker if (src_bits)
2611*38e8c45fSAndroid Build Coastguard Worker src->unlock();
2612*38e8c45fSAndroid Build Coastguard Worker
2613*38e8c45fSAndroid Build Coastguard Worker if (dst_bits)
2614*38e8c45fSAndroid Build Coastguard Worker dst->unlockAsync(dstFenceFd);
2615*38e8c45fSAndroid Build Coastguard Worker
2616*38e8c45fSAndroid Build Coastguard Worker return err;
2617*38e8c45fSAndroid Build Coastguard Worker }
2618*38e8c45fSAndroid Build Coastguard Worker
2619*38e8c45fSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
2620*38e8c45fSAndroid Build Coastguard Worker
lock(ANativeWindow_Buffer * outBuffer,ARect * inOutDirtyBounds)2621*38e8c45fSAndroid Build Coastguard Worker status_t Surface::lock(
2622*38e8c45fSAndroid Build Coastguard Worker ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
2623*38e8c45fSAndroid Build Coastguard Worker {
2624*38e8c45fSAndroid Build Coastguard Worker if (mLockedBuffer != nullptr) {
2625*38e8c45fSAndroid Build Coastguard Worker ALOGE("Surface::lock failed, already locked");
2626*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
2627*38e8c45fSAndroid Build Coastguard Worker }
2628*38e8c45fSAndroid Build Coastguard Worker
2629*38e8c45fSAndroid Build Coastguard Worker if (!mConnectedToCpu) {
2630*38e8c45fSAndroid Build Coastguard Worker int err = Surface::connect(NATIVE_WINDOW_API_CPU);
2631*38e8c45fSAndroid Build Coastguard Worker if (err) {
2632*38e8c45fSAndroid Build Coastguard Worker return err;
2633*38e8c45fSAndroid Build Coastguard Worker }
2634*38e8c45fSAndroid Build Coastguard Worker // we're intending to do software rendering from this point
2635*38e8c45fSAndroid Build Coastguard Worker setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
2636*38e8c45fSAndroid Build Coastguard Worker }
2637*38e8c45fSAndroid Build Coastguard Worker
2638*38e8c45fSAndroid Build Coastguard Worker ANativeWindowBuffer* out;
2639*38e8c45fSAndroid Build Coastguard Worker int fenceFd = -1;
2640*38e8c45fSAndroid Build Coastguard Worker status_t err = dequeueBuffer(&out, &fenceFd);
2641*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
2642*38e8c45fSAndroid Build Coastguard Worker if (err == NO_ERROR) {
2643*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
2644*38e8c45fSAndroid Build Coastguard Worker const Rect bounds(backBuffer->width, backBuffer->height);
2645*38e8c45fSAndroid Build Coastguard Worker
2646*38e8c45fSAndroid Build Coastguard Worker Region newDirtyRegion;
2647*38e8c45fSAndroid Build Coastguard Worker if (inOutDirtyBounds) {
2648*38e8c45fSAndroid Build Coastguard Worker newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
2649*38e8c45fSAndroid Build Coastguard Worker newDirtyRegion.andSelf(bounds);
2650*38e8c45fSAndroid Build Coastguard Worker } else {
2651*38e8c45fSAndroid Build Coastguard Worker newDirtyRegion.set(bounds);
2652*38e8c45fSAndroid Build Coastguard Worker }
2653*38e8c45fSAndroid Build Coastguard Worker
2654*38e8c45fSAndroid Build Coastguard Worker // figure out if we can copy the frontbuffer back
2655*38e8c45fSAndroid Build Coastguard Worker const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
2656*38e8c45fSAndroid Build Coastguard Worker const bool canCopyBack = (frontBuffer != nullptr &&
2657*38e8c45fSAndroid Build Coastguard Worker backBuffer->width == frontBuffer->width &&
2658*38e8c45fSAndroid Build Coastguard Worker backBuffer->height == frontBuffer->height &&
2659*38e8c45fSAndroid Build Coastguard Worker backBuffer->format == frontBuffer->format);
2660*38e8c45fSAndroid Build Coastguard Worker
2661*38e8c45fSAndroid Build Coastguard Worker if (canCopyBack) {
2662*38e8c45fSAndroid Build Coastguard Worker // copy the area that is invalid and not repainted this round
2663*38e8c45fSAndroid Build Coastguard Worker const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
2664*38e8c45fSAndroid Build Coastguard Worker if (!copyback.isEmpty()) {
2665*38e8c45fSAndroid Build Coastguard Worker copyBlt(backBuffer, frontBuffer, copyback, &fenceFd);
2666*38e8c45fSAndroid Build Coastguard Worker }
2667*38e8c45fSAndroid Build Coastguard Worker } else {
2668*38e8c45fSAndroid Build Coastguard Worker // if we can't copy-back anything, modify the user's dirty
2669*38e8c45fSAndroid Build Coastguard Worker // region to make sure they redraw the whole buffer
2670*38e8c45fSAndroid Build Coastguard Worker newDirtyRegion.set(bounds);
2671*38e8c45fSAndroid Build Coastguard Worker mDirtyRegion.clear();
2672*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2673*38e8c45fSAndroid Build Coastguard Worker for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
2674*38e8c45fSAndroid Build Coastguard Worker mSlots[i].dirtyRegion.clear();
2675*38e8c45fSAndroid Build Coastguard Worker }
2676*38e8c45fSAndroid Build Coastguard Worker }
2677*38e8c45fSAndroid Build Coastguard Worker
2678*38e8c45fSAndroid Build Coastguard Worker
2679*38e8c45fSAndroid Build Coastguard Worker { // scope for the lock
2680*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2681*38e8c45fSAndroid Build Coastguard Worker int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
2682*38e8c45fSAndroid Build Coastguard Worker if (backBufferSlot >= 0) {
2683*38e8c45fSAndroid Build Coastguard Worker Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
2684*38e8c45fSAndroid Build Coastguard Worker mDirtyRegion.subtract(dirtyRegion);
2685*38e8c45fSAndroid Build Coastguard Worker dirtyRegion = newDirtyRegion;
2686*38e8c45fSAndroid Build Coastguard Worker }
2687*38e8c45fSAndroid Build Coastguard Worker }
2688*38e8c45fSAndroid Build Coastguard Worker
2689*38e8c45fSAndroid Build Coastguard Worker mDirtyRegion.orSelf(newDirtyRegion);
2690*38e8c45fSAndroid Build Coastguard Worker if (inOutDirtyBounds) {
2691*38e8c45fSAndroid Build Coastguard Worker *inOutDirtyBounds = newDirtyRegion.getBounds();
2692*38e8c45fSAndroid Build Coastguard Worker }
2693*38e8c45fSAndroid Build Coastguard Worker
2694*38e8c45fSAndroid Build Coastguard Worker void* vaddr;
2695*38e8c45fSAndroid Build Coastguard Worker status_t res = backBuffer->lockAsync(
2696*38e8c45fSAndroid Build Coastguard Worker GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2697*38e8c45fSAndroid Build Coastguard Worker newDirtyRegion.bounds(), &vaddr, fenceFd);
2698*38e8c45fSAndroid Build Coastguard Worker
2699*38e8c45fSAndroid Build Coastguard Worker ALOGW_IF(res, "failed locking buffer (handle = %p)",
2700*38e8c45fSAndroid Build Coastguard Worker backBuffer->handle);
2701*38e8c45fSAndroid Build Coastguard Worker
2702*38e8c45fSAndroid Build Coastguard Worker if (res != 0) {
2703*38e8c45fSAndroid Build Coastguard Worker err = INVALID_OPERATION;
2704*38e8c45fSAndroid Build Coastguard Worker } else {
2705*38e8c45fSAndroid Build Coastguard Worker mLockedBuffer = backBuffer;
2706*38e8c45fSAndroid Build Coastguard Worker outBuffer->width = backBuffer->width;
2707*38e8c45fSAndroid Build Coastguard Worker outBuffer->height = backBuffer->height;
2708*38e8c45fSAndroid Build Coastguard Worker outBuffer->stride = backBuffer->stride;
2709*38e8c45fSAndroid Build Coastguard Worker outBuffer->format = backBuffer->format;
2710*38e8c45fSAndroid Build Coastguard Worker outBuffer->bits = vaddr;
2711*38e8c45fSAndroid Build Coastguard Worker }
2712*38e8c45fSAndroid Build Coastguard Worker }
2713*38e8c45fSAndroid Build Coastguard Worker return err;
2714*38e8c45fSAndroid Build Coastguard Worker }
2715*38e8c45fSAndroid Build Coastguard Worker
unlockAndPost()2716*38e8c45fSAndroid Build Coastguard Worker status_t Surface::unlockAndPost()
2717*38e8c45fSAndroid Build Coastguard Worker {
2718*38e8c45fSAndroid Build Coastguard Worker if (mLockedBuffer == nullptr) {
2719*38e8c45fSAndroid Build Coastguard Worker ALOGE("Surface::unlockAndPost failed, no locked buffer");
2720*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
2721*38e8c45fSAndroid Build Coastguard Worker }
2722*38e8c45fSAndroid Build Coastguard Worker
2723*38e8c45fSAndroid Build Coastguard Worker int fd = -1;
2724*38e8c45fSAndroid Build Coastguard Worker status_t err = mLockedBuffer->unlockAsync(&fd);
2725*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
2726*38e8c45fSAndroid Build Coastguard Worker
2727*38e8c45fSAndroid Build Coastguard Worker err = queueBuffer(mLockedBuffer.get(), fd);
2728*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
2729*38e8c45fSAndroid Build Coastguard Worker mLockedBuffer->handle, strerror(-err));
2730*38e8c45fSAndroid Build Coastguard Worker
2731*38e8c45fSAndroid Build Coastguard Worker mPostedBuffer = mLockedBuffer;
2732*38e8c45fSAndroid Build Coastguard Worker mLockedBuffer = nullptr;
2733*38e8c45fSAndroid Build Coastguard Worker return err;
2734*38e8c45fSAndroid Build Coastguard Worker }
2735*38e8c45fSAndroid Build Coastguard Worker
waitForNextFrame(uint64_t lastFrame,nsecs_t timeout)2736*38e8c45fSAndroid Build Coastguard Worker bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) {
2737*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2738*38e8c45fSAndroid Build Coastguard Worker if (mLastFrameNumber > lastFrame) {
2739*38e8c45fSAndroid Build Coastguard Worker return true;
2740*38e8c45fSAndroid Build Coastguard Worker }
2741*38e8c45fSAndroid Build Coastguard Worker return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK;
2742*38e8c45fSAndroid Build Coastguard Worker }
2743*38e8c45fSAndroid Build Coastguard Worker
getUniqueId(uint64_t * outId) const2744*38e8c45fSAndroid Build Coastguard Worker status_t Surface::getUniqueId(uint64_t* outId) const {
2745*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2746*38e8c45fSAndroid Build Coastguard Worker return mGraphicBufferProducer->getUniqueId(outId);
2747*38e8c45fSAndroid Build Coastguard Worker }
2748*38e8c45fSAndroid Build Coastguard Worker
getConsumerUsage(uint64_t * outUsage) const2749*38e8c45fSAndroid Build Coastguard Worker int Surface::getConsumerUsage(uint64_t* outUsage) const {
2750*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2751*38e8c45fSAndroid Build Coastguard Worker return mGraphicBufferProducer->getConsumerUsage(outUsage);
2752*38e8c45fSAndroid Build Coastguard Worker }
2753*38e8c45fSAndroid Build Coastguard Worker
getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>> * out)2754*38e8c45fSAndroid Build Coastguard Worker status_t Surface::getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out) {
2755*38e8c45fSAndroid Build Coastguard Worker if (out == nullptr) {
2756*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: out must not be null!", __FUNCTION__);
2757*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
2758*38e8c45fSAndroid Build Coastguard Worker }
2759*38e8c45fSAndroid Build Coastguard Worker
2760*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2761*38e8c45fSAndroid Build Coastguard Worker *out = mRemovedBuffers;
2762*38e8c45fSAndroid Build Coastguard Worker mRemovedBuffers.clear();
2763*38e8c45fSAndroid Build Coastguard Worker return OK;
2764*38e8c45fSAndroid Build Coastguard Worker }
2765*38e8c45fSAndroid Build Coastguard Worker
attachAndQueueBufferWithDataspace(Surface * surface,sp<GraphicBuffer> buffer,Dataspace dataspace)2766*38e8c45fSAndroid Build Coastguard Worker status_t Surface::attachAndQueueBufferWithDataspace(Surface* surface, sp<GraphicBuffer> buffer,
2767*38e8c45fSAndroid Build Coastguard Worker Dataspace dataspace) {
2768*38e8c45fSAndroid Build Coastguard Worker if (buffer == nullptr) {
2769*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
2770*38e8c45fSAndroid Build Coastguard Worker }
2771*38e8c45fSAndroid Build Coastguard Worker int err = static_cast<ANativeWindow*>(surface)->perform(surface, NATIVE_WINDOW_API_CONNECT,
2772*38e8c45fSAndroid Build Coastguard Worker NATIVE_WINDOW_API_CPU);
2773*38e8c45fSAndroid Build Coastguard Worker if (err != OK) {
2774*38e8c45fSAndroid Build Coastguard Worker return err;
2775*38e8c45fSAndroid Build Coastguard Worker }
2776*38e8c45fSAndroid Build Coastguard Worker ui::Dataspace tmpDataspace = surface->getBuffersDataSpace();
2777*38e8c45fSAndroid Build Coastguard Worker err = surface->setBuffersDataSpace(dataspace);
2778*38e8c45fSAndroid Build Coastguard Worker if (err != OK) {
2779*38e8c45fSAndroid Build Coastguard Worker return err;
2780*38e8c45fSAndroid Build Coastguard Worker }
2781*38e8c45fSAndroid Build Coastguard Worker err = surface->attachBuffer(buffer->getNativeBuffer());
2782*38e8c45fSAndroid Build Coastguard Worker if (err != OK) {
2783*38e8c45fSAndroid Build Coastguard Worker return err;
2784*38e8c45fSAndroid Build Coastguard Worker }
2785*38e8c45fSAndroid Build Coastguard Worker err = static_cast<ANativeWindow*>(surface)->queueBuffer(surface, buffer->getNativeBuffer(), -1);
2786*38e8c45fSAndroid Build Coastguard Worker if (err != OK) {
2787*38e8c45fSAndroid Build Coastguard Worker return err;
2788*38e8c45fSAndroid Build Coastguard Worker }
2789*38e8c45fSAndroid Build Coastguard Worker err = surface->setBuffersDataSpace(tmpDataspace);
2790*38e8c45fSAndroid Build Coastguard Worker if (err != OK) {
2791*38e8c45fSAndroid Build Coastguard Worker return err;
2792*38e8c45fSAndroid Build Coastguard Worker }
2793*38e8c45fSAndroid Build Coastguard Worker err = surface->disconnect(NATIVE_WINDOW_API_CPU);
2794*38e8c45fSAndroid Build Coastguard Worker return err;
2795*38e8c45fSAndroid Build Coastguard Worker }
2796*38e8c45fSAndroid Build Coastguard Worker
setAutoPrerotation(bool autoPrerotation)2797*38e8c45fSAndroid Build Coastguard Worker int Surface::setAutoPrerotation(bool autoPrerotation) {
2798*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2799*38e8c45fSAndroid Build Coastguard Worker ALOGV("Surface::setAutoPrerotation (%d)", autoPrerotation);
2800*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2801*38e8c45fSAndroid Build Coastguard Worker
2802*38e8c45fSAndroid Build Coastguard Worker if (mAutoPrerotation == autoPrerotation) {
2803*38e8c45fSAndroid Build Coastguard Worker return OK;
2804*38e8c45fSAndroid Build Coastguard Worker }
2805*38e8c45fSAndroid Build Coastguard Worker
2806*38e8c45fSAndroid Build Coastguard Worker status_t err = mGraphicBufferProducer->setAutoPrerotation(autoPrerotation);
2807*38e8c45fSAndroid Build Coastguard Worker if (err == NO_ERROR) {
2808*38e8c45fSAndroid Build Coastguard Worker mAutoPrerotation = autoPrerotation;
2809*38e8c45fSAndroid Build Coastguard Worker }
2810*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(err, "IGraphicBufferProducer::setAutoPrerotation(%d) returned %s", autoPrerotation,
2811*38e8c45fSAndroid Build Coastguard Worker strerror(-err));
2812*38e8c45fSAndroid Build Coastguard Worker return err;
2813*38e8c45fSAndroid Build Coastguard Worker }
2814*38e8c45fSAndroid Build Coastguard Worker
onBuffersDiscarded(const std::vector<int32_t> & slots)2815*38e8c45fSAndroid Build Coastguard Worker void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vector<int32_t>& slots) {
2816*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
2817*38e8c45fSAndroid Build Coastguard Worker sp<Surface> parent = mParent.promote();
2818*38e8c45fSAndroid Build Coastguard Worker if (parent == nullptr) {
2819*38e8c45fSAndroid Build Coastguard Worker return;
2820*38e8c45fSAndroid Build Coastguard Worker }
2821*38e8c45fSAndroid Build Coastguard Worker
2822*38e8c45fSAndroid Build Coastguard Worker std::vector<sp<GraphicBuffer>> discardedBufs;
2823*38e8c45fSAndroid Build Coastguard Worker status_t res = parent->getAndFlushBuffersFromSlots(slots, &discardedBufs);
2824*38e8c45fSAndroid Build Coastguard Worker if (res != OK) {
2825*38e8c45fSAndroid Build Coastguard Worker ALOGE("%s: Failed to get buffers from slots: %s(%d)", __FUNCTION__,
2826*38e8c45fSAndroid Build Coastguard Worker strerror(-res), res);
2827*38e8c45fSAndroid Build Coastguard Worker return;
2828*38e8c45fSAndroid Build Coastguard Worker }
2829*38e8c45fSAndroid Build Coastguard Worker
2830*38e8c45fSAndroid Build Coastguard Worker mSurfaceListener->onBuffersDiscarded(discardedBufs);
2831*38e8c45fSAndroid Build Coastguard Worker }
2832*38e8c45fSAndroid Build Coastguard Worker
setFrameRate(float frameRate,int8_t compatibility,int8_t changeFrameRateStrategy)2833*38e8c45fSAndroid Build Coastguard Worker status_t Surface::setFrameRate(float frameRate, int8_t compatibility,
2834*38e8c45fSAndroid Build Coastguard Worker int8_t changeFrameRateStrategy) {
2835*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_SETFRAMERATE)
2836*38e8c45fSAndroid Build Coastguard Worker if (flags::bq_setframerate()) {
2837*38e8c45fSAndroid Build Coastguard Worker status_t err = mGraphicBufferProducer->setFrameRate(frameRate, compatibility,
2838*38e8c45fSAndroid Build Coastguard Worker changeFrameRateStrategy);
2839*38e8c45fSAndroid Build Coastguard Worker ALOGE_IF(err, "IGraphicBufferProducer::setFrameRate(%.2f) returned %s", frameRate,
2840*38e8c45fSAndroid Build Coastguard Worker strerror(-err));
2841*38e8c45fSAndroid Build Coastguard Worker return err;
2842*38e8c45fSAndroid Build Coastguard Worker }
2843*38e8c45fSAndroid Build Coastguard Worker #else
2844*38e8c45fSAndroid Build Coastguard Worker static_cast<void>(frameRate);
2845*38e8c45fSAndroid Build Coastguard Worker static_cast<void>(compatibility);
2846*38e8c45fSAndroid Build Coastguard Worker static_cast<void>(changeFrameRateStrategy);
2847*38e8c45fSAndroid Build Coastguard Worker #endif
2848*38e8c45fSAndroid Build Coastguard Worker
2849*38e8c45fSAndroid Build Coastguard Worker ALOGI("Surface::setFrameRate is deprecated, setFrameRate hint is dropped as destination is not "
2850*38e8c45fSAndroid Build Coastguard Worker "SurfaceFlinger");
2851*38e8c45fSAndroid Build Coastguard Worker // ISurfaceComposer no longer supports setFrameRate, we will return NO_ERROR when the api is
2852*38e8c45fSAndroid Build Coastguard Worker // called to avoid apps crashing, as BAD_VALUE can generate fatal exception in apps.
2853*38e8c45fSAndroid Build Coastguard Worker return NO_ERROR;
2854*38e8c45fSAndroid Build Coastguard Worker }
2855*38e8c45fSAndroid Build Coastguard Worker
setFrameTimelineInfo(uint64_t,const FrameTimelineInfo &)2856*38e8c45fSAndroid Build Coastguard Worker status_t Surface::setFrameTimelineInfo(uint64_t /*frameNumber*/,
2857*38e8c45fSAndroid Build Coastguard Worker const FrameTimelineInfo& /*frameTimelineInfo*/) {
2858*38e8c45fSAndroid Build Coastguard Worker // ISurfaceComposer no longer supports setFrameTimelineInfo
2859*38e8c45fSAndroid Build Coastguard Worker return BAD_VALUE;
2860*38e8c45fSAndroid Build Coastguard Worker }
2861*38e8c45fSAndroid Build Coastguard Worker
2862*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE)
setAdditionalOptions(const std::vector<gui::AdditionalOptions> & options)2863*38e8c45fSAndroid Build Coastguard Worker status_t Surface::setAdditionalOptions(const std::vector<gui::AdditionalOptions>& options) {
2864*38e8c45fSAndroid Build Coastguard Worker if (!GraphicBufferAllocator::get().supportsAdditionalOptions()) {
2865*38e8c45fSAndroid Build Coastguard Worker return INVALID_OPERATION;
2866*38e8c45fSAndroid Build Coastguard Worker }
2867*38e8c45fSAndroid Build Coastguard Worker
2868*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2869*38e8c45fSAndroid Build Coastguard Worker return mGraphicBufferProducer->setAdditionalOptions(options);
2870*38e8c45fSAndroid Build Coastguard Worker }
2871*38e8c45fSAndroid Build Coastguard Worker #endif
2872*38e8c45fSAndroid Build Coastguard Worker
getSurfaceControlHandle() const2873*38e8c45fSAndroid Build Coastguard Worker sp<IBinder> Surface::getSurfaceControlHandle() const {
2874*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2875*38e8c45fSAndroid Build Coastguard Worker return mSurfaceControlHandle;
2876*38e8c45fSAndroid Build Coastguard Worker }
2877*38e8c45fSAndroid Build Coastguard Worker
destroy()2878*38e8c45fSAndroid Build Coastguard Worker void Surface::destroy() {
2879*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mMutex);
2880*38e8c45fSAndroid Build Coastguard Worker mSurfaceControlHandle = nullptr;
2881*38e8c45fSAndroid Build Coastguard Worker }
2882*38e8c45fSAndroid Build Coastguard Worker
getDebugName()2883*38e8c45fSAndroid Build Coastguard Worker const char* Surface::getDebugName() {
2884*38e8c45fSAndroid Build Coastguard Worker std::unique_lock lock{mNameMutex};
2885*38e8c45fSAndroid Build Coastguard Worker if (mName.empty()) {
2886*38e8c45fSAndroid Build Coastguard Worker mName = getConsumerName();
2887*38e8c45fSAndroid Build Coastguard Worker }
2888*38e8c45fSAndroid Build Coastguard Worker return mName.c_str();
2889*38e8c45fSAndroid Build Coastguard Worker }
2890*38e8c45fSAndroid Build Coastguard Worker
2891*38e8c45fSAndroid Build Coastguard Worker }; // namespace android
2892