blob: 8b8a501ff6ee9811f3271c5f7aa721c4ff831916 [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 Agopianb0e76f42012-03-23 14:15:44 -070021#include <android/native_window.h>
22
Mathias Agopiane3c697f2013-02-14 17:11:02 -080023#include <binder/Parcel.h>
24
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
Mathias Agopiane3c697f2013-02-14 17:11:02 -080029#include <ui/Fence.h>
Dan Stoza5065a552015-03-17 16:23:42 -070030#include <ui/Region.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070031
Dan Stozaf0eaf252014-03-21 13:05:51 -070032#include <gui/IProducerListener.h>
Mathias Agopian90ac7992012-02-25 18:48:35 -080033#include <gui/ISurfaceComposer.h>
Mathias Agopian90ac7992012-02-25 18:48:35 -080034#include <gui/SurfaceComposerClient.h>
Mathias Agopiane3c697f2013-02-14 17:11:02 -080035#include <gui/GLConsumer.h>
36#include <gui/Surface.h>
37
38#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),
52 mNextFrameNumber(1)
Mathias Agopian62185b72009-04-16 16:19:50 -070053{
Mathias Agopiane3c697f2013-02-14 17:11:02 -080054 // Initialize the ANativeWindow function pointers.
55 ANativeWindow::setSwapInterval = hook_setSwapInterval;
56 ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
57 ANativeWindow::cancelBuffer = hook_cancelBuffer;
58 ANativeWindow::queueBuffer = hook_queueBuffer;
59 ANativeWindow::query = hook_query;
60 ANativeWindow::perform = hook_perform;
61
62 ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
63 ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
64 ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
65 ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
66
67 const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
68 const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
69
70 mReqWidth = 0;
71 mReqHeight = 0;
72 mReqFormat = 0;
73 mReqUsage = 0;
74 mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -080075 mDataSpace = HAL_DATASPACE_UNKNOWN;
Mathias Agopiane3c697f2013-02-14 17:11:02 -080076 mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
77 mTransform = 0;
Ruben Brunk1681d952014-06-27 15:51:55 -070078 mStickyTransform = 0;
Mathias Agopiane3c697f2013-02-14 17:11:02 -080079 mDefaultWidth = 0;
80 mDefaultHeight = 0;
81 mUserWidth = 0;
82 mUserHeight = 0;
83 mTransformHint = 0;
84 mConsumerRunningBehind = false;
85 mConnectedToCpu = false;
Eino-Ville Talvala7895e902013-08-21 11:53:37 -070086 mProducerControlledByApp = controlledByApp;
Mathias Agopian7cdd7862013-07-18 22:10:56 -070087 mSwapIntervalZero = false;
Mathias Agopian62185b72009-04-16 16:19:50 -070088}
89
Mathias Agopian35ffa6a2013-03-12 18:45:09 -070090Surface::~Surface() {
91 if (mConnectedToCpu) {
92 Surface::disconnect(NATIVE_WINDOW_API_CPU);
93 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -080094}
95
96sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const {
97 return mGraphicBufferProducer;
98}
99
Wonsik Kim0ee14ca2014-03-17 17:46:53 +0900100void Surface::setSidebandStream(const sp<NativeHandle>& stream) {
101 mGraphicBufferProducer->setSidebandStream(stream);
102}
103
Dan Stoza29a3e902014-06-20 13:13:57 -0700104void Surface::allocateBuffers() {
105 uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth;
106 uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight;
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700107 mGraphicBufferProducer->allocateBuffers(reqWidth, reqHeight,
108 mReqFormat, mReqUsage);
Dan Stoza29a3e902014-06-20 13:13:57 -0700109}
110
Dan Stoza812ed062015-06-02 15:45:22 -0700111status_t Surface::setGenerationNumber(uint32_t generation) {
112 status_t result = mGraphicBufferProducer->setGenerationNumber(generation);
113 if (result == NO_ERROR) {
114 mGenerationNumber = generation;
115 }
116 return result;
117}
118
Dan Stoza7dde5992015-05-22 09:51:44 -0700119uint64_t Surface::getNextFrameNumber() const {
Pablo Ceballosbc8c1922016-07-01 14:15:41 -0700120 Mutex::Autolock lock(mMutex);
121 return mNextFrameNumber;
Dan Stoza7dde5992015-05-22 09:51:44 -0700122}
123
Dan Stozac6f30bd2015-06-08 09:32:50 -0700124String8 Surface::getConsumerName() const {
125 return mGraphicBufferProducer->getConsumerName();
126}
127
Dan Stoza127fc632015-06-30 13:43:32 -0700128status_t Surface::setDequeueTimeout(nsecs_t timeout) {
129 return mGraphicBufferProducer->setDequeueTimeout(timeout);
130}
131
Dan Stoza50101d02016-04-07 16:53:23 -0700132status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
John Reck1a61da52016-04-28 13:18:15 -0700133 sp<Fence>* outFence, float outTransformMatrix[16]) {
134 return mGraphicBufferProducer->getLastQueuedBuffer(outBuffer, outFence,
135 outTransformMatrix);
Dan Stoza50101d02016-04-07 16:53:23 -0700136}
137
Pablo Ceballosce796e72016-02-04 19:10:51 -0800138bool Surface::getFrameTimestamps(uint64_t frameNumber, nsecs_t* outPostedTime,
139 nsecs_t* outAcquireTime, nsecs_t* outRefreshStartTime,
140 nsecs_t* outGlCompositionDoneTime, nsecs_t* outDisplayRetireTime,
141 nsecs_t* outReleaseTime) {
142 ATRACE_CALL();
143
144 FrameTimestamps timestamps;
145 bool found = mGraphicBufferProducer->getFrameTimestamps(frameNumber,
146 &timestamps);
147 if (found) {
148 if (outPostedTime) {
149 *outPostedTime = timestamps.postedTime;
150 }
151 if (outAcquireTime) {
152 *outAcquireTime = timestamps.acquireTime;
153 }
154 if (outRefreshStartTime) {
155 *outRefreshStartTime = timestamps.refreshStartTime;
156 }
157 if (outGlCompositionDoneTime) {
158 *outGlCompositionDoneTime = timestamps.glCompositionDoneTime;
159 }
160 if (outDisplayRetireTime) {
161 *outDisplayRetireTime = timestamps.displayRetireTime;
162 }
163 if (outReleaseTime) {
164 *outReleaseTime = timestamps.releaseTime;
165 }
166 return true;
167 }
168 return false;
169}
170
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800171int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
172 Surface* c = getSelf(window);
173 return c->setSwapInterval(interval);
174}
175
176int Surface::hook_dequeueBuffer(ANativeWindow* window,
177 ANativeWindowBuffer** buffer, int* fenceFd) {
178 Surface* c = getSelf(window);
179 return c->dequeueBuffer(buffer, fenceFd);
180}
181
182int Surface::hook_cancelBuffer(ANativeWindow* window,
183 ANativeWindowBuffer* buffer, int fenceFd) {
184 Surface* c = getSelf(window);
185 return c->cancelBuffer(buffer, fenceFd);
186}
187
188int Surface::hook_queueBuffer(ANativeWindow* window,
189 ANativeWindowBuffer* buffer, int fenceFd) {
190 Surface* c = getSelf(window);
191 return c->queueBuffer(buffer, fenceFd);
192}
193
194int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
195 ANativeWindowBuffer** buffer) {
196 Surface* c = getSelf(window);
197 ANativeWindowBuffer* buf;
198 int fenceFd = -1;
199 int result = c->dequeueBuffer(&buf, &fenceFd);
Mike Stroyan87709c92016-06-03 12:43:26 -0600200 if (result != OK) {
201 return result;
202 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800203 sp<Fence> fence(new Fence(fenceFd));
Mathias Agopianea74d3b2013-05-16 18:03:22 -0700204 int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800205 if (waitResult != OK) {
206 ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d",
207 waitResult);
208 c->cancelBuffer(buf, -1);
209 return waitResult;
Mathias Agopian62185b72009-04-16 16:19:50 -0700210 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800211 *buffer = buf;
212 return result;
Mathias Agopian62185b72009-04-16 16:19:50 -0700213}
214
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800215int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
216 ANativeWindowBuffer* buffer) {
217 Surface* c = getSelf(window);
218 return c->cancelBuffer(buffer, -1);
Mathias Agopian62185b72009-04-16 16:19:50 -0700219}
220
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800221int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
222 ANativeWindowBuffer* buffer) {
223 Surface* c = getSelf(window);
224 return c->lockBuffer_DEPRECATED(buffer);
Mathias Agopian62185b72009-04-16 16:19:50 -0700225}
226
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800227int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
228 ANativeWindowBuffer* buffer) {
229 Surface* c = getSelf(window);
230 return c->queueBuffer(buffer, -1);
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700231}
Mathias Agopian62185b72009-04-16 16:19:50 -0700232
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800233int Surface::hook_query(const ANativeWindow* window,
234 int what, int* value) {
235 const Surface* c = getSelf(window);
236 return c->query(what, value);
237}
238
239int Surface::hook_perform(ANativeWindow* window, int operation, ...) {
240 va_list args;
241 va_start(args, operation);
242 Surface* c = getSelf(window);
Haixia Shid89c2bb2015-09-14 11:02:18 -0700243 int result = c->perform(operation, args);
244 va_end(args);
245 return result;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800246}
247
248int Surface::setSwapInterval(int interval) {
249 ATRACE_CALL();
250 // EGL specification states:
251 // interval is silently clamped to minimum and maximum implementation
252 // dependent values before being stored.
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800253
254 if (interval < minSwapInterval)
255 interval = minSwapInterval;
256
257 if (interval > maxSwapInterval)
258 interval = maxSwapInterval;
259
Mathias Agopian7cdd7862013-07-18 22:10:56 -0700260 mSwapIntervalZero = (interval == 0);
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700261 mGraphicBufferProducer->setAsyncMode(mSwapIntervalZero);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800262
Mathias Agopian7cdd7862013-07-18 22:10:56 -0700263 return NO_ERROR;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800264}
265
Mathias Agopianba93b3f2013-08-01 15:48:40 -0700266int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800267 ATRACE_CALL();
268 ALOGV("Surface::dequeueBuffer");
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800269
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800270 uint32_t reqWidth;
271 uint32_t reqHeight;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800272 PixelFormat reqFormat;
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800273 uint32_t reqUsage;
274
275 {
276 Mutex::Autolock lock(mMutex);
277
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800278 reqWidth = mReqWidth ? mReqWidth : mUserWidth;
279 reqHeight = mReqHeight ? mReqHeight : mUserHeight;
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800280
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800281 reqFormat = mReqFormat;
282 reqUsage = mReqUsage;
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800283
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700284 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot !=
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800285 BufferItem::INVALID_BUFFER_SLOT) {
286 sp<GraphicBuffer>& gbuf(mSlots[mSharedBufferSlot].buffer);
287 if (gbuf != NULL) {
288 *buffer = gbuf.get();
289 *fenceFd = -1;
290 return OK;
291 }
292 }
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800293 } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer
294
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800295 int buf = -1;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800296 sp<Fence> fence;
Dan Stoza70ccba52016-07-01 14:00:40 -0700297 nsecs_t now = systemTime();
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700298 status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800299 reqWidth, reqHeight, reqFormat, reqUsage);
Dan Stoza70ccba52016-07-01 14:00:40 -0700300 mLastDequeueDuration = systemTime() - now;
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800301
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800302 if (result < 0) {
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700303 ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer"
304 "(%d, %d, %d, %d) failed: %d", reqWidth, reqHeight, reqFormat,
305 reqUsage, result);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800306 return result;
Mathias Agopian62185b72009-04-16 16:19:50 -0700307 }
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800308
Dan Stoza90ce2a92017-05-01 16:31:53 -0700309 if (buf < 0 || buf >= NUM_BUFFER_SLOTS) {
310 ALOGE("dequeueBuffer: IGraphicBufferProducer returned invalid slot number %d", buf);
311 android_errorWriteLog(0x534e4554, "36991414"); // SafetyNet logging
312 return FAILED_TRANSACTION;
313 }
314
Igor Murashkin0f1889e2014-02-28 18:44:21 -0800315 Mutex::Autolock lock(mMutex);
316
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800317 sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
Mathias Agopianba93b3f2013-08-01 15:48:40 -0700318
319 // this should never happen
320 ALOGE_IF(fence == NULL, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);
321
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800322 if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
323 freeAllBuffers();
Mathias Agopian579b3f82010-06-08 19:54:15 -0700324 }
Ted Bonkenburgbd050ab2011-07-15 15:10:10 -0700325
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800326 if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
327 result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
328 if (result != NO_ERROR) {
Mathias Agopianba93b3f2013-08-01 15:48:40 -0700329 ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
Jesse Hall9f5a1b62014-10-02 11:09:03 -0700330 mGraphicBufferProducer->cancelBuffer(buf, fence);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800331 return result;
332 }
333 }
Mathias Agopian579b3f82010-06-08 19:54:15 -0700334
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800335 if (fence->isValid()) {
336 *fenceFd = fence->dup();
337 if (*fenceFd == -1) {
338 ALOGE("dequeueBuffer: error duping fence: %d", errno);
339 // dup() should never fail; something is badly wrong. Soldier on
340 // and hope for the best; the worst that should happen is some
341 // visible corruption that lasts until the next frame.
342 }
Ted Bonkenburge5d6eb82011-08-09 22:38:41 -0700343 } else {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800344 *fenceFd = -1;
Mathias Agopiana0c30e92010-06-04 18:26:32 -0700345 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800346
347 *buffer = gbuf.get();
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800348
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700349 if (mSharedBufferMode && mAutoRefresh) {
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800350 mSharedBufferSlot = buf;
351 mSharedBufferHasBeenQueued = false;
352 } else if (mSharedBufferSlot == buf) {
353 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
354 mSharedBufferHasBeenQueued = false;
355 }
356
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800357 return OK;
Jamie Gennisaca4e222010-07-15 17:29:15 -0700358}
359
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800360int Surface::cancelBuffer(android_native_buffer_t* buffer,
361 int fenceFd) {
362 ATRACE_CALL();
363 ALOGV("Surface::cancelBuffer");
364 Mutex::Autolock lock(mMutex);
365 int i = getSlotFromBufferLocked(buffer);
366 if (i < 0) {
Taiju Tsuiki4d0cd3f2015-04-30 22:15:33 +0900367 if (fenceFd >= 0) {
368 close(fenceFd);
369 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800370 return i;
371 }
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800372 if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
373 if (fenceFd >= 0) {
374 close(fenceFd);
375 }
376 return OK;
377 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800378 sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
379 mGraphicBufferProducer->cancelBuffer(i, fence);
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800380
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700381 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800382 mSharedBufferHasBeenQueued = true;
383 }
384
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800385 return OK;
386}
387
388int Surface::getSlotFromBufferLocked(
389 android_native_buffer_t* buffer) const {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800390 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
391 if (mSlots[i].buffer != NULL &&
392 mSlots[i].buffer->handle == buffer->handle) {
393 return i;
Jamie Gennisaca4e222010-07-15 17:29:15 -0700394 }
395 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800396 ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
397 return BAD_VALUE;
Mathias Agopiana0c30e92010-06-04 18:26:32 -0700398}
399
Igor Murashkin7d2d1602013-11-12 18:02:20 -0800400int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800401 ALOGV("Surface::lockBuffer");
402 Mutex::Autolock lock(mMutex);
403 return OK;
404}
Mathias Agopian631f3582010-05-25 17:51:34 -0700405
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800406int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
407 ATRACE_CALL();
408 ALOGV("Surface::queueBuffer");
409 Mutex::Autolock lock(mMutex);
410 int64_t timestamp;
Andy McFadden3c256212013-08-16 14:55:39 -0700411 bool isAutoTimestamp = false;
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800412
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800413 if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
Andy McFadden4b49e082013-08-02 15:31:45 -0700414 timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
Andy McFadden3c256212013-08-16 14:55:39 -0700415 isAutoTimestamp = true;
Andy McFadden4b49e082013-08-02 15:31:45 -0700416 ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
417 timestamp / 1000000.f);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800418 } else {
419 timestamp = mTimestamp;
Mathias Agopian631f3582010-05-25 17:51:34 -0700420 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800421 int i = getSlotFromBufferLocked(buffer);
422 if (i < 0) {
Taiju Tsuiki4d0cd3f2015-04-30 22:15:33 +0900423 if (fenceFd >= 0) {
424 close(fenceFd);
425 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800426 return i;
427 }
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800428 if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
429 if (fenceFd >= 0) {
430 close(fenceFd);
431 }
432 return OK;
433 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800434
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800435
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800436 // Make sure the crop rectangle is entirely inside the buffer.
Pablo Ceballos60d69222015-08-07 14:47:20 -0700437 Rect crop(Rect::EMPTY_RECT);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800438 mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800439
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800440 sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
441 IGraphicBufferProducer::QueueBufferOutput output;
Andy McFadden3c256212013-08-16 14:55:39 -0700442 IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800443 mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform,
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700444 fence, mStickyTransform);
Dan Stoza5065a552015-03-17 16:23:42 -0700445
Dan Stozac62acbd2015-04-21 16:42:49 -0700446 if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) {
Dan Stoza5065a552015-03-17 16:23:42 -0700447 input.setSurfaceDamage(Region::INVALID_REGION);
448 } else {
Dan Stozadb4850c2015-06-25 16:10:18 -0700449 // Here we do two things:
450 // 1) The surface damage was specified using the OpenGL ES convention of
451 // the origin being in the bottom-left corner. Here we flip to the
452 // convention that the rest of the system uses (top-left corner) by
453 // subtracting all top/bottom coordinates from the buffer height.
454 // 2) If the buffer is coming in rotated (for example, because the EGL
455 // implementation is reacting to the transform hint coming back from
456 // SurfaceFlinger), the surface damage needs to be rotated the
457 // opposite direction, since it was generated assuming an unrotated
458 // buffer (the app doesn't know that the EGL implementation is
459 // reacting to the transform hint behind its back). The
460 // transformations in the switch statement below apply those
461 // complementary rotations (e.g., if 90 degrees, rotate 270 degrees).
462
463 int width = buffer->width;
Dan Stoza0e65e6c2015-05-26 13:22:27 -0700464 int height = buffer->height;
Dan Stozadb4850c2015-06-25 16:10:18 -0700465 bool rotated90 = (mTransform ^ mStickyTransform) &
466 NATIVE_WINDOW_TRANSFORM_ROT_90;
467 if (rotated90) {
468 std::swap(width, height);
Dan Stoza0e65e6c2015-05-26 13:22:27 -0700469 }
Dan Stozadb4850c2015-06-25 16:10:18 -0700470
Dan Stoza5065a552015-03-17 16:23:42 -0700471 Region flippedRegion;
472 for (auto rect : mDirtyRegion) {
Dan Stozadb4850c2015-06-25 16:10:18 -0700473 int left = rect.left;
474 int right = rect.right;
475 int top = height - rect.bottom; // Flip from OpenGL convention
476 int bottom = height - rect.top; // Flip from OpenGL convention
477 switch (mTransform ^ mStickyTransform) {
478 case NATIVE_WINDOW_TRANSFORM_ROT_90: {
479 // Rotate 270 degrees
480 Rect flippedRect{top, width - right, bottom, width - left};
481 flippedRegion.orSelf(flippedRect);
482 break;
483 }
484 case NATIVE_WINDOW_TRANSFORM_ROT_180: {
485 // Rotate 180 degrees
486 Rect flippedRect{width - right, height - bottom,
487 width - left, height - top};
488 flippedRegion.orSelf(flippedRect);
489 break;
490 }
491 case NATIVE_WINDOW_TRANSFORM_ROT_270: {
492 // Rotate 90 degrees
493 Rect flippedRect{height - bottom, left,
494 height - top, right};
495 flippedRegion.orSelf(flippedRect);
496 break;
497 }
498 default: {
499 Rect flippedRect{left, top, right, bottom};
500 flippedRegion.orSelf(flippedRect);
501 break;
502 }
503 }
Dan Stoza5065a552015-03-17 16:23:42 -0700504 }
505
506 input.setSurfaceDamage(flippedRegion);
507 }
508
Dan Stoza70ccba52016-07-01 14:00:40 -0700509 nsecs_t now = systemTime();
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800510 status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
Dan Stoza70ccba52016-07-01 14:00:40 -0700511 mLastQueueDuration = systemTime() - now;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800512 if (err != OK) {
513 ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
514 }
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800515
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800516 uint32_t numPendingBuffers = 0;
Ruben Brunk1681d952014-06-27 15:51:55 -0700517 uint32_t hint = 0;
518 output.deflate(&mDefaultWidth, &mDefaultHeight, &hint,
Pablo Ceballosbc8c1922016-07-01 14:15:41 -0700519 &numPendingBuffers, &mNextFrameNumber);
tedbo1e7fa9e2011-06-22 15:52:53 -0700520
Ruben Brunk1681d952014-06-27 15:51:55 -0700521 // Disable transform hint if sticky transform is set.
522 if (mStickyTransform == 0) {
523 mTransformHint = hint;
524 }
525
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800526 mConsumerRunningBehind = (numPendingBuffers >= 2);
Mathias Agopian631f3582010-05-25 17:51:34 -0700527
Dan Stozac62acbd2015-04-21 16:42:49 -0700528 if (!mConnectedToCpu) {
529 // Clear surface damage back to full-buffer
530 mDirtyRegion = Region::INVALID_REGION;
531 }
Dan Stoza5065a552015-03-17 16:23:42 -0700532
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700533 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800534 mSharedBufferHasBeenQueued = true;
535 }
536
Robert Carr9f31e292016-04-11 11:15:32 -0700537 mQueueBufferCondition.broadcast();
538
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800539 return err;
540}
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700541
Mathias Agopiana67932f2011-04-20 14:20:59 -0700542int Surface::query(int what, int* value) const {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800543 ATRACE_CALL();
544 ALOGV("Surface::query");
545 { // scope for the lock
546 Mutex::Autolock lock(mMutex);
547 switch (what) {
548 case NATIVE_WINDOW_FORMAT:
549 if (mReqFormat) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800550 *value = static_cast<int>(mReqFormat);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800551 return NO_ERROR;
552 }
553 break;
554 case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
555 sp<ISurfaceComposer> composer(
556 ComposerService::getComposerService());
557 if (composer->authenticateSurfaceTexture(mGraphicBufferProducer)) {
558 *value = 1;
559 } else {
560 *value = 0;
561 }
562 return NO_ERROR;
563 }
564 case NATIVE_WINDOW_CONCRETE_TYPE:
565 *value = NATIVE_WINDOW_SURFACE;
566 return NO_ERROR;
567 case NATIVE_WINDOW_DEFAULT_WIDTH:
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800568 *value = static_cast<int>(
569 mUserWidth ? mUserWidth : mDefaultWidth);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800570 return NO_ERROR;
571 case NATIVE_WINDOW_DEFAULT_HEIGHT:
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800572 *value = static_cast<int>(
573 mUserHeight ? mUserHeight : mDefaultHeight);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800574 return NO_ERROR;
575 case NATIVE_WINDOW_TRANSFORM_HINT:
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800576 *value = static_cast<int>(mTransformHint);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800577 return NO_ERROR;
578 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
579 status_t err = NO_ERROR;
580 if (!mConsumerRunningBehind) {
581 *value = 0;
582 } else {
583 err = mGraphicBufferProducer->query(what, value);
584 if (err == NO_ERROR) {
585 mConsumerRunningBehind = *value;
586 }
587 }
588 return err;
589 }
Dan Stoza70ccba52016-07-01 14:00:40 -0700590 case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: {
591 int64_t durationUs = mLastDequeueDuration / 1000;
592 *value = durationUs > std::numeric_limits<int>::max() ?
593 std::numeric_limits<int>::max() :
594 static_cast<int>(durationUs);
595 return NO_ERROR;
596 }
597 case NATIVE_WINDOW_LAST_QUEUE_DURATION: {
598 int64_t durationUs = mLastQueueDuration / 1000;
599 *value = durationUs > std::numeric_limits<int>::max() ?
600 std::numeric_limits<int>::max() :
601 static_cast<int>(durationUs);
602 return NO_ERROR;
603 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800604 }
Jamie Gennis391bbe22011-03-14 15:00:06 -0700605 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800606 return mGraphicBufferProducer->query(what, value);
Eino-Ville Talvala1d01a122011-02-18 11:02:42 -0800607}
608
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800609int Surface::perform(int operation, va_list args)
610{
611 int res = NO_ERROR;
612 switch (operation) {
613 case NATIVE_WINDOW_CONNECT:
614 // deprecated. must return NO_ERROR.
615 break;
616 case NATIVE_WINDOW_DISCONNECT:
617 // deprecated. must return NO_ERROR.
618 break;
619 case NATIVE_WINDOW_SET_USAGE:
620 res = dispatchSetUsage(args);
621 break;
622 case NATIVE_WINDOW_SET_CROP:
623 res = dispatchSetCrop(args);
624 break;
625 case NATIVE_WINDOW_SET_BUFFER_COUNT:
626 res = dispatchSetBufferCount(args);
627 break;
628 case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
629 res = dispatchSetBuffersGeometry(args);
630 break;
631 case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
632 res = dispatchSetBuffersTransform(args);
633 break;
Ruben Brunk1681d952014-06-27 15:51:55 -0700634 case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM:
635 res = dispatchSetBuffersStickyTransform(args);
636 break;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800637 case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
638 res = dispatchSetBuffersTimestamp(args);
639 break;
640 case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
641 res = dispatchSetBuffersDimensions(args);
642 break;
643 case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
644 res = dispatchSetBuffersUserDimensions(args);
645 break;
646 case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
647 res = dispatchSetBuffersFormat(args);
648 break;
649 case NATIVE_WINDOW_LOCK:
650 res = dispatchLock(args);
651 break;
652 case NATIVE_WINDOW_UNLOCK_AND_POST:
653 res = dispatchUnlockAndPost(args);
654 break;
655 case NATIVE_WINDOW_SET_SCALING_MODE:
656 res = dispatchSetScalingMode(args);
657 break;
658 case NATIVE_WINDOW_API_CONNECT:
659 res = dispatchConnect(args);
660 break;
661 case NATIVE_WINDOW_API_DISCONNECT:
662 res = dispatchDisconnect(args);
663 break;
Rachad7cb0d392014-07-29 17:53:53 -0700664 case NATIVE_WINDOW_SET_SIDEBAND_STREAM:
665 res = dispatchSetSidebandStream(args);
666 break;
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800667 case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
668 res = dispatchSetBuffersDataSpace(args);
669 break;
Dan Stoza5065a552015-03-17 16:23:42 -0700670 case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
671 res = dispatchSetSurfaceDamage(args);
672 break;
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700673 case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE:
674 res = dispatchSetSharedBufferMode(args);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700675 break;
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800676 case NATIVE_WINDOW_SET_AUTO_REFRESH:
677 res = dispatchSetAutoRefresh(args);
678 break;
Pablo Ceballosce796e72016-02-04 19:10:51 -0800679 case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS:
680 res = dispatchGetFrameTimestamps(args);
681 break;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800682 default:
683 res = NAME_NOT_FOUND;
684 break;
685 }
686 return res;
687}
Mathias Agopiana138f892010-05-21 17:24:35 -0700688
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800689int Surface::dispatchConnect(va_list args) {
690 int api = va_arg(args, int);
691 return connect(api);
692}
Mathias Agopian55fa2512010-03-11 15:06:54 -0800693
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800694int Surface::dispatchDisconnect(va_list args) {
695 int api = va_arg(args, int);
696 return disconnect(api);
697}
698
699int Surface::dispatchSetUsage(va_list args) {
700 int usage = va_arg(args, int);
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800701 return setUsage(static_cast<uint32_t>(usage));
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800702}
703
704int Surface::dispatchSetCrop(va_list args) {
705 android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
706 return setCrop(reinterpret_cast<Rect const*>(rect));
707}
708
709int Surface::dispatchSetBufferCount(va_list args) {
710 size_t bufferCount = va_arg(args, size_t);
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800711 return setBufferCount(static_cast<int32_t>(bufferCount));
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800712}
713
714int Surface::dispatchSetBuffersGeometry(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800715 uint32_t width = va_arg(args, uint32_t);
716 uint32_t height = va_arg(args, uint32_t);
717 PixelFormat format = va_arg(args, PixelFormat);
718 int err = setBuffersDimensions(width, height);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800719 if (err != 0) {
720 return err;
721 }
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800722 return setBuffersFormat(format);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800723}
724
725int Surface::dispatchSetBuffersDimensions(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800726 uint32_t width = va_arg(args, uint32_t);
727 uint32_t height = va_arg(args, uint32_t);
728 return setBuffersDimensions(width, height);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800729}
730
731int Surface::dispatchSetBuffersUserDimensions(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800732 uint32_t width = va_arg(args, uint32_t);
733 uint32_t height = va_arg(args, uint32_t);
734 return setBuffersUserDimensions(width, height);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800735}
736
737int Surface::dispatchSetBuffersFormat(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800738 PixelFormat format = va_arg(args, PixelFormat);
739 return setBuffersFormat(format);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800740}
741
742int Surface::dispatchSetScalingMode(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800743 int mode = va_arg(args, int);
744 return setScalingMode(mode);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800745}
746
747int Surface::dispatchSetBuffersTransform(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800748 uint32_t transform = va_arg(args, uint32_t);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800749 return setBuffersTransform(transform);
750}
751
Ruben Brunk1681d952014-06-27 15:51:55 -0700752int Surface::dispatchSetBuffersStickyTransform(va_list args) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800753 uint32_t transform = va_arg(args, uint32_t);
Ruben Brunk1681d952014-06-27 15:51:55 -0700754 return setBuffersStickyTransform(transform);
755}
756
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800757int Surface::dispatchSetBuffersTimestamp(va_list args) {
758 int64_t timestamp = va_arg(args, int64_t);
759 return setBuffersTimestamp(timestamp);
760}
761
762int Surface::dispatchLock(va_list args) {
763 ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
764 ARect* inOutDirtyBounds = va_arg(args, ARect*);
765 return lock(outBuffer, inOutDirtyBounds);
766}
767
Igor Murashkin7d2d1602013-11-12 18:02:20 -0800768int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800769 return unlockAndPost();
770}
771
Rachad7cb0d392014-07-29 17:53:53 -0700772int Surface::dispatchSetSidebandStream(va_list args) {
773 native_handle_t* sH = va_arg(args, native_handle_t*);
774 sp<NativeHandle> sidebandHandle = NativeHandle::create(sH, false);
775 setSidebandStream(sidebandHandle);
776 return OK;
777}
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800778
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800779int Surface::dispatchSetBuffersDataSpace(va_list args) {
780 android_dataspace dataspace =
781 static_cast<android_dataspace>(va_arg(args, int));
782 return setBuffersDataSpace(dataspace);
783}
784
Dan Stoza5065a552015-03-17 16:23:42 -0700785int Surface::dispatchSetSurfaceDamage(va_list args) {
786 android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
787 size_t numRects = va_arg(args, size_t);
788 setSurfaceDamage(rects, numRects);
789 return NO_ERROR;
790}
791
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700792int Surface::dispatchSetSharedBufferMode(va_list args) {
793 bool sharedBufferMode = va_arg(args, int);
794 return setSharedBufferMode(sharedBufferMode);
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800795}
796
797int Surface::dispatchSetAutoRefresh(va_list args) {
798 bool autoRefresh = va_arg(args, int);
799 return setAutoRefresh(autoRefresh);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700800}
801
Pablo Ceballosce796e72016-02-04 19:10:51 -0800802int Surface::dispatchGetFrameTimestamps(va_list args) {
803 uint32_t framesAgo = va_arg(args, uint32_t);
804 nsecs_t* outPostedTime = va_arg(args, int64_t*);
805 nsecs_t* outAcquireTime = va_arg(args, int64_t*);
806 nsecs_t* outRefreshStartTime = va_arg(args, int64_t*);
807 nsecs_t* outGlCompositionDoneTime = va_arg(args, int64_t*);
808 nsecs_t* outDisplayRetireTime = va_arg(args, int64_t*);
809 nsecs_t* outReleaseTime = va_arg(args, int64_t*);
810 bool ret = getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo,
811 outPostedTime, outAcquireTime, outRefreshStartTime,
812 outGlCompositionDoneTime, outDisplayRetireTime, outReleaseTime);
813 return ret ? NO_ERROR : BAD_VALUE;
814}
815
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800816int Surface::connect(int api) {
Dan Stoza966b98b2015-03-02 22:12:37 -0800817 static sp<IProducerListener> listener = new DummyProducerListener();
818 return connect(api, listener);
819}
820
821int Surface::connect(int api, const sp<IProducerListener>& listener) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800822 ATRACE_CALL();
823 ALOGV("Surface::connect");
824 Mutex::Autolock lock(mMutex);
825 IGraphicBufferProducer::QueueBufferOutput output;
Dan Stozaf0eaf252014-03-21 13:05:51 -0700826 int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800827 if (err == NO_ERROR) {
828 uint32_t numPendingBuffers = 0;
Ruben Brunk1681d952014-06-27 15:51:55 -0700829 uint32_t hint = 0;
830 output.deflate(&mDefaultWidth, &mDefaultHeight, &hint,
Pablo Ceballosbc8c1922016-07-01 14:15:41 -0700831 &numPendingBuffers, &mNextFrameNumber);
Ruben Brunk1681d952014-06-27 15:51:55 -0700832
833 // Disable transform hint if sticky transform is set.
834 if (mStickyTransform == 0) {
835 mTransformHint = hint;
836 }
837
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800838 mConsumerRunningBehind = (numPendingBuffers >= 2);
839 }
840 if (!err && api == NATIVE_WINDOW_API_CPU) {
841 mConnectedToCpu = true;
Dan Stoza5065a552015-03-17 16:23:42 -0700842 // Clear the dirty region in case we're switching from a non-CPU API
843 mDirtyRegion.clear();
844 } else if (!err) {
845 // Initialize the dirty region for tracking surface damage
846 mDirtyRegion = Region::INVALID_REGION;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800847 }
Dan Stoza5065a552015-03-17 16:23:42 -0700848
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800849 return err;
850}
851
Mathias Agopian365857d2013-09-11 19:35:45 -0700852
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800853int Surface::disconnect(int api) {
854 ATRACE_CALL();
855 ALOGV("Surface::disconnect");
856 Mutex::Autolock lock(mMutex);
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800857 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
858 mSharedBufferHasBeenQueued = false;
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800859 freeAllBuffers();
860 int err = mGraphicBufferProducer->disconnect(api);
861 if (!err) {
862 mReqFormat = 0;
863 mReqWidth = 0;
864 mReqHeight = 0;
865 mReqUsage = 0;
866 mCrop.clear();
867 mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
868 mTransform = 0;
Ruben Brunk1681d952014-06-27 15:51:55 -0700869 mStickyTransform = 0;
870
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800871 if (api == NATIVE_WINDOW_API_CPU) {
872 mConnectedToCpu = false;
873 }
874 }
875 return err;
876}
877
Dan Stozad9c49712015-04-27 11:06:01 -0700878int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
Dan Stoza231832e2015-03-11 11:55:01 -0700879 sp<Fence>* outFence) {
880 ATRACE_CALL();
881 ALOGV("Surface::detachNextBuffer");
882
883 if (outBuffer == NULL || outFence == NULL) {
884 return BAD_VALUE;
885 }
886
887 Mutex::Autolock lock(mMutex);
888
889 sp<GraphicBuffer> buffer(NULL);
890 sp<Fence> fence(NULL);
891 status_t result = mGraphicBufferProducer->detachNextBuffer(
892 &buffer, &fence);
893 if (result != NO_ERROR) {
894 return result;
895 }
896
Dan Stozad9c49712015-04-27 11:06:01 -0700897 *outBuffer = buffer;
Dan Stoza231832e2015-03-11 11:55:01 -0700898 if (fence != NULL && fence->isValid()) {
899 *outFence = fence;
900 } else {
901 *outFence = Fence::NO_FENCE;
902 }
903
Pablo Ceballos23b4abe2016-01-08 12:15:22 -0800904 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
905 if (mSlots[i].buffer != NULL &&
906 mSlots[i].buffer->handle == buffer->handle) {
907 mSlots[i].buffer = NULL;
908 }
909 }
910
Dan Stoza231832e2015-03-11 11:55:01 -0700911 return NO_ERROR;
912}
913
914int Surface::attachBuffer(ANativeWindowBuffer* buffer)
915{
916 ATRACE_CALL();
917 ALOGV("Surface::attachBuffer");
918
919 Mutex::Autolock lock(mMutex);
920
921 sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
Dan Stoza812ed062015-06-02 15:45:22 -0700922 uint32_t priorGeneration = graphicBuffer->mGenerationNumber;
923 graphicBuffer->mGenerationNumber = mGenerationNumber;
Dan Stoza231832e2015-03-11 11:55:01 -0700924 int32_t attachedSlot = -1;
925 status_t result = mGraphicBufferProducer->attachBuffer(
926 &attachedSlot, graphicBuffer);
927 if (result != NO_ERROR) {
928 ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result);
Dan Stoza812ed062015-06-02 15:45:22 -0700929 graphicBuffer->mGenerationNumber = priorGeneration;
Dan Stoza231832e2015-03-11 11:55:01 -0700930 return result;
931 }
932 mSlots[attachedSlot].buffer = graphicBuffer;
933
934 return NO_ERROR;
935}
936
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800937int Surface::setUsage(uint32_t reqUsage)
938{
939 ALOGV("Surface::setUsage");
940 Mutex::Autolock lock(mMutex);
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800941 if (reqUsage != mReqUsage) {
942 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
943 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800944 mReqUsage = reqUsage;
945 return OK;
946}
947
948int Surface::setCrop(Rect const* rect)
949{
950 ATRACE_CALL();
951
Pablo Ceballos60d69222015-08-07 14:47:20 -0700952 Rect realRect(Rect::EMPTY_RECT);
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800953 if (rect == NULL || rect->isEmpty()) {
954 realRect.clear();
955 } else {
956 realRect = *rect;
Mathias Agopian55fa2512010-03-11 15:06:54 -0800957 }
958
Mathias Agopiane3c697f2013-02-14 17:11:02 -0800959 ALOGV("Surface::setCrop rect=[%d %d %d %d]",
960 realRect.left, realRect.top, realRect.right, realRect.bottom);
961
962 Mutex::Autolock lock(mMutex);
963 mCrop = realRect;
964 return NO_ERROR;
965}
966
967int Surface::setBufferCount(int bufferCount)
968{
969 ATRACE_CALL();
970 ALOGV("Surface::setBufferCount");
971 Mutex::Autolock lock(mMutex);
972
Pablo Ceballose5b755a2015-08-13 16:18:19 -0700973 status_t err = NO_ERROR;
974 if (bufferCount == 0) {
975 err = mGraphicBufferProducer->setMaxDequeuedBufferCount(1);
976 } else {
977 int minUndequeuedBuffers = 0;
978 err = mGraphicBufferProducer->query(
979 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers);
980 if (err == NO_ERROR) {
981 err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
982 bufferCount - minUndequeuedBuffers);
983 }
984 }
Mathias Agopian90147262010-01-22 11:47:55 -0800985
Pablo Ceballose5b755a2015-08-13 16:18:19 -0700986 ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
987 bufferCount, strerror(-err));
988
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700989 return err;
990}
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700991
Pablo Ceballosfa455352015-08-12 17:47:47 -0700992int Surface::setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
993 ATRACE_CALL();
994 ALOGV("Surface::setMaxDequeuedBufferCount");
995 Mutex::Autolock lock(mMutex);
996
997 status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
998 maxDequeuedBuffers);
999 ALOGE_IF(err, "IGraphicBufferProducer::setMaxDequeuedBufferCount(%d) "
1000 "returned %s", maxDequeuedBuffers, strerror(-err));
1001
Pablo Ceballosfa455352015-08-12 17:47:47 -07001002 return err;
1003}
1004
1005int Surface::setAsyncMode(bool async) {
1006 ATRACE_CALL();
1007 ALOGV("Surface::setAsyncMode");
1008 Mutex::Autolock lock(mMutex);
1009
1010 status_t err = mGraphicBufferProducer->setAsyncMode(async);
1011 ALOGE_IF(err, "IGraphicBufferProducer::setAsyncMode(%d) returned %s",
1012 async, strerror(-err));
1013
Pablo Ceballosfa455352015-08-12 17:47:47 -07001014 return err;
1015}
1016
Pablo Ceballos3559fbf2016-03-17 15:50:23 -07001017int Surface::setSharedBufferMode(bool sharedBufferMode) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -07001018 ATRACE_CALL();
Pablo Ceballos3559fbf2016-03-17 15:50:23 -07001019 ALOGV("Surface::setSharedBufferMode (%d)", sharedBufferMode);
Pablo Ceballosccdfd602015-10-07 15:05:45 -07001020 Mutex::Autolock lock(mMutex);
1021
Pablo Ceballos3559fbf2016-03-17 15:50:23 -07001022 status_t err = mGraphicBufferProducer->setSharedBufferMode(
1023 sharedBufferMode);
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001024 if (err == NO_ERROR) {
Pablo Ceballos3559fbf2016-03-17 15:50:23 -07001025 mSharedBufferMode = sharedBufferMode;
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001026 }
Pablo Ceballos3559fbf2016-03-17 15:50:23 -07001027 ALOGE_IF(err, "IGraphicBufferProducer::setSharedBufferMode(%d) returned"
1028 "%s", sharedBufferMode, strerror(-err));
Pablo Ceballosccdfd602015-10-07 15:05:45 -07001029
1030 return err;
1031}
1032
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001033int Surface::setAutoRefresh(bool autoRefresh) {
1034 ATRACE_CALL();
1035 ALOGV("Surface::setAutoRefresh (%d)", autoRefresh);
1036 Mutex::Autolock lock(mMutex);
1037
1038 status_t err = mGraphicBufferProducer->setAutoRefresh(autoRefresh);
1039 if (err == NO_ERROR) {
1040 mAutoRefresh = autoRefresh;
1041 }
1042 ALOGE_IF(err, "IGraphicBufferProducer::setAutoRefresh(%d) returned %s",
1043 autoRefresh, strerror(-err));
1044 return err;
1045}
1046
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001047int Surface::setBuffersDimensions(uint32_t width, uint32_t height)
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001048{
1049 ATRACE_CALL();
1050 ALOGV("Surface::setBuffersDimensions");
1051
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001052 if ((width && !height) || (!width && height))
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001053 return BAD_VALUE;
1054
1055 Mutex::Autolock lock(mMutex);
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001056 if (width != mReqWidth || height != mReqHeight) {
1057 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1058 }
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001059 mReqWidth = width;
1060 mReqHeight = height;
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001061 return NO_ERROR;
1062}
1063
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001064int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height)
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001065{
1066 ATRACE_CALL();
1067 ALOGV("Surface::setBuffersUserDimensions");
1068
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001069 if ((width && !height) || (!width && height))
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001070 return BAD_VALUE;
1071
1072 Mutex::Autolock lock(mMutex);
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001073 if (width != mUserWidth || height != mUserHeight) {
1074 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1075 }
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001076 mUserWidth = width;
1077 mUserHeight = height;
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001078 return NO_ERROR;
1079}
1080
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001081int Surface::setBuffersFormat(PixelFormat format)
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001082{
1083 ALOGV("Surface::setBuffersFormat");
1084
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001085 Mutex::Autolock lock(mMutex);
Pablo Ceballosff95aab2016-01-13 17:09:58 -08001086 if (format != mReqFormat) {
1087 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
1088 }
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001089 mReqFormat = format;
1090 return NO_ERROR;
1091}
1092
1093int Surface::setScalingMode(int mode)
1094{
1095 ATRACE_CALL();
1096 ALOGV("Surface::setScalingMode(%d)", mode);
1097
1098 switch (mode) {
1099 case NATIVE_WINDOW_SCALING_MODE_FREEZE:
1100 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
1101 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
Robert Carrc2e77882015-12-16 18:14:03 -08001102 case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001103 break;
1104 default:
1105 ALOGE("unknown scaling mode: %d", mode);
1106 return BAD_VALUE;
1107 }
1108
1109 Mutex::Autolock lock(mMutex);
1110 mScalingMode = mode;
1111 return NO_ERROR;
1112}
1113
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001114int Surface::setBuffersTransform(uint32_t transform)
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001115{
1116 ATRACE_CALL();
1117 ALOGV("Surface::setBuffersTransform");
1118 Mutex::Autolock lock(mMutex);
1119 mTransform = transform;
1120 return NO_ERROR;
1121}
1122
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001123int Surface::setBuffersStickyTransform(uint32_t transform)
Ruben Brunk1681d952014-06-27 15:51:55 -07001124{
1125 ATRACE_CALL();
1126 ALOGV("Surface::setBuffersStickyTransform");
1127 Mutex::Autolock lock(mMutex);
1128 mStickyTransform = transform;
1129 return NO_ERROR;
1130}
1131
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001132int Surface::setBuffersTimestamp(int64_t timestamp)
1133{
1134 ALOGV("Surface::setBuffersTimestamp");
1135 Mutex::Autolock lock(mMutex);
1136 mTimestamp = timestamp;
1137 return NO_ERROR;
1138}
1139
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -08001140int Surface::setBuffersDataSpace(android_dataspace dataSpace)
1141{
1142 ALOGV("Surface::setBuffersDataSpace");
1143 Mutex::Autolock lock(mMutex);
1144 mDataSpace = dataSpace;
1145 return NO_ERROR;
1146}
1147
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001148void Surface::freeAllBuffers() {
1149 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
1150 mSlots[i].buffer = 0;
1151 }
1152}
1153
Dan Stoza5065a552015-03-17 16:23:42 -07001154void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) {
1155 ATRACE_CALL();
1156 ALOGV("Surface::setSurfaceDamage");
1157 Mutex::Autolock lock(mMutex);
1158
Dan Stozac62acbd2015-04-21 16:42:49 -07001159 if (mConnectedToCpu || numRects == 0) {
Dan Stoza5065a552015-03-17 16:23:42 -07001160 mDirtyRegion = Region::INVALID_REGION;
1161 return;
1162 }
1163
1164 mDirtyRegion.clear();
1165 for (size_t r = 0; r < numRects; ++r) {
1166 // We intentionally flip top and bottom here, since because they're
1167 // specified with a bottom-left origin, top > bottom, which fails
1168 // validation in the Region class. We will fix this up when we flip to a
1169 // top-left origin in queueBuffer.
1170 Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top);
1171 mDirtyRegion.orSelf(rect);
1172 }
1173}
1174
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001175// ----------------------------------------------------------------------
1176// the lock/unlock APIs must be used from the same thread
1177
1178static status_t copyBlt(
1179 const sp<GraphicBuffer>& dst,
1180 const sp<GraphicBuffer>& src,
1181 const Region& reg)
1182{
1183 // src and dst with, height and format must be identical. no verification
1184 // is done here.
1185 status_t err;
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001186 uint8_t* src_bits = NULL;
1187 err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(),
1188 reinterpret_cast<void**>(&src_bits));
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001189 ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
1190
1191 uint8_t* dst_bits = NULL;
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001192 err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(),
1193 reinterpret_cast<void**>(&dst_bits));
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001194 ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
1195
1196 Region::const_iterator head(reg.begin());
1197 Region::const_iterator tail(reg.end());
1198 if (head != tail && src_bits && dst_bits) {
1199 const size_t bpp = bytesPerPixel(src->format);
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001200 const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp;
1201 const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp;
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001202
1203 while (head != tail) {
1204 const Rect& r(*head++);
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001205 int32_t h = r.height();
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001206 if (h <= 0) continue;
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001207 size_t size = static_cast<uint32_t>(r.width()) * bpp;
1208 uint8_t const * s = src_bits +
1209 static_cast<uint32_t>(r.left + src->stride * r.top) * bpp;
1210 uint8_t * d = dst_bits +
1211 static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp;
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001212 if (dbpr==sbpr && size==sbpr) {
Dan Stoza3be1c6b2014-11-18 10:24:03 -08001213 size *= static_cast<size_t>(h);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001214 h = 1;
1215 }
1216 do {
1217 memcpy(d, s, size);
1218 d += dbpr;
1219 s += sbpr;
1220 } while (--h > 0);
1221 }
1222 }
1223
1224 if (src_bits)
1225 src->unlock();
1226
1227 if (dst_bits)
1228 dst->unlock();
1229
1230 return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001231}
1232
Mathias Agopiana138f892010-05-21 17:24:35 -07001233// ----------------------------------------------------------------------------
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001234
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001235status_t Surface::lock(
1236 ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
1237{
1238 if (mLockedBuffer != 0) {
1239 ALOGE("Surface::lock failed, already locked");
1240 return INVALID_OPERATION;
1241 }
1242
1243 if (!mConnectedToCpu) {
1244 int err = Surface::connect(NATIVE_WINDOW_API_CPU);
1245 if (err) {
1246 return err;
1247 }
1248 // we're intending to do software rendering from this point
1249 setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
1250 }
1251
1252 ANativeWindowBuffer* out;
1253 int fenceFd = -1;
1254 status_t err = dequeueBuffer(&out, &fenceFd);
1255 ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
1256 if (err == NO_ERROR) {
1257 sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001258 const Rect bounds(backBuffer->width, backBuffer->height);
1259
1260 Region newDirtyRegion;
1261 if (inOutDirtyBounds) {
1262 newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
1263 newDirtyRegion.andSelf(bounds);
1264 } else {
1265 newDirtyRegion.set(bounds);
1266 }
1267
1268 // figure out if we can copy the frontbuffer back
1269 const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
1270 const bool canCopyBack = (frontBuffer != 0 &&
1271 backBuffer->width == frontBuffer->width &&
1272 backBuffer->height == frontBuffer->height &&
1273 backBuffer->format == frontBuffer->format);
1274
1275 if (canCopyBack) {
1276 // copy the area that is invalid and not repainted this round
1277 const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
1278 if (!copyback.isEmpty())
1279 copyBlt(backBuffer, frontBuffer, copyback);
1280 } else {
1281 // if we can't copy-back anything, modify the user's dirty
1282 // region to make sure they redraw the whole buffer
1283 newDirtyRegion.set(bounds);
1284 mDirtyRegion.clear();
1285 Mutex::Autolock lock(mMutex);
1286 for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
1287 mSlots[i].dirtyRegion.clear();
1288 }
1289 }
1290
1291
1292 { // scope for the lock
1293 Mutex::Autolock lock(mMutex);
1294 int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
1295 if (backBufferSlot >= 0) {
1296 Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
1297 mDirtyRegion.subtract(dirtyRegion);
1298 dirtyRegion = newDirtyRegion;
1299 }
1300 }
1301
1302 mDirtyRegion.orSelf(newDirtyRegion);
1303 if (inOutDirtyBounds) {
1304 *inOutDirtyBounds = newDirtyRegion.getBounds();
1305 }
1306
1307 void* vaddr;
Francis Hart8f396012014-04-01 15:30:53 +03001308 status_t res = backBuffer->lockAsync(
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001309 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
Francis Hart8f396012014-04-01 15:30:53 +03001310 newDirtyRegion.bounds(), &vaddr, fenceFd);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001311
1312 ALOGW_IF(res, "failed locking buffer (handle = %p)",
1313 backBuffer->handle);
1314
1315 if (res != 0) {
1316 err = INVALID_OPERATION;
1317 } else {
1318 mLockedBuffer = backBuffer;
1319 outBuffer->width = backBuffer->width;
1320 outBuffer->height = backBuffer->height;
1321 outBuffer->stride = backBuffer->stride;
1322 outBuffer->format = backBuffer->format;
1323 outBuffer->bits = vaddr;
1324 }
1325 }
1326 return err;
1327}
1328
1329status_t Surface::unlockAndPost()
1330{
1331 if (mLockedBuffer == 0) {
1332 ALOGE("Surface::unlockAndPost failed, no locked buffer");
1333 return INVALID_OPERATION;
1334 }
1335
Francis Hart8f396012014-04-01 15:30:53 +03001336 int fd = -1;
1337 status_t err = mLockedBuffer->unlockAsync(&fd);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001338 ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
1339
Francis Hart8f396012014-04-01 15:30:53 +03001340 err = queueBuffer(mLockedBuffer.get(), fd);
Mathias Agopiane3c697f2013-02-14 17:11:02 -08001341 ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
1342 mLockedBuffer->handle, strerror(-err));
1343
1344 mPostedBuffer = mLockedBuffer;
1345 mLockedBuffer = 0;
1346 return err;
1347}
1348
Robert Carr9f31e292016-04-11 11:15:32 -07001349bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) {
1350 Mutex::Autolock lock(mMutex);
Pablo Ceballosbc8c1922016-07-01 14:15:41 -07001351 if (mNextFrameNumber > lastFrame) {
Robert Carr9f31e292016-04-11 11:15:32 -07001352 return true;
1353 }
1354 return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK;
1355}
1356
Pablo Ceballos8e3e92b2016-06-27 17:56:53 -07001357status_t Surface::getUniqueId(uint64_t* outId) const {
1358 Mutex::Autolock lock(mMutex);
1359 return mGraphicBufferProducer->getUniqueId(outId);
1360}
1361
Eino-Ville Talvala88612912016-01-06 12:09:11 -08001362namespace view {
1363
1364status_t Surface::writeToParcel(Parcel* parcel) const {
1365 return writeToParcel(parcel, false);
1366}
1367
1368status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const {
1369 if (parcel == nullptr) return BAD_VALUE;
1370
1371 status_t res = OK;
1372
1373 if (!nameAlreadyWritten) res = parcel->writeString16(name);
1374
1375 if (res == OK) {
1376 res = parcel->writeStrongBinder(
1377 IGraphicBufferProducer::asBinder(graphicBufferProducer));
1378 }
1379 return res;
1380}
1381
1382status_t Surface::readFromParcel(const Parcel* parcel) {
1383 return readFromParcel(parcel, false);
1384}
1385
1386status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) {
1387 if (parcel == nullptr) return BAD_VALUE;
1388
1389 if (!nameAlreadyRead) {
1390 name = readMaybeEmptyString16(parcel);
1391 }
1392
1393 sp<IBinder> binder;
1394
1395 status_t res = parcel->readStrongBinder(&binder);
1396 if (res != OK) return res;
1397
1398 graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder);
1399
1400 return OK;
1401}
1402
1403String16 Surface::readMaybeEmptyString16(const Parcel* parcel) {
1404 size_t len;
1405 const char16_t* str = parcel->readString16Inplace(&len);
1406 if (str != nullptr) {
1407 return String16(str, len);
1408 } else {
1409 return String16();
1410 }
1411}
1412
1413} // namespace view
1414
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001415}; // namespace android