blob: 429e837fba9596206cd20304f75f96a03fc9d543 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
Mathias Agopiane3c697f2013-02-14 17:11:02 -08002 * Copyright (C) 2010 The Android Open Source Project
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Surface"
Mathias Agopiane3c697f2013-02-14 17:11:02 -080018#define ATRACE_TAG ATRACE_TAG_GRAPHICS
19//#define LOG_NDEBUG 0
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080020
Mathias Agopian05debe12017-02-08 17:04:18 -080021#include <gui/Surface.h>
Mathias Agopianb0e76f42012-03-23 14:15:44 -070022
Mathias Agopian05debe12017-02-08 17:04:18 -080023#include <android/native_window.h>
Mathias Agopiane3c697f2013-02-14 17:11:02 -080024
Mathias Agopian9cce3252010-02-09 17:46:37 -080025#include <utils/Log.h>
Mathias Agopiane3c697f2013-02-14 17:11:02 -080026#include <utils/Trace.h>
Rachad7cb0d392014-07-29 17:53:53 -070027#include <utils/NativeHandle.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080028
Ian Elliott62c48c92017-01-20 13:13:20 -070029#include <ui/DisplayStatInfo.h>
Courtney Goeltzenleuchterc5b97c52017-02-26 14:47:13 -070030#include <ui/Fence.h>
31#include <ui/HdrCapabilities.h>
32#include <ui/Region.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070033
Mathias Agopian2b5dd402017-02-07 17:36:19 -080034#include <gui/BufferItem.h>
Dan Stozaf0eaf252014-03-21 13:05:51 -070035#include <gui/IProducerListener.h>
Mathias Agopiane3c697f2013-02-14 17:11:02 -080036
Mathias Agopian2b5dd402017-02-07 17:36:19 -080037#include <gui/ISurfaceComposer.h>
Mathias Agopiane3c697f2013-02-14 17:11:02 -080038#include <private/gui/ComposerService.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070039
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080040namespace android {
41
Mathias Agopiane3c697f2013-02-14 17:11:02 -080042Surface::Surface(
Mathias Agopian595264f2013-07-16 22:56:09 -070043 const sp<IGraphicBufferProducer>& bufferProducer,
44 bool controlledByApp)
Dan Stoza812ed062015-06-02 15:45:22 -070045 : mGraphicBufferProducer(bufferProducer),
Pablo Ceballos60d69222015-08-07 14:47:20 -070046 mCrop(Rect::EMPTY_RECT),
Pablo Ceballosff95aab2016-01-13 17:09:58 -080047 mGenerationNumber(0),
Pablo Ceballos3559fbf2016-03-17 15:50:23 -070048 mSharedBufferMode(false),
Pablo Ceballosff95aab2016-01-13 17:09:58 -080049 mAutoRefresh(false),
50 mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
Pablo Ceballosbc8c1922016-07-01 14:15:41 -070051 mSharedBufferHasBeenQueued(false),
Brian Anderson3da8d272016-07-28 16:20:47 -070052 mEnableFrameTimestamps(false),
53 mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>())
Mathias Agopian62185b72009-04-16 16:19:50 -070054{
Mathias Agopiane3c697f2013-02-14 17:11:02 -080055 // Initialize the ANativeWindow function pointers.
56 ANativeWindow::setSwapInterval = hook_setSwapInterval;
57 ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
58 ANativeWindow::cancelBuffer = hook_cancelBuffer;
59 ANativeWindow::queueBuffer = hook_queueBuffer;
60 ANativeWindow::query = hook_query;
61 ANativeWindow::perform = hook_perform;
62
63 ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
64 ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
65 ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
66 ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
67
68 const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
69 const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
70
71 mReqWidth = 0;
72 mReqHeight = 0;
73 mReqFormat = 0;
74 mReqUsage = 0;
75 mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -080076 mDataSpace = HAL_DATASPACE_UNKNOWN;
Mathias Agopiane3c697f2013-02-14 17:11:02 -080077 mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
78 mTransform = 0;
Ruben Brunk1681d952014-06-27 15:51:55 -070079 mStickyTransform = 0;
Mathias Agopiane3c697f2013-02-14 17:11:02 -080080 mDefaultWidth = 0;
81 mDefaultHeight = 0;
82 mUserWidth = 0;
83 mUserHeight = 0;
84 mTransformHint = 0;
85 mConsumerRunningBehind = false;
86 mConnectedToCpu = false;
Eino-Ville Talvala7895e902013-08-21 11:53:37 -070087 mProducerControlledByApp = controlledByApp;
Mathias Agopian7cdd7862013-07-18 22:10:56 -070088 mSwapIntervalZero = false;
Mathias Agopian62185b72009-04-16 16:19:50 -070089}
90
Mathias Agopian35ffa6a2013-03-12 18:45:09 -070091Surface::~Surface() {
92 if (mConnectedToCpu) {
93 Surface::disconnect(NATIVE_WINDOW_API_CPU);
94 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -080095}
96
Brian Anderson3da8d272016-07-28 16:20:47 -070097sp<ISurfaceComposer> Surface::composerService() const {
98 return ComposerService::getComposerService();
99}
100
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800101nsecs_t Surface::now() const {
102 return systemTime();
103}
104
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800105sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const {
106 return mGraphicBufferProducer;
107}
108
Wonsik Kim0ee14ca2014-03-17 17:46:53 +0900109void Surface::setSidebandStream(const sp<NativeHandle>& stream) {
110 mGraphicBufferProducer->setSidebandStream(stream);
111}
112
Dan Stoza29a3e902014-06-20 13:13:57 -0700113void Surface::allocateBuffers() {
114 uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth;
115 uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight;
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700116 mGraphicBufferProducer->allocateBuffers(reqWidth, reqHeight,
117 mReqFormat, mReqUsage);
Dan Stoza29a3e902014-06-20 13:13:57 -0700118}
119
Dan Stoza812ed062015-06-02 15:45:22 -0700120status_t Surface::setGenerationNumber(uint32_t generation) {
121 status_t result = mGraphicBufferProducer->setGenerationNumber(generation);
122 if (result == NO_ERROR) {
123 mGenerationNumber = generation;
124 }
125 return result;
126}
127
Dan Stoza7dde5992015-05-22 09:51:44 -0700128uint64_t Surface::getNextFrameNumber() const {
Pablo Ceballosbc8c1922016-07-01 14:15:41 -0700129 Mutex::Autolock lock(mMutex);
130 return mNextFrameNumber;
Dan Stoza7dde5992015-05-22 09:51:44 -0700131}
132
Dan Stozac6f30bd2015-06-08 09:32:50 -0700133String8 Surface::getConsumerName() const {
134 return mGraphicBufferProducer->getConsumerName();
135}
136
Dan Stoza127fc632015-06-30 13:43:32 -0700137status_t Surface::setDequeueTimeout(nsecs_t timeout) {
138 return mGraphicBufferProducer->setDequeueTimeout(timeout);
139}
140
Dan Stoza50101d02016-04-07 16:53:23 -0700141status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
John Reck1a61da52016-04-28 13:18:15 -0700142 sp<Fence>* outFence, float outTransformMatrix[16]) {
143 return mGraphicBufferProducer->getLastQueuedBuffer(outBuffer, outFence,
144 outTransformMatrix);
Dan Stoza50101d02016-04-07 16:53:23 -0700145}
146
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800147status_t Surface::getDisplayRefreshCycleDuration(nsecs_t* outRefreshDuration) {
148 ATRACE_CALL();
149
150 DisplayStatInfo stats;
151 status_t err = composerService()->getDisplayStats(NULL, &stats);
152
153 *outRefreshDuration = stats.vsyncPeriod;
154
155 return NO_ERROR;
156}
157
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700158void Surface::enableFrameTimestamps(bool enable) {
159 Mutex::Autolock lock(mMutex);
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800160 // If going from disabled to enabled, get the initial values for
161 // compositor and display timing.
162 if (!mEnableFrameTimestamps && enable) {
163 FrameEventHistoryDelta delta;
164 mGraphicBufferProducer->getFrameTimestamps(&delta);
165 mFrameEventHistory->applyDelta(delta);
166 }
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700167 mEnableFrameTimestamps = enable;
168}
169
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800170status_t Surface::getCompositorTiming(
171 nsecs_t* compositeDeadline, nsecs_t* compositeInterval,
172 nsecs_t* compositeToPresentLatency) {
173 Mutex::Autolock lock(mMutex);
174 if (!mEnableFrameTimestamps) {
175 return INVALID_OPERATION;
176 }
177
178 if (compositeDeadline != nullptr) {
179 *compositeDeadline =
180 mFrameEventHistory->getNextCompositeDeadline(now());
181 }
182 if (compositeInterval != nullptr) {
183 *compositeInterval = mFrameEventHistory->getCompositeInterval();
184 }
185 if (compositeToPresentLatency != nullptr) {
186 *compositeToPresentLatency =
187 mFrameEventHistory->getCompositeToPresentLatency();
188 }
189 return NO_ERROR;
190}
191
Brian Anderson50143b32016-09-30 14:01:24 -0700192static bool checkConsumerForUpdates(
193 const FrameEvents* e, const uint64_t lastFrameNumber,
Brian Andersonf7fd56a2016-09-02 10:10:04 -0700194 const nsecs_t* outLatchTime,
195 const nsecs_t* outFirstRefreshStartTime,
196 const nsecs_t* outLastRefreshStartTime,
Brian Andersonb04c6f02016-10-21 12:57:46 -0700197 const nsecs_t* outGpuCompositionDoneTime,
Brian Anderson50143b32016-09-30 14:01:24 -0700198 const nsecs_t* outDisplayPresentTime,
Brian Andersonf7fd56a2016-09-02 10:10:04 -0700199 const nsecs_t* outDequeueReadyTime,
Brian Anderson50143b32016-09-30 14:01:24 -0700200 const nsecs_t* outReleaseTime) {
Brian Andersonf7fd56a2016-09-02 10:10:04 -0700201 bool checkForLatch = (outLatchTime != nullptr) && !e->hasLatchInfo();
202 bool checkForFirstRefreshStart = (outFirstRefreshStartTime != nullptr) &&
Brian Anderson50143b32016-09-30 14:01:24 -0700203 !e->hasFirstRefreshStartInfo();
Brian Andersonb04c6f02016-10-21 12:57:46 -0700204 bool checkForGpuCompositionDone = (outGpuCompositionDoneTime != nullptr) &&
Brian Anderson50143b32016-09-30 14:01:24 -0700205 !e->hasGpuCompositionDoneInfo();
206 bool checkForDisplayPresent = (outDisplayPresentTime != nullptr) &&
207 !e->hasDisplayPresentInfo();
208
Brian Anderson4e606e32017-03-16 15:34:57 -0700209 // LastRefreshStart, DequeueReady, and Release are never
Brian Andersonf7fd56a2016-09-02 10:10:04 -0700210 // available for the last frame.
211 bool checkForLastRefreshStart = (outLastRefreshStartTime != nullptr) &&
212 !e->hasLastRefreshStartInfo() &&
213 (e->frameNumber != lastFrameNumber);
Brian Andersonf7fd56a2016-09-02 10:10:04 -0700214 bool checkForDequeueReady = (outDequeueReadyTime != nullptr) &&
215 !e->hasDequeueReadyInfo() && (e->frameNumber != lastFrameNumber);
Brian Anderson50143b32016-09-30 14:01:24 -0700216 bool checkForRelease = (outReleaseTime != nullptr) &&
217 !e->hasReleaseInfo() && (e->frameNumber != lastFrameNumber);
218
219 // RequestedPresent and Acquire info are always available producer-side.
Brian Andersonf7fd56a2016-09-02 10:10:04 -0700220 return checkForLatch || checkForFirstRefreshStart ||
Brian Andersonb04c6f02016-10-21 12:57:46 -0700221 checkForLastRefreshStart || checkForGpuCompositionDone ||
Brian Anderson4e606e32017-03-16 15:34:57 -0700222 checkForDisplayPresent || checkForDequeueReady || checkForRelease;
Brian Anderson50143b32016-09-30 14:01:24 -0700223}
224
Brian Anderson3d4039d2016-09-23 16:31:30 -0700225static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) {
226 if (dst != nullptr) {
Brian Andersoned816e62016-10-26 16:12:21 -0700227 *dst = FrameEvents::isValidTimestamp(src) ? src : 0;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700228 }
229}
230
231static void getFrameTimestampFence(nsecs_t *dst, const std::shared_ptr<FenceTime>& src) {
232 if (dst != nullptr) {
233 nsecs_t signalTime = src->getSignalTime();
234 *dst = Fence::isValidTimestamp(signalTime) ? signalTime : 0;
235 }
236}
237
Brian Anderson069b3652016-07-22 10:32:47 -0700238status_t Surface::getFrameTimestamps(uint64_t frameNumber,
Brian Andersondbd0ea82016-07-22 09:38:59 -0700239 nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime,
Brian Andersonf7fd56a2016-09-02 10:10:04 -0700240 nsecs_t* outLatchTime, nsecs_t* outFirstRefreshStartTime,
Brian Andersonb04c6f02016-10-21 12:57:46 -0700241 nsecs_t* outLastRefreshStartTime, nsecs_t* outGpuCompositionDoneTime,
Brian Anderson4e606e32017-03-16 15:34:57 -0700242 nsecs_t* outDisplayPresentTime, nsecs_t* outDequeueReadyTime,
243 nsecs_t* outReleaseTime) {
Pablo Ceballosce796e72016-02-04 19:10:51 -0800244 ATRACE_CALL();
245
Brian Anderson3890c392016-07-25 12:48:08 -0700246 Mutex::Autolock lock(mMutex);
Brian Anderson069b3652016-07-22 10:32:47 -0700247
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700248 if (!mEnableFrameTimestamps) {
249 return INVALID_OPERATION;
250 }
251
Brian Anderson3da8d272016-07-28 16:20:47 -0700252 FrameEvents* events = mFrameEventHistory->getFrame(frameNumber);
Brian Anderson50143b32016-09-30 14:01:24 -0700253 if (events == nullptr) {
254 // If the entry isn't available in the producer, it's definitely not
255 // available in the consumer.
256 return NAME_NOT_FOUND;
Brian Anderson3890c392016-07-25 12:48:08 -0700257 }
258
Brian Anderson50143b32016-09-30 14:01:24 -0700259 // Update our cache of events if the requested events are not available.
260 if (checkConsumerForUpdates(events, mLastFrameNumber,
Brian Andersonf7fd56a2016-09-02 10:10:04 -0700261 outLatchTime, outFirstRefreshStartTime, outLastRefreshStartTime,
Brian Andersonb04c6f02016-10-21 12:57:46 -0700262 outGpuCompositionDoneTime, outDisplayPresentTime,
Brian Anderson4e606e32017-03-16 15:34:57 -0700263 outDequeueReadyTime, outReleaseTime)) {
Brian Anderson50143b32016-09-30 14:01:24 -0700264 FrameEventHistoryDelta delta;
265 mGraphicBufferProducer->getFrameTimestamps(&delta);
Brian Anderson3da8d272016-07-28 16:20:47 -0700266 mFrameEventHistory->applyDelta(delta);
267 events = mFrameEventHistory->getFrame(frameNumber);
Brian Anderson50143b32016-09-30 14:01:24 -0700268 }
269
Brian Anderson3890c392016-07-25 12:48:08 -0700270 if (events == nullptr) {
Brian Anderson50143b32016-09-30 14:01:24 -0700271 // The entry was available before the update, but was overwritten
272 // after the update. Make sure not to send the wrong frame's data.
Brian Anderson069b3652016-07-22 10:32:47 -0700273 return NAME_NOT_FOUND;
Pablo Ceballosce796e72016-02-04 19:10:51 -0800274 }
Brian Anderson069b3652016-07-22 10:32:47 -0700275
Brian Anderson3d4039d2016-09-23 16:31:30 -0700276 getFrameTimestamp(outRequestedPresentTime, events->requestedPresentTime);
Brian Andersonf7fd56a2016-09-02 10:10:04 -0700277 getFrameTimestamp(outLatchTime, events->latchTime);
278 getFrameTimestamp(outFirstRefreshStartTime, events->firstRefreshStartTime);
279 getFrameTimestamp(outLastRefreshStartTime, events->lastRefreshStartTime);
280 getFrameTimestamp(outDequeueReadyTime, events->dequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700281
Brian Anderson3d4039d2016-09-23 16:31:30 -0700282 getFrameTimestampFence(outAcquireTime, events->acquireFence);
283 getFrameTimestampFence(
Brian Andersonb04c6f02016-10-21 12:57:46 -0700284 outGpuCompositionDoneTime, events->gpuCompositionDoneFence);
Brian Anderson3d4039d2016-09-23 16:31:30 -0700285 getFrameTimestampFence(
286 outDisplayPresentTime, events->displayPresentFence);
Brian Anderson3d4039d2016-09-23 16:31:30 -0700287 getFrameTimestampFence(outReleaseTime, events->releaseFence);
Brian Anderson069b3652016-07-22 10:32:47 -0700288
289 return NO_ERROR;
Pablo Ceballosce796e72016-02-04 19:10:51 -0800290}
291
Courtney Goeltzenleuchter1eb1b272017-02-02 16:51:06 -0700292status_t Surface::getWideColorSupport(bool* supported) {
293 ATRACE_CALL();
294
295 sp<IBinder> display(
296 composerService()->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
297 Vector<android_color_mode_t> colorModes;
298 status_t err =
299 composerService()->getDisplayColorModes(display, &colorModes);
300
301 if (err)
302 return err;
303
304 *supported = false;
305 for (android_color_mode_t colorMode : colorModes) {
306 switch (colorMode) {
307 case HAL_COLOR_MODE_DISPLAY_P3:
308 case HAL_COLOR_MODE_ADOBE_RGB:
309 case HAL_COLOR_MODE_DCI_P3:
310 *supported = true;
311 break;
312 default:
313 break;
314 }
315 }
316
317 return NO_ERROR;
318}
319
Courtney Goeltzenleuchterc5b97c52017-02-26 14:47:13 -0700320status_t Surface::getHdrSupport(bool* supported) {
321 ATRACE_CALL();
322
323 sp<IBinder> display(
324 composerService()->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
325 HdrCapabilities hdrCapabilities;
326 status_t err =
327 composerService()->getHdrCapabilities(display, &hdrCapabilities);
328
329 if (err)
330 return err;
331
332 *supported = !hdrCapabilities.getSupportedHdrTypes().empty();
333
334 return NO_ERROR;
335}
336
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800337int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
338 Surface* c = getSelf(window);
339 return c->setSwapInterval(interval);
340}
341
342int Surface::hook_dequeueBuffer(ANativeWindow* window,
343 ANativeWindowBuffer** buffer, int* fenceFd) {
344 Surface* c = getSelf(window);
345 return c->dequeueBuffer(buffer, fenceFd);
346}
347
348int Surface::hook_cancelBuffer(ANativeWindow* window,
349 ANativeWindowBuffer* buffer, int fenceFd) {
350 Surface* c = getSelf(window);
351 return c->cancelBuffer(buffer, fenceFd);
352}
353
354int Surface::hook_queueBuffer(ANativeWindow* window,
355 ANativeWindowBuffer* buffer, int fenceFd) {
356 Surface* c = getSelf(window);
357 return c->queueBuffer(buffer, fenceFd);
358}
359
360int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
361 ANativeWindowBuffer** buffer) {
362 Surface* c = getSelf(window);
363 ANativeWindowBuffer* buf;
364 int fenceFd = -1;
365 int result = c->dequeueBuffer(&buf, &fenceFd);
Mike Stroyan87709c92016-06-03 12:43:26 -0600366 if (result != OK) {
367 return result;
368 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800369 sp<Fence> fence(new Fence(fenceFd));
Mathias Agopianea74d3b2013-05-16 18:03:22 -0700370 int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800371 if (waitResult != OK) {
372 ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d",
373 waitResult);
374 c->cancelBuffer(buf, -1);
375 return waitResult;
Mathias Agopian62185b72009-04-16 16:19:50 -0700376 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800377 *buffer = buf;
378 return result;
Mathias Agopian62185b72009-04-16 16:19:50 -0700379}
380
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800381int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
382 ANativeWindowBuffer* buffer) {
383 Surface* c = getSelf(window);
384 return c->cancelBuffer(buffer, -1);
Mathias Agopian62185b72009-04-16 16:19:50 -0700385}
386
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800387int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
388 ANativeWindowBuffer* buffer) {
389 Surface* c = getSelf(window);
390 return c->lockBuffer_DEPRECATED(buffer);
Mathias Agopian62185b72009-04-16 16:19:50 -0700391}
392
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800393int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
394 ANativeWindowBuffer* buffer) {
395 Surface* c = getSelf(window);
396 return c->queueBuffer(buffer, -1);
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700397}
Mathias Agopian62185b72009-04-16 16:19:50 -0700398
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800399int Surface::hook_query(const ANativeWindow* window,
400 int what, int* value) {
401 const Surface* c = getSelf(window);
402 return c->query(what, value);
403}
404
405int Surface::hook_perform(ANativeWindow* window, int operation, ...) {
406 va_list args;
407 va_start(args, operation);
408 Surface* c = getSelf(window);
Haixia Shid89c2bb2015-09-14 11:02:18 -0700409 int result = c->perform(operation, args);
410 va_end(args);
411 return result;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800412}
413
414int Surface::setSwapInterval(int interval) {
415 ATRACE_CALL();
416 // EGL specification states:
417 // interval is silently clamped to minimum and maximum implementation
418 // dependent values before being stored.
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800419
420 if (interval < minSwapInterval)
421 interval = minSwapInterval;
422
423 if (interval > maxSwapInterval)
424 interval = maxSwapInterval;
425
Mathias Agopian7cdd7862013-07-18 22:10:56 -0700426 mSwapIntervalZero = (interval == 0);
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700427 mGraphicBufferProducer->setAsyncMode(mSwapIntervalZero);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800428
Mathias Agopian7cdd7862013-07-18 22:10:56 -0700429 return NO_ERROR;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800430}
431
Mathias Agopianba93b3f2013-08-01 15:48:40 -0700432int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800433 ATRACE_CALL();
434 ALOGV("Surface::dequeueBuffer");
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800435
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800436 uint32_t reqWidth;
437 uint32_t reqHeight;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800438 PixelFormat reqFormat;
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800439 uint32_t reqUsage;
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700440 bool enableFrameTimestamps;
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800441
442 {
443 Mutex::Autolock lock(mMutex);
444
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800445 reqWidth = mReqWidth ? mReqWidth : mUserWidth;
446 reqHeight = mReqHeight ? mReqHeight : mUserHeight;
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800447
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800448 reqFormat = mReqFormat;
449 reqUsage = mReqUsage;
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800450
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700451 enableFrameTimestamps = mEnableFrameTimestamps;
452
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700453 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot !=
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800454 BufferItem::INVALID_BUFFER_SLOT) {
455 sp<GraphicBuffer>& gbuf(mSlots[mSharedBufferSlot].buffer);
456 if (gbuf != NULL) {
457 *buffer = gbuf.get();
458 *fenceFd = -1;
459 return OK;
460 }
461 }
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800462 } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer
463
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800464 int buf = -1;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800465 sp<Fence> fence;
Dan Stoza70ccba52016-07-01 14:00:40 -0700466 nsecs_t now = systemTime();
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700467
468 FrameEventHistoryDelta frameTimestamps;
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700469 status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
Brian Anderson50143b32016-09-30 14:01:24 -0700470 reqWidth, reqHeight, reqFormat, reqUsage,
471 enableFrameTimestamps ? &frameTimestamps : nullptr);
Dan Stoza70ccba52016-07-01 14:00:40 -0700472 mLastDequeueDuration = systemTime() - now;
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800473
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800474 if (result < 0) {
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700475 ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer"
476 "(%d, %d, %d, %d) failed: %d", reqWidth, reqHeight, reqFormat,
477 reqUsage, result);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800478 return result;
Mathias Agopian62185b72009-04-16 16:19:50 -0700479 }
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800480
481 Mutex::Autolock lock(mMutex);
482
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800483 sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
Mathias Agopianba93b3f2013-08-01 15:48:40 -0700484
485 // this should never happen
486 ALOGE_IF(fence == NULL, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);
487
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800488 if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
489 freeAllBuffers();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700490 }
Ted Bonkenburgbd050ab2011-07-15 15:10:10 -0700491
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700492 if (enableFrameTimestamps) {
Brian Anderson3da8d272016-07-28 16:20:47 -0700493 mFrameEventHistory->applyDelta(frameTimestamps);
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700494 }
495
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800496 if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
497 result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
498 if (result != NO_ERROR) {
Mathias Agopianba93b3f2013-08-01 15:48:40 -0700499 ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
Jesse Hall9f5a1b62014-10-02 11:09:03 -0700500 mGraphicBufferProducer->cancelBuffer(buf, fence);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800501 return result;
502 }
503 }
Mathias Agopian579b3f82010-06-08 19:54:15 -0700504
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800505 if (fence->isValid()) {
506 *fenceFd = fence->dup();
507 if (*fenceFd == -1) {
508 ALOGE("dequeueBuffer: error duping fence: %d", errno);
509 // dup() should never fail; something is badly wrong. Soldier on
510 // and hope for the best; the worst that should happen is some
511 // visible corruption that lasts until the next frame.
512 }
Ted Bonkenburge5d6eb82011-08-09 22:38:41 -0700513 } else {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800514 *fenceFd = -1;
Mathias Agopiana0c30e92010-06-04 18:26:32 -0700515 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800516
517 *buffer = gbuf.get();
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800518
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700519 if (mSharedBufferMode && mAutoRefresh) {
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800520 mSharedBufferSlot = buf;
521 mSharedBufferHasBeenQueued = false;
522 } else if (mSharedBufferSlot == buf) {
523 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
524 mSharedBufferHasBeenQueued = false;
525 }
526
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800527 return OK;
Jamie Gennisaca4e222010-07-15 17:29:15 -0700528}
529
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800530int Surface::cancelBuffer(android_native_buffer_t* buffer,
531 int fenceFd) {
532 ATRACE_CALL();
533 ALOGV("Surface::cancelBuffer");
534 Mutex::Autolock lock(mMutex);
535 int i = getSlotFromBufferLocked(buffer);
536 if (i < 0) {
Taiju Tsuiki4d0cd3f2015-04-30 22:15:33 +0900537 if (fenceFd >= 0) {
538 close(fenceFd);
539 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800540 return i;
541 }
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800542 if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
543 if (fenceFd >= 0) {
544 close(fenceFd);
545 }
546 return OK;
547 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800548 sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
549 mGraphicBufferProducer->cancelBuffer(i, fence);
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800550
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700551 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800552 mSharedBufferHasBeenQueued = true;
553 }
554
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800555 return OK;
556}
557
558int Surface::getSlotFromBufferLocked(
559 android_native_buffer_t* buffer) const {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800560 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
561 if (mSlots[i].buffer != NULL &&
562 mSlots[i].buffer->handle == buffer->handle) {
563 return i;
Jamie Gennisaca4e222010-07-15 17:29:15 -0700564 }
565 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800566 ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
567 return BAD_VALUE;
Mathias Agopiana0c30e92010-06-04 18:26:32 -0700568}
569
Igor Murashkin7d2d1602013-11-12 18:02:20 -0800570int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800571 ALOGV("Surface::lockBuffer");
572 Mutex::Autolock lock(mMutex);
573 return OK;
574}
Mathias Agopian631f3582010-05-25 17:51:34 -0700575
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800576int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
577 ATRACE_CALL();
578 ALOGV("Surface::queueBuffer");
579 Mutex::Autolock lock(mMutex);
580 int64_t timestamp;
Andy McFadden3c256212013-08-16 14:55:39 -0700581 bool isAutoTimestamp = false;
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800582
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800583 if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
Andy McFadden4b49e082013-08-02 15:31:45 -0700584 timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
Andy McFadden3c256212013-08-16 14:55:39 -0700585 isAutoTimestamp = true;
Andy McFadden4b49e082013-08-02 15:31:45 -0700586 ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
Colin Cross9a80d502016-09-27 14:12:48 -0700587 timestamp / 1000000.0);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800588 } else {
589 timestamp = mTimestamp;
Mathias Agopian631f3582010-05-25 17:51:34 -0700590 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800591 int i = getSlotFromBufferLocked(buffer);
592 if (i < 0) {
Taiju Tsuiki4d0cd3f2015-04-30 22:15:33 +0900593 if (fenceFd >= 0) {
594 close(fenceFd);
595 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800596 return i;
597 }
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800598 if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
599 if (fenceFd >= 0) {
600 close(fenceFd);
601 }
602 return OK;
603 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800604
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800605
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800606 // Make sure the crop rectangle is entirely inside the buffer.
Pablo Ceballos60d69222015-08-07 14:47:20 -0700607 Rect crop(Rect::EMPTY_RECT);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800608 mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800609
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800610 sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
611 IGraphicBufferProducer::QueueBufferOutput output;
Andy McFadden3c256212013-08-16 14:55:39 -0700612 IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800613 mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700614 fence, mStickyTransform, mEnableFrameTimestamps);
Dan Stoza5065a552015-03-17 16:23:42 -0700615
Dan Stozac62acbd2015-04-21 16:42:49 -0700616 if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) {
Dan Stoza5065a552015-03-17 16:23:42 -0700617 input.setSurfaceDamage(Region::INVALID_REGION);
618 } else {
Dan Stozadb4850c2015-06-25 16:10:18 -0700619 // Here we do two things:
620 // 1) The surface damage was specified using the OpenGL ES convention of
621 // the origin being in the bottom-left corner. Here we flip to the
622 // convention that the rest of the system uses (top-left corner) by
623 // subtracting all top/bottom coordinates from the buffer height.
624 // 2) If the buffer is coming in rotated (for example, because the EGL
625 // implementation is reacting to the transform hint coming back from
626 // SurfaceFlinger), the surface damage needs to be rotated the
627 // opposite direction, since it was generated assuming an unrotated
628 // buffer (the app doesn't know that the EGL implementation is
629 // reacting to the transform hint behind its back). The
630 // transformations in the switch statement below apply those
631 // complementary rotations (e.g., if 90 degrees, rotate 270 degrees).
632
633 int width = buffer->width;
Dan Stoza0e65e6c2015-05-26 13:22:27 -0700634 int height = buffer->height;
Dan Stozadb4850c2015-06-25 16:10:18 -0700635 bool rotated90 = (mTransform ^ mStickyTransform) &
636 NATIVE_WINDOW_TRANSFORM_ROT_90;
637 if (rotated90) {
638 std::swap(width, height);
Dan Stoza0e65e6c2015-05-26 13:22:27 -0700639 }
Dan Stozadb4850c2015-06-25 16:10:18 -0700640
Dan Stoza5065a552015-03-17 16:23:42 -0700641 Region flippedRegion;
642 for (auto rect : mDirtyRegion) {
Dan Stozadb4850c2015-06-25 16:10:18 -0700643 int left = rect.left;
644 int right = rect.right;
645 int top = height - rect.bottom; // Flip from OpenGL convention
646 int bottom = height - rect.top; // Flip from OpenGL convention
647 switch (mTransform ^ mStickyTransform) {
648 case NATIVE_WINDOW_TRANSFORM_ROT_90: {
649 // Rotate 270 degrees
650 Rect flippedRect{top, width - right, bottom, width - left};
651 flippedRegion.orSelf(flippedRect);
652 break;
653 }
654 case NATIVE_WINDOW_TRANSFORM_ROT_180: {
655 // Rotate 180 degrees
656 Rect flippedRect{width - right, height - bottom,
657 width - left, height - top};
658 flippedRegion.orSelf(flippedRect);
659 break;
660 }
661 case NATIVE_WINDOW_TRANSFORM_ROT_270: {
662 // Rotate 90 degrees
663 Rect flippedRect{height - bottom, left,
664 height - top, right};
665 flippedRegion.orSelf(flippedRect);
666 break;
667 }
668 default: {
669 Rect flippedRect{left, top, right, bottom};
670 flippedRegion.orSelf(flippedRect);
671 break;
672 }
673 }
Dan Stoza5065a552015-03-17 16:23:42 -0700674 }
675
676 input.setSurfaceDamage(flippedRegion);
677 }
678
Dan Stoza70ccba52016-07-01 14:00:40 -0700679 nsecs_t now = systemTime();
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800680 status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
Dan Stoza70ccba52016-07-01 14:00:40 -0700681 mLastQueueDuration = systemTime() - now;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800682 if (err != OK) {
683 ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
684 }
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800685
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700686 if (mEnableFrameTimestamps) {
Brian Anderson3da8d272016-07-28 16:20:47 -0700687 mFrameEventHistory->applyDelta(output.frameTimestamps);
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700688 // Update timestamps with the local acquire fence.
689 // The consumer doesn't send it back to prevent us from having two
690 // file descriptors of the same fence.
Brian Anderson3da8d272016-07-28 16:20:47 -0700691 mFrameEventHistory->updateAcquireFence(mNextFrameNumber,
Brian Anderson3d4039d2016-09-23 16:31:30 -0700692 std::make_shared<FenceTime>(std::move(fence)));
693
694 // Cache timestamps of signaled fences so we can close their file
695 // descriptors.
Brian Anderson3da8d272016-07-28 16:20:47 -0700696 mFrameEventHistory->updateSignalTimes();
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700697 }
698
Brian Anderson50143b32016-09-30 14:01:24 -0700699 mLastFrameNumber = mNextFrameNumber;
700
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700701 mDefaultWidth = output.width;
702 mDefaultHeight = output.height;
703 mNextFrameNumber = output.nextFrameNumber;
tedbo1e7fa9e2011-06-22 15:52:53 -0700704
Ruben Brunk1681d952014-06-27 15:51:55 -0700705 // Disable transform hint if sticky transform is set.
706 if (mStickyTransform == 0) {
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700707 mTransformHint = output.transformHint;
Ruben Brunk1681d952014-06-27 15:51:55 -0700708 }
709
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700710 mConsumerRunningBehind = (output.numPendingBuffers >= 2);
Mathias Agopian631f3582010-05-25 17:51:34 -0700711
Dan Stozac62acbd2015-04-21 16:42:49 -0700712 if (!mConnectedToCpu) {
713 // Clear surface damage back to full-buffer
714 mDirtyRegion = Region::INVALID_REGION;
715 }
Dan Stoza5065a552015-03-17 16:23:42 -0700716
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700717 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800718 mSharedBufferHasBeenQueued = true;
719 }
720
Robert Carr9f31e292016-04-11 11:15:32 -0700721 mQueueBufferCondition.broadcast();
722
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800723 return err;
724}
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700725
Mathias Agopiana67932f2011-04-20 14:20:59 -0700726int Surface::query(int what, int* value) const {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800727 ATRACE_CALL();
728 ALOGV("Surface::query");
729 { // scope for the lock
730 Mutex::Autolock lock(mMutex);
731 switch (what) {
732 case NATIVE_WINDOW_FORMAT:
733 if (mReqFormat) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800734 *value = static_cast<int>(mReqFormat);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800735 return NO_ERROR;
736 }
737 break;
738 case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
Brian Anderson3da8d272016-07-28 16:20:47 -0700739 if (composerService()->authenticateSurfaceTexture(
740 mGraphicBufferProducer)) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800741 *value = 1;
742 } else {
743 *value = 0;
744 }
745 return NO_ERROR;
746 }
747 case NATIVE_WINDOW_CONCRETE_TYPE:
748 *value = NATIVE_WINDOW_SURFACE;
749 return NO_ERROR;
750 case NATIVE_WINDOW_DEFAULT_WIDTH:
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800751 *value = static_cast<int>(
752 mUserWidth ? mUserWidth : mDefaultWidth);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800753 return NO_ERROR;
754 case NATIVE_WINDOW_DEFAULT_HEIGHT:
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800755 *value = static_cast<int>(
756 mUserHeight ? mUserHeight : mDefaultHeight);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800757 return NO_ERROR;
758 case NATIVE_WINDOW_TRANSFORM_HINT:
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800759 *value = static_cast<int>(mTransformHint);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800760 return NO_ERROR;
761 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
762 status_t err = NO_ERROR;
763 if (!mConsumerRunningBehind) {
764 *value = 0;
765 } else {
766 err = mGraphicBufferProducer->query(what, value);
767 if (err == NO_ERROR) {
768 mConsumerRunningBehind = *value;
769 }
770 }
771 return err;
772 }
Dan Stoza70ccba52016-07-01 14:00:40 -0700773 case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: {
774 int64_t durationUs = mLastDequeueDuration / 1000;
775 *value = durationUs > std::numeric_limits<int>::max() ?
776 std::numeric_limits<int>::max() :
777 static_cast<int>(durationUs);
778 return NO_ERROR;
779 }
780 case NATIVE_WINDOW_LAST_QUEUE_DURATION: {
781 int64_t durationUs = mLastQueueDuration / 1000;
782 *value = durationUs > std::numeric_limits<int>::max() ?
783 std::numeric_limits<int>::max() :
784 static_cast<int>(durationUs);
785 return NO_ERROR;
786 }
Mathias Agopian10e9ab52017-03-08 15:02:55 -0800787 case NATIVE_WINDOW_IS_VALID: {
788 *value = mGraphicBufferProducer != nullptr ? 1 : 0;
789 return NO_ERROR;
790 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800791 }
Jamie Gennis391bbe22011-03-14 15:00:06 -0700792 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800793 return mGraphicBufferProducer->query(what, value);
Eino-Ville Talvala1d01a122011-02-18 11:02:42 -0800794}
795
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800796int Surface::perform(int operation, va_list args)
797{
798 int res = NO_ERROR;
799 switch (operation) {
800 case NATIVE_WINDOW_CONNECT:
801 // deprecated. must return NO_ERROR.
802 break;
803 case NATIVE_WINDOW_DISCONNECT:
804 // deprecated. must return NO_ERROR.
805 break;
806 case NATIVE_WINDOW_SET_USAGE:
807 res = dispatchSetUsage(args);
808 break;
809 case NATIVE_WINDOW_SET_CROP:
810 res = dispatchSetCrop(args);
811 break;
812 case NATIVE_WINDOW_SET_BUFFER_COUNT:
813 res = dispatchSetBufferCount(args);
814 break;
815 case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
816 res = dispatchSetBuffersGeometry(args);
817 break;
818 case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
819 res = dispatchSetBuffersTransform(args);
820 break;
Ruben Brunk1681d952014-06-27 15:51:55 -0700821 case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM:
822 res = dispatchSetBuffersStickyTransform(args);
823 break;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800824 case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
825 res = dispatchSetBuffersTimestamp(args);
826 break;
827 case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
828 res = dispatchSetBuffersDimensions(args);
829 break;
830 case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
831 res = dispatchSetBuffersUserDimensions(args);
832 break;
833 case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
834 res = dispatchSetBuffersFormat(args);
835 break;
836 case NATIVE_WINDOW_LOCK:
837 res = dispatchLock(args);
838 break;
839 case NATIVE_WINDOW_UNLOCK_AND_POST:
840 res = dispatchUnlockAndPost(args);
841 break;
842 case NATIVE_WINDOW_SET_SCALING_MODE:
843 res = dispatchSetScalingMode(args);
844 break;
845 case NATIVE_WINDOW_API_CONNECT:
846 res = dispatchConnect(args);
847 break;
848 case NATIVE_WINDOW_API_DISCONNECT:
849 res = dispatchDisconnect(args);
850 break;
Rachad7cb0d392014-07-29 17:53:53 -0700851 case NATIVE_WINDOW_SET_SIDEBAND_STREAM:
852 res = dispatchSetSidebandStream(args);
853 break;
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800854 case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
855 res = dispatchSetBuffersDataSpace(args);
856 break;
Dan Stoza5065a552015-03-17 16:23:42 -0700857 case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
858 res = dispatchSetSurfaceDamage(args);
859 break;
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700860 case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE:
861 res = dispatchSetSharedBufferMode(args);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700862 break;
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800863 case NATIVE_WINDOW_SET_AUTO_REFRESH:
864 res = dispatchSetAutoRefresh(args);
865 break;
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800866 case NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION:
867 res = dispatchGetDisplayRefreshCycleDuration(args);
868 break;
Brian Anderson1049d1d2016-12-16 17:25:57 -0800869 case NATIVE_WINDOW_GET_NEXT_FRAME_ID:
870 res = dispatchGetNextFrameId(args);
871 break;
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700872 case NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS:
873 res = dispatchEnableFrameTimestamps(args);
874 break;
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800875 case NATIVE_WINDOW_GET_COMPOSITOR_TIMING:
876 res = dispatchGetCompositorTiming(args);
877 break;
Pablo Ceballosce796e72016-02-04 19:10:51 -0800878 case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS:
879 res = dispatchGetFrameTimestamps(args);
880 break;
Courtney Goeltzenleuchter1eb1b272017-02-02 16:51:06 -0700881 case NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT:
882 res = dispatchGetWideColorSupport(args);
883 break;
Courtney Goeltzenleuchterc5b97c52017-02-26 14:47:13 -0700884 case NATIVE_WINDOW_GET_HDR_SUPPORT:
885 res = dispatchGetHdrSupport(args);
886 break;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800887 default:
888 res = NAME_NOT_FOUND;
889 break;
890 }
891 return res;
892}
Mathias Agopiana138f892010-05-21 17:24:35 -0700893
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800894int Surface::dispatchConnect(va_list args) {
895 int api = va_arg(args, int);
896 return connect(api);
897}
Mathias Agopian55fa2512010-03-11 15:06:54 -0800898
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800899int Surface::dispatchDisconnect(va_list args) {
900 int api = va_arg(args, int);
901 return disconnect(api);
902}
903
904int Surface::dispatchSetUsage(va_list args) {
905 int usage = va_arg(args, int);
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800906 return setUsage(static_cast<uint32_t>(usage));
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800907}
908
909int Surface::dispatchSetCrop(va_list args) {
910 android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
911 return setCrop(reinterpret_cast<Rect const*>(rect));
912}
913
914int Surface::dispatchSetBufferCount(va_list args) {
915 size_t bufferCount = va_arg(args, size_t);
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800916 return setBufferCount(static_cast<int32_t>(bufferCount));
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800917}
918
919int Surface::dispatchSetBuffersGeometry(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800920 uint32_t width = va_arg(args, uint32_t);
921 uint32_t height = va_arg(args, uint32_t);
922 PixelFormat format = va_arg(args, PixelFormat);
923 int err = setBuffersDimensions(width, height);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800924 if (err != 0) {
925 return err;
926 }
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800927 return setBuffersFormat(format);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800928}
929
930int Surface::dispatchSetBuffersDimensions(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800931 uint32_t width = va_arg(args, uint32_t);
932 uint32_t height = va_arg(args, uint32_t);
933 return setBuffersDimensions(width, height);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800934}
935
936int Surface::dispatchSetBuffersUserDimensions(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800937 uint32_t width = va_arg(args, uint32_t);
938 uint32_t height = va_arg(args, uint32_t);
939 return setBuffersUserDimensions(width, height);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800940}
941
942int Surface::dispatchSetBuffersFormat(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800943 PixelFormat format = va_arg(args, PixelFormat);
944 return setBuffersFormat(format);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800945}
946
947int Surface::dispatchSetScalingMode(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800948 int mode = va_arg(args, int);
949 return setScalingMode(mode);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800950}
951
952int Surface::dispatchSetBuffersTransform(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800953 uint32_t transform = va_arg(args, uint32_t);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800954 return setBuffersTransform(transform);
955}
956
Ruben Brunk1681d952014-06-27 15:51:55 -0700957int Surface::dispatchSetBuffersStickyTransform(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800958 uint32_t transform = va_arg(args, uint32_t);
Ruben Brunk1681d952014-06-27 15:51:55 -0700959 return setBuffersStickyTransform(transform);
960}
961
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800962int Surface::dispatchSetBuffersTimestamp(va_list args) {
963 int64_t timestamp = va_arg(args, int64_t);
964 return setBuffersTimestamp(timestamp);
965}
966
967int Surface::dispatchLock(va_list args) {
968 ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
969 ARect* inOutDirtyBounds = va_arg(args, ARect*);
970 return lock(outBuffer, inOutDirtyBounds);
971}
972
Igor Murashkin7d2d1602013-11-12 18:02:20 -0800973int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800974 return unlockAndPost();
975}
976
Rachad7cb0d392014-07-29 17:53:53 -0700977int Surface::dispatchSetSidebandStream(va_list args) {
978 native_handle_t* sH = va_arg(args, native_handle_t*);
979 sp<NativeHandle> sidebandHandle = NativeHandle::create(sH, false);
980 setSidebandStream(sidebandHandle);
981 return OK;
982}
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800983
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800984int Surface::dispatchSetBuffersDataSpace(va_list args) {
985 android_dataspace dataspace =
986 static_cast<android_dataspace>(va_arg(args, int));
987 return setBuffersDataSpace(dataspace);
988}
989
Dan Stoza5065a552015-03-17 16:23:42 -0700990int Surface::dispatchSetSurfaceDamage(va_list args) {
991 android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
992 size_t numRects = va_arg(args, size_t);
993 setSurfaceDamage(rects, numRects);
994 return NO_ERROR;
995}
996
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700997int Surface::dispatchSetSharedBufferMode(va_list args) {
998 bool sharedBufferMode = va_arg(args, int);
999 return setSharedBufferMode(sharedBufferMode);
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001000}
1001
1002int Surface::dispatchSetAutoRefresh(va_list args) {
1003 bool autoRefresh = va_arg(args, int);
1004 return setAutoRefresh(autoRefresh);
Pablo Ceballosccdfd602015-10-07 15:05:45 -07001005}
1006
Brian Anderson0a61b0c2016-12-07 14:55:56 -08001007int Surface::dispatchGetDisplayRefreshCycleDuration(va_list args) {
1008 nsecs_t* outRefreshDuration = va_arg(args, int64_t*);
1009 return getDisplayRefreshCycleDuration(outRefreshDuration);
1010}
1011
Brian Anderson1049d1d2016-12-16 17:25:57 -08001012int Surface::dispatchGetNextFrameId(va_list args) {
1013 uint64_t* nextFrameId = va_arg(args, uint64_t*);
1014 *nextFrameId = getNextFrameNumber();
1015 return NO_ERROR;
1016}
1017
Brian Anderson7c3ba8a2016-07-25 12:48:08 -07001018int Surface::dispatchEnableFrameTimestamps(va_list args) {
1019 bool enable = va_arg(args, int);
1020 enableFrameTimestamps(enable);
1021 return NO_ERROR;
1022}
1023
Brian Anderson0a61b0c2016-12-07 14:55:56 -08001024int Surface::dispatchGetCompositorTiming(va_list args) {
1025 nsecs_t* compositeDeadline = va_arg(args, int64_t*);
1026 nsecs_t* compositeInterval = va_arg(args, int64_t*);
1027 nsecs_t* compositeToPresentLatency = va_arg(args, int64_t*);
1028 return getCompositorTiming(compositeDeadline, compositeInterval,
1029 compositeToPresentLatency);
1030}
1031
Pablo Ceballosce796e72016-02-04 19:10:51 -08001032int Surface::dispatchGetFrameTimestamps(va_list args) {
Brian Anderson1049d1d2016-12-16 17:25:57 -08001033 uint64_t frameId = va_arg(args, uint64_t);
Brian Andersondbd0ea82016-07-22 09:38:59 -07001034 nsecs_t* outRequestedPresentTime = va_arg(args, int64_t*);
Pablo Ceballosce796e72016-02-04 19:10:51 -08001035 nsecs_t* outAcquireTime = va_arg(args, int64_t*);
Brian Andersonf7fd56a2016-09-02 10:10:04 -07001036 nsecs_t* outLatchTime = va_arg(args, int64_t*);
1037 nsecs_t* outFirstRefreshStartTime = va_arg(args, int64_t*);
1038 nsecs_t* outLastRefreshStartTime = va_arg(args, int64_t*);
Brian Andersonb04c6f02016-10-21 12:57:46 -07001039 nsecs_t* outGpuCompositionDoneTime = va_arg(args, int64_t*);
Brian Anderson069b3652016-07-22 10:32:47 -07001040 nsecs_t* outDisplayPresentTime = va_arg(args, int64_t*);
Brian Andersonf7fd56a2016-09-02 10:10:04 -07001041 nsecs_t* outDequeueReadyTime = va_arg(args, int64_t*);
Pablo Ceballosce796e72016-02-04 19:10:51 -08001042 nsecs_t* outReleaseTime = va_arg(args, int64_t*);
Brian Anderson1049d1d2016-12-16 17:25:57 -08001043 return getFrameTimestamps(frameId,
Brian Andersonf7fd56a2016-09-02 10:10:04 -07001044 outRequestedPresentTime, outAcquireTime, outLatchTime,
1045 outFirstRefreshStartTime, outLastRefreshStartTime,
Brian Andersonb04c6f02016-10-21 12:57:46 -07001046 outGpuCompositionDoneTime, outDisplayPresentTime,
Brian Anderson4e606e32017-03-16 15:34:57 -07001047 outDequeueReadyTime, outReleaseTime);
Pablo Ceballosce796e72016-02-04 19:10:51 -08001048}
1049
Courtney Goeltzenleuchter1eb1b272017-02-02 16:51:06 -07001050int Surface::dispatchGetWideColorSupport(va_list args) {
1051 bool* outSupport = va_arg(args, bool*);
1052 return getWideColorSupport(outSupport);
1053}
1054
Courtney Goeltzenleuchterc5b97c52017-02-26 14:47:13 -07001055int Surface::dispatchGetHdrSupport(va_list args) {
1056 bool* outSupport = va_arg(args, bool*);
1057 return getHdrSupport(outSupport);
1058}
1059
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001060int Surface::connect(int api) {
Dan Stoza966b98b2015-03-02 22:12:37 -08001061 static sp<IProducerListener> listener = new DummyProducerListener();
1062 return connect(api, listener);
1063}
1064
1065int Surface::connect(int api, const sp<IProducerListener>& listener) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001066 ATRACE_CALL();
1067 ALOGV("Surface::connect");
1068 Mutex::Autolock lock(mMutex);
1069 IGraphicBufferProducer::QueueBufferOutput output;
Dan Stozaf0eaf252014-03-21 13:05:51 -07001070 int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001071 if (err == NO_ERROR) {
Brian Anderson7c3ba8a2016-07-25 12:48:08 -07001072 mDefaultWidth = output.width;
1073 mDefaultHeight = output.height;
1074 mNextFrameNumber = output.nextFrameNumber;
Ruben Brunk1681d952014-06-27 15:51:55 -07001075
1076 // Disable transform hint if sticky transform is set.
1077 if (mStickyTransform == 0) {
Brian Anderson7c3ba8a2016-07-25 12:48:08 -07001078 mTransformHint = output.transformHint;
Ruben Brunk1681d952014-06-27 15:51:55 -07001079 }
1080
Brian Anderson7c3ba8a2016-07-25 12:48:08 -07001081 mConsumerRunningBehind = (output.numPendingBuffers >= 2);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001082 }
1083 if (!err && api == NATIVE_WINDOW_API_CPU) {
1084 mConnectedToCpu = true;
Dan Stoza5065a552015-03-17 16:23:42 -07001085 // Clear the dirty region in case we're switching from a non-CPU API
1086 mDirtyRegion.clear();
1087 } else if (!err) {
1088 // Initialize the dirty region for tracking surface damage
1089 mDirtyRegion = Region::INVALID_REGION;
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001090 }
Dan Stoza5065a552015-03-17 16:23:42 -07001091
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001092 return err;
1093}
1094
Mathias Agopian365857d2013-09-11 19:35:45 -07001095
Robert Carr97b9c862016-09-08 13:54:35 -07001096int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001097 ATRACE_CALL();
1098 ALOGV("Surface::disconnect");
1099 Mutex::Autolock lock(mMutex);
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001100 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1101 mSharedBufferHasBeenQueued = false;
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001102 freeAllBuffers();
Robert Carr97b9c862016-09-08 13:54:35 -07001103 int err = mGraphicBufferProducer->disconnect(api, mode);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001104 if (!err) {
1105 mReqFormat = 0;
1106 mReqWidth = 0;
1107 mReqHeight = 0;
1108 mReqUsage = 0;
1109 mCrop.clear();
1110 mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
1111 mTransform = 0;
Ruben Brunk1681d952014-06-27 15:51:55 -07001112 mStickyTransform = 0;
1113
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001114 if (api == NATIVE_WINDOW_API_CPU) {
1115 mConnectedToCpu = false;
1116 }
1117 }
1118 return err;
1119}
1120
Dan Stozad9c49712015-04-27 11:06:01 -07001121int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
Dan Stoza231832e2015-03-11 11:55:01 -07001122 sp<Fence>* outFence) {
1123 ATRACE_CALL();
1124 ALOGV("Surface::detachNextBuffer");
1125
1126 if (outBuffer == NULL || outFence == NULL) {
1127 return BAD_VALUE;
1128 }
1129
1130 Mutex::Autolock lock(mMutex);
1131
1132 sp<GraphicBuffer> buffer(NULL);
1133 sp<Fence> fence(NULL);
1134 status_t result = mGraphicBufferProducer->detachNextBuffer(
1135 &buffer, &fence);
1136 if (result != NO_ERROR) {
1137 return result;
1138 }
1139
Dan Stozad9c49712015-04-27 11:06:01 -07001140 *outBuffer = buffer;
Dan Stoza231832e2015-03-11 11:55:01 -07001141 if (fence != NULL && fence->isValid()) {
1142 *outFence = fence;
1143 } else {
1144 *outFence = Fence::NO_FENCE;
1145 }
1146
Pablo Ceballos23b4abe2016-01-08 12:15:22 -08001147 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
1148 if (mSlots[i].buffer != NULL &&
1149 mSlots[i].buffer->handle == buffer->handle) {
1150 mSlots[i].buffer = NULL;
1151 }
1152 }
1153
Dan Stoza231832e2015-03-11 11:55:01 -07001154 return NO_ERROR;
1155}
1156
1157int Surface::attachBuffer(ANativeWindowBuffer* buffer)
1158{
1159 ATRACE_CALL();
1160 ALOGV("Surface::attachBuffer");
1161
1162 Mutex::Autolock lock(mMutex);
1163
1164 sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
Dan Stoza812ed062015-06-02 15:45:22 -07001165 uint32_t priorGeneration = graphicBuffer->mGenerationNumber;
1166 graphicBuffer->mGenerationNumber = mGenerationNumber;
Dan Stoza231832e2015-03-11 11:55:01 -07001167 int32_t attachedSlot = -1;
1168 status_t result = mGraphicBufferProducer->attachBuffer(
1169 &attachedSlot, graphicBuffer);
1170 if (result != NO_ERROR) {
1171 ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result);
Dan Stoza812ed062015-06-02 15:45:22 -07001172 graphicBuffer->mGenerationNumber = priorGeneration;
Dan Stoza231832e2015-03-11 11:55:01 -07001173 return result;
1174 }
1175 mSlots[attachedSlot].buffer = graphicBuffer;
1176
1177 return NO_ERROR;
1178}
1179
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001180int Surface::setUsage(uint32_t reqUsage)
1181{
1182 ALOGV("Surface::setUsage");
1183 Mutex::Autolock lock(mMutex);
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001184 if (reqUsage != mReqUsage) {
1185 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1186 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001187 mReqUsage = reqUsage;
1188 return OK;
1189}
1190
1191int Surface::setCrop(Rect const* rect)
1192{
1193 ATRACE_CALL();
1194
Pablo Ceballos60d69222015-08-07 14:47:20 -07001195 Rect realRect(Rect::EMPTY_RECT);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001196 if (rect == NULL || rect->isEmpty()) {
1197 realRect.clear();
1198 } else {
1199 realRect = *rect;
Mathias Agopian55fa2512010-03-11 15:06:54 -08001200 }
1201
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001202 ALOGV("Surface::setCrop rect=[%d %d %d %d]",
1203 realRect.left, realRect.top, realRect.right, realRect.bottom);
1204
1205 Mutex::Autolock lock(mMutex);
1206 mCrop = realRect;
1207 return NO_ERROR;
1208}
1209
1210int Surface::setBufferCount(int bufferCount)
1211{
1212 ATRACE_CALL();
1213 ALOGV("Surface::setBufferCount");
1214 Mutex::Autolock lock(mMutex);
1215
Pablo Ceballose5b755a2015-08-13 16:18:19 -07001216 status_t err = NO_ERROR;
1217 if (bufferCount == 0) {
1218 err = mGraphicBufferProducer->setMaxDequeuedBufferCount(1);
1219 } else {
1220 int minUndequeuedBuffers = 0;
1221 err = mGraphicBufferProducer->query(
1222 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers);
1223 if (err == NO_ERROR) {
1224 err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
1225 bufferCount - minUndequeuedBuffers);
1226 }
1227 }
Mathias Agopian90147262010-01-22 11:47:55 -08001228
Pablo Ceballose5b755a2015-08-13 16:18:19 -07001229 ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
1230 bufferCount, strerror(-err));
1231
Mathias Agopian076b1cc2009-04-10 14:24:30 -07001232 return err;
1233}
Mathias Agopian076b1cc2009-04-10 14:24:30 -07001234
Pablo Ceballosfa455352015-08-12 17:47:47 -07001235int Surface::setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
1236 ATRACE_CALL();
1237 ALOGV("Surface::setMaxDequeuedBufferCount");
1238 Mutex::Autolock lock(mMutex);
1239
1240 status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
1241 maxDequeuedBuffers);
1242 ALOGE_IF(err, "IGraphicBufferProducer::setMaxDequeuedBufferCount(%d) "
1243 "returned %s", maxDequeuedBuffers, strerror(-err));
1244
Pablo Ceballosfa455352015-08-12 17:47:47 -07001245 return err;
1246}
1247
1248int Surface::setAsyncMode(bool async) {
1249 ATRACE_CALL();
1250 ALOGV("Surface::setAsyncMode");
1251 Mutex::Autolock lock(mMutex);
1252
1253 status_t err = mGraphicBufferProducer->setAsyncMode(async);
1254 ALOGE_IF(err, "IGraphicBufferProducer::setAsyncMode(%d) returned %s",
1255 async, strerror(-err));
1256
Pablo Ceballosfa455352015-08-12 17:47:47 -07001257 return err;
1258}
1259
Pablo Ceballos3559fbf2016-03-17 15:50:23 -07001260int Surface::setSharedBufferMode(bool sharedBufferMode) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -07001261 ATRACE_CALL();
Pablo Ceballos3559fbf2016-03-17 15:50:23 -07001262 ALOGV("Surface::setSharedBufferMode (%d)", sharedBufferMode);
Pablo Ceballosccdfd602015-10-07 15:05:45 -07001263 Mutex::Autolock lock(mMutex);
1264
Pablo Ceballos3559fbf2016-03-17 15:50:23 -07001265 status_t err = mGraphicBufferProducer->setSharedBufferMode(
1266 sharedBufferMode);
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001267 if (err == NO_ERROR) {
Pablo Ceballos3559fbf2016-03-17 15:50:23 -07001268 mSharedBufferMode = sharedBufferMode;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001269 }
Pablo Ceballos3559fbf2016-03-17 15:50:23 -07001270 ALOGE_IF(err, "IGraphicBufferProducer::setSharedBufferMode(%d) returned"
1271 "%s", sharedBufferMode, strerror(-err));
Pablo Ceballosccdfd602015-10-07 15:05:45 -07001272
1273 return err;
1274}
1275
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001276int Surface::setAutoRefresh(bool autoRefresh) {
1277 ATRACE_CALL();
1278 ALOGV("Surface::setAutoRefresh (%d)", autoRefresh);
1279 Mutex::Autolock lock(mMutex);
1280
1281 status_t err = mGraphicBufferProducer->setAutoRefresh(autoRefresh);
1282 if (err == NO_ERROR) {
1283 mAutoRefresh = autoRefresh;
1284 }
1285 ALOGE_IF(err, "IGraphicBufferProducer::setAutoRefresh(%d) returned %s",
1286 autoRefresh, strerror(-err));
1287 return err;
1288}
1289
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001290int Surface::setBuffersDimensions(uint32_t width, uint32_t height)
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001291{
1292 ATRACE_CALL();
1293 ALOGV("Surface::setBuffersDimensions");
1294
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001295 if ((width && !height) || (!width && height))
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001296 return BAD_VALUE;
1297
1298 Mutex::Autolock lock(mMutex);
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001299 if (width != mReqWidth || height != mReqHeight) {
1300 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1301 }
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001302 mReqWidth = width;
1303 mReqHeight = height;
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001304 return NO_ERROR;
1305}
1306
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001307int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height)
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001308{
1309 ATRACE_CALL();
1310 ALOGV("Surface::setBuffersUserDimensions");
1311
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001312 if ((width && !height) || (!width && height))
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001313 return BAD_VALUE;
1314
1315 Mutex::Autolock lock(mMutex);
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001316 if (width != mUserWidth || height != mUserHeight) {
1317 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1318 }
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001319 mUserWidth = width;
1320 mUserHeight = height;
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001321 return NO_ERROR;
1322}
1323
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001324int Surface::setBuffersFormat(PixelFormat format)
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001325{
1326 ALOGV("Surface::setBuffersFormat");
1327
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001328 Mutex::Autolock lock(mMutex);
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001329 if (format != mReqFormat) {
1330 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1331 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001332 mReqFormat = format;
1333 return NO_ERROR;
1334}
1335
1336int Surface::setScalingMode(int mode)
1337{
1338 ATRACE_CALL();
1339 ALOGV("Surface::setScalingMode(%d)", mode);
1340
1341 switch (mode) {
1342 case NATIVE_WINDOW_SCALING_MODE_FREEZE:
1343 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
1344 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
Robert Carrc2e77882015-12-16 18:14:03 -08001345 case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001346 break;
1347 default:
1348 ALOGE("unknown scaling mode: %d", mode);
1349 return BAD_VALUE;
1350 }
1351
1352 Mutex::Autolock lock(mMutex);
1353 mScalingMode = mode;
1354 return NO_ERROR;
1355}
1356
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001357int Surface::setBuffersTransform(uint32_t transform)
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001358{
1359 ATRACE_CALL();
1360 ALOGV("Surface::setBuffersTransform");
1361 Mutex::Autolock lock(mMutex);
1362 mTransform = transform;
1363 return NO_ERROR;
1364}
1365
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001366int Surface::setBuffersStickyTransform(uint32_t transform)
Ruben Brunk1681d952014-06-27 15:51:55 -07001367{
1368 ATRACE_CALL();
1369 ALOGV("Surface::setBuffersStickyTransform");
1370 Mutex::Autolock lock(mMutex);
1371 mStickyTransform = transform;
1372 return NO_ERROR;
1373}
1374
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001375int Surface::setBuffersTimestamp(int64_t timestamp)
1376{
1377 ALOGV("Surface::setBuffersTimestamp");
1378 Mutex::Autolock lock(mMutex);
1379 mTimestamp = timestamp;
1380 return NO_ERROR;
1381}
1382
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -08001383int Surface::setBuffersDataSpace(android_dataspace dataSpace)
1384{
1385 ALOGV("Surface::setBuffersDataSpace");
1386 Mutex::Autolock lock(mMutex);
1387 mDataSpace = dataSpace;
1388 return NO_ERROR;
1389}
1390
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001391void Surface::freeAllBuffers() {
1392 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
1393 mSlots[i].buffer = 0;
1394 }
1395}
1396
Dan Stoza5065a552015-03-17 16:23:42 -07001397void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) {
1398 ATRACE_CALL();
1399 ALOGV("Surface::setSurfaceDamage");
1400 Mutex::Autolock lock(mMutex);
1401
Dan Stozac62acbd2015-04-21 16:42:49 -07001402 if (mConnectedToCpu || numRects == 0) {
Dan Stoza5065a552015-03-17 16:23:42 -07001403 mDirtyRegion = Region::INVALID_REGION;
1404 return;
1405 }
1406
1407 mDirtyRegion.clear();
1408 for (size_t r = 0; r < numRects; ++r) {
1409 // We intentionally flip top and bottom here, since because they're
1410 // specified with a bottom-left origin, top > bottom, which fails
1411 // validation in the Region class. We will fix this up when we flip to a
1412 // top-left origin in queueBuffer.
1413 Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top);
1414 mDirtyRegion.orSelf(rect);
1415 }
1416}
1417
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001418// ----------------------------------------------------------------------
1419// the lock/unlock APIs must be used from the same thread
1420
1421static status_t copyBlt(
1422 const sp<GraphicBuffer>& dst,
1423 const sp<GraphicBuffer>& src,
Francis Hart7b09e792015-01-09 11:10:54 +02001424 const Region& reg,
1425 int *dstFenceFd)
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001426{
1427 // src and dst with, height and format must be identical. no verification
1428 // is done here.
1429 status_t err;
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001430 uint8_t* src_bits = NULL;
1431 err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(),
1432 reinterpret_cast<void**>(&src_bits));
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001433 ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
1434
1435 uint8_t* dst_bits = NULL;
Francis Hart7b09e792015-01-09 11:10:54 +02001436 err = dst->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(),
1437 reinterpret_cast<void**>(&dst_bits), *dstFenceFd);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001438 ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
Francis Hart7b09e792015-01-09 11:10:54 +02001439 *dstFenceFd = -1;
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001440
1441 Region::const_iterator head(reg.begin());
1442 Region::const_iterator tail(reg.end());
1443 if (head != tail && src_bits && dst_bits) {
1444 const size_t bpp = bytesPerPixel(src->format);
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001445 const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp;
1446 const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp;
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001447
1448 while (head != tail) {
1449 const Rect& r(*head++);
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001450 int32_t h = r.height();
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001451 if (h <= 0) continue;
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001452 size_t size = static_cast<uint32_t>(r.width()) * bpp;
1453 uint8_t const * s = src_bits +
1454 static_cast<uint32_t>(r.left + src->stride * r.top) * bpp;
1455 uint8_t * d = dst_bits +
1456 static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp;
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001457 if (dbpr==sbpr && size==sbpr) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001458 size *= static_cast<size_t>(h);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001459 h = 1;
1460 }
1461 do {
1462 memcpy(d, s, size);
1463 d += dbpr;
1464 s += sbpr;
1465 } while (--h > 0);
1466 }
1467 }
1468
1469 if (src_bits)
1470 src->unlock();
1471
1472 if (dst_bits)
Francis Hart7b09e792015-01-09 11:10:54 +02001473 dst->unlockAsync(dstFenceFd);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001474
1475 return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001476}
1477
Mathias Agopiana138f892010-05-21 17:24:35 -07001478// ----------------------------------------------------------------------------
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001479
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001480status_t Surface::lock(
1481 ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
1482{
1483 if (mLockedBuffer != 0) {
1484 ALOGE("Surface::lock failed, already locked");
1485 return INVALID_OPERATION;
1486 }
1487
1488 if (!mConnectedToCpu) {
1489 int err = Surface::connect(NATIVE_WINDOW_API_CPU);
1490 if (err) {
1491 return err;
1492 }
1493 // we're intending to do software rendering from this point
1494 setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
1495 }
1496
1497 ANativeWindowBuffer* out;
1498 int fenceFd = -1;
1499 status_t err = dequeueBuffer(&out, &fenceFd);
1500 ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
1501 if (err == NO_ERROR) {
1502 sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001503 const Rect bounds(backBuffer->width, backBuffer->height);
1504
1505 Region newDirtyRegion;
1506 if (inOutDirtyBounds) {
1507 newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
1508 newDirtyRegion.andSelf(bounds);
1509 } else {
1510 newDirtyRegion.set(bounds);
1511 }
1512
1513 // figure out if we can copy the frontbuffer back
1514 const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
1515 const bool canCopyBack = (frontBuffer != 0 &&
1516 backBuffer->width == frontBuffer->width &&
1517 backBuffer->height == frontBuffer->height &&
1518 backBuffer->format == frontBuffer->format);
1519
1520 if (canCopyBack) {
1521 // copy the area that is invalid and not repainted this round
1522 const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
Francis Hartdc10f842014-12-01 16:04:49 +02001523 if (!copyback.isEmpty()) {
Francis Hart7b09e792015-01-09 11:10:54 +02001524 copyBlt(backBuffer, frontBuffer, copyback, &fenceFd);
Francis Hartdc10f842014-12-01 16:04:49 +02001525 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001526 } else {
1527 // if we can't copy-back anything, modify the user's dirty
1528 // region to make sure they redraw the whole buffer
1529 newDirtyRegion.set(bounds);
1530 mDirtyRegion.clear();
1531 Mutex::Autolock lock(mMutex);
1532 for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
1533 mSlots[i].dirtyRegion.clear();
1534 }
1535 }
1536
1537
1538 { // scope for the lock
1539 Mutex::Autolock lock(mMutex);
1540 int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
1541 if (backBufferSlot >= 0) {
1542 Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
1543 mDirtyRegion.subtract(dirtyRegion);
1544 dirtyRegion = newDirtyRegion;
1545 }
1546 }
1547
1548 mDirtyRegion.orSelf(newDirtyRegion);
1549 if (inOutDirtyBounds) {
1550 *inOutDirtyBounds = newDirtyRegion.getBounds();
1551 }
1552
1553 void* vaddr;
Francis Hart8f396012014-04-01 15:30:53 +03001554 status_t res = backBuffer->lockAsync(
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001555 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
Francis Hart8f396012014-04-01 15:30:53 +03001556 newDirtyRegion.bounds(), &vaddr, fenceFd);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001557
1558 ALOGW_IF(res, "failed locking buffer (handle = %p)",
1559 backBuffer->handle);
1560
1561 if (res != 0) {
1562 err = INVALID_OPERATION;
1563 } else {
1564 mLockedBuffer = backBuffer;
1565 outBuffer->width = backBuffer->width;
1566 outBuffer->height = backBuffer->height;
1567 outBuffer->stride = backBuffer->stride;
1568 outBuffer->format = backBuffer->format;
1569 outBuffer->bits = vaddr;
1570 }
1571 }
1572 return err;
1573}
1574
1575status_t Surface::unlockAndPost()
1576{
1577 if (mLockedBuffer == 0) {
1578 ALOGE("Surface::unlockAndPost failed, no locked buffer");
1579 return INVALID_OPERATION;
1580 }
1581
Francis Hart8f396012014-04-01 15:30:53 +03001582 int fd = -1;
1583 status_t err = mLockedBuffer->unlockAsync(&fd);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001584 ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
1585
Francis Hart8f396012014-04-01 15:30:53 +03001586 err = queueBuffer(mLockedBuffer.get(), fd);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001587 ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
1588 mLockedBuffer->handle, strerror(-err));
1589
1590 mPostedBuffer = mLockedBuffer;
1591 mLockedBuffer = 0;
1592 return err;
1593}
1594
Robert Carr9f31e292016-04-11 11:15:32 -07001595bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) {
1596 Mutex::Autolock lock(mMutex);
Pablo Ceballosbc8c1922016-07-01 14:15:41 -07001597 if (mNextFrameNumber > lastFrame) {
Robert Carr9f31e292016-04-11 11:15:32 -07001598 return true;
1599 }
1600 return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK;
1601}
1602
Pablo Ceballos8e3e92b2016-06-27 17:56:53 -07001603status_t Surface::getUniqueId(uint64_t* outId) const {
1604 Mutex::Autolock lock(mMutex);
1605 return mGraphicBufferProducer->getUniqueId(outId);
1606}
1607
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001608}; // namespace android