VirtualDisplaySurface.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. /*
  2. * Copyright 2013 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. // #define LOG_NDEBUG 0
  17. #include "VirtualDisplaySurface.h"
  18. #include "HWComposer.h"
  19. #include <gui/BufferItem.h>
  20. #include <gui/Surface.h>
  21. // ---------------------------------------------------------------------------
  22. namespace android {
  23. // ---------------------------------------------------------------------------
  24. #if defined(FORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS)
  25. static const bool sForceHwcCopy = true;
  26. #else
  27. static const bool sForceHwcCopy = false;
  28. #endif
  29. #ifndef NUM_FRAMEBUFFER_SURFACE_BUFFERS
  30. #define NUM_FRAMEBUFFER_SURFACE_BUFFERS (2)
  31. #endif
  32. #define VDS_LOGE(msg, ...) ALOGE("[%s] " msg, \
  33. mDisplayName.string(), ##__VA_ARGS__)
  34. #define VDS_LOGW_IF(cond, msg, ...) ALOGW_IF(cond, "[%s] " msg, \
  35. mDisplayName.string(), ##__VA_ARGS__)
  36. #define VDS_LOGV(msg, ...) ALOGV("[%s] " msg, \
  37. mDisplayName.string(), ##__VA_ARGS__)
  38. static const char* dbgCompositionTypeStr(DisplaySurface::CompositionType type) {
  39. switch (type) {
  40. case DisplaySurface::COMPOSITION_UNKNOWN: return "UNKNOWN";
  41. case DisplaySurface::COMPOSITION_GLES: return "GLES";
  42. case DisplaySurface::COMPOSITION_HWC: return "HWC";
  43. case DisplaySurface::COMPOSITION_MIXED: return "MIXED";
  44. default: return "<INVALID>";
  45. }
  46. }
  47. VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
  48. const sp<IGraphicBufferProducer>& sink,
  49. const sp<IGraphicBufferProducer>& bqProducer,
  50. const sp<IGraphicBufferConsumer>& bqConsumer,
  51. const String8& name)
  52. : ConsumerBase(bqConsumer),
  53. mHwc(hwc),
  54. mDisplayId(dispId),
  55. mDisplayName(name),
  56. mOutputUsage(GRALLOC_USAGE_HW_COMPOSER),
  57. mProducerSlotSource(0),
  58. mDbgState(DBG_STATE_IDLE),
  59. mDbgLastCompositionType(COMPOSITION_UNKNOWN),
  60. mMustRecompose(false)
  61. {
  62. mSource[SOURCE_SINK] = sink;
  63. mSource[SOURCE_SCRATCH] = bqProducer;
  64. sp<Surface> surface(new Surface(bqProducer, false));
  65. resetPerFrameState();
  66. int sinkWidth, sinkHeight;
  67. sink->query(NATIVE_WINDOW_WIDTH, &sinkWidth);
  68. sink->query(NATIVE_WINDOW_HEIGHT, &sinkHeight);
  69. mSinkBufferWidth = sinkWidth;
  70. mSinkBufferHeight = sinkHeight;
  71. // Pick the buffer format to request from the sink when not rendering to it
  72. // with GLES. If the consumer needs CPU access, use the default format
  73. // set by the consumer. Otherwise allow gralloc to decide the format based
  74. // on usage bits.
  75. int sinkUsage;
  76. sink->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &sinkUsage);
  77. if (sinkUsage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
  78. int sinkFormat;
  79. sink->query(NATIVE_WINDOW_FORMAT, &sinkFormat);
  80. mDefaultOutputFormat = sinkFormat;
  81. } else {
  82. mDefaultOutputFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
  83. }
  84. mOutputFormat = mDefaultOutputFormat;
  85. ConsumerBase::mName = String8::format("VDS: %s", mDisplayName.string());
  86. mConsumer->setConsumerName(ConsumerBase::mName);
  87. mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
  88. mConsumer->setDefaultBufferSize(sinkWidth, sinkHeight);
  89. mConsumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
  90. surface->allocateBuffers();
  91. }
  92. VirtualDisplaySurface::~VirtualDisplaySurface() {
  93. }
  94. status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) {
  95. if (mDisplayId < 0)
  96. return NO_ERROR;
  97. mMustRecompose = mustRecompose;
  98. VDS_LOGW_IF(mDbgState != DBG_STATE_IDLE,
  99. "Unexpected beginFrame() in %s state", dbgStateStr());
  100. mDbgState = DBG_STATE_BEGUN;
  101. return refreshOutputBuffer();
  102. }
  103. status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
  104. if (mDisplayId < 0)
  105. return NO_ERROR;
  106. VDS_LOGW_IF(mDbgState != DBG_STATE_BEGUN,
  107. "Unexpected prepareFrame() in %s state", dbgStateStr());
  108. mDbgState = DBG_STATE_PREPARED;
  109. mCompositionType = compositionType;
  110. if (sForceHwcCopy && mCompositionType == COMPOSITION_GLES) {
  111. // Some hardware can do RGB->YUV conversion more efficiently in hardware
  112. // controlled by HWC than in hardware controlled by the video encoder.
  113. // Forcing GLES-composed frames to go through an extra copy by the HWC
  114. // allows the format conversion to happen there, rather than passing RGB
  115. // directly to the consumer.
  116. //
  117. // On the other hand, when the consumer prefers RGB or can consume RGB
  118. // inexpensively, this forces an unnecessary copy.
  119. mCompositionType = COMPOSITION_MIXED;
  120. }
  121. if (mCompositionType != mDbgLastCompositionType) {
  122. VDS_LOGV("prepareFrame: composition type changed to %s",
  123. dbgCompositionTypeStr(mCompositionType));
  124. mDbgLastCompositionType = mCompositionType;
  125. }
  126. if (mCompositionType != COMPOSITION_GLES &&
  127. (mOutputFormat != mDefaultOutputFormat ||
  128. mOutputUsage != GRALLOC_USAGE_HW_COMPOSER)) {
  129. // We must have just switched from GLES-only to MIXED or HWC
  130. // composition. Stop using the format and usage requested by the GLES
  131. // driver; they may be suboptimal when HWC is writing to the output
  132. // buffer. For example, if the output is going to a video encoder, and
  133. // HWC can write directly to YUV, some hardware can skip a
  134. // memory-to-memory RGB-to-YUV conversion step.
  135. //
  136. // If we just switched *to* GLES-only mode, we'll change the
  137. // format/usage and get a new buffer when the GLES driver calls
  138. // dequeueBuffer().
  139. mOutputFormat = mDefaultOutputFormat;
  140. setOutputUsage(GRALLOC_USAGE_HW_COMPOSER);
  141. refreshOutputBuffer();
  142. }
  143. return NO_ERROR;
  144. }
  145. status_t VirtualDisplaySurface::compositionComplete() {
  146. return NO_ERROR;
  147. }
  148. status_t VirtualDisplaySurface::advanceFrame() {
  149. if (mDisplayId < 0)
  150. return NO_ERROR;
  151. if (mCompositionType == COMPOSITION_HWC) {
  152. VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED,
  153. "Unexpected advanceFrame() in %s state on HWC frame",
  154. dbgStateStr());
  155. } else {
  156. VDS_LOGW_IF(mDbgState != DBG_STATE_GLES_DONE,
  157. "Unexpected advanceFrame() in %s state on GLES/MIXED frame",
  158. dbgStateStr());
  159. }
  160. mDbgState = DBG_STATE_HWC;
  161. if (mOutputProducerSlot < 0 ||
  162. (mCompositionType != COMPOSITION_HWC && mFbProducerSlot < 0)) {
  163. // Last chance bailout if something bad happened earlier. For example,
  164. // in a GLES configuration, if the sink disappears then dequeueBuffer
  165. // will fail, the GLES driver won't queue a buffer, but SurfaceFlinger
  166. // will soldier on. So we end up here without a buffer. There should
  167. // be lots of scary messages in the log just before this.
  168. VDS_LOGE("advanceFrame: no buffer, bailing out");
  169. return NO_MEMORY;
  170. }
  171. sp<GraphicBuffer> fbBuffer = mFbProducerSlot >= 0 ?
  172. mProducerBuffers[mFbProducerSlot] : sp<GraphicBuffer>(NULL);
  173. sp<GraphicBuffer> outBuffer = mProducerBuffers[mOutputProducerSlot];
  174. VDS_LOGV("advanceFrame: fb=%d(%p) out=%d(%p)",
  175. mFbProducerSlot, fbBuffer.get(),
  176. mOutputProducerSlot, outBuffer.get());
  177. // At this point we know the output buffer acquire fence,
  178. // so update HWC state with it.
  179. mHwc.setOutputBuffer(mDisplayId, mOutputFence, outBuffer);
  180. status_t result = NO_ERROR;
  181. if (fbBuffer != NULL) {
  182. result = mHwc.fbPost(mDisplayId, mFbFence, fbBuffer);
  183. }
  184. return result;
  185. }
  186. void VirtualDisplaySurface::onFrameCommitted() {
  187. if (mDisplayId < 0)
  188. return;
  189. VDS_LOGW_IF(mDbgState != DBG_STATE_HWC,
  190. "Unexpected onFrameCommitted() in %s state", dbgStateStr());
  191. mDbgState = DBG_STATE_IDLE;
  192. sp<Fence> fbFence = mHwc.getAndResetReleaseFence(mDisplayId);
  193. if (mCompositionType == COMPOSITION_MIXED && mFbProducerSlot >= 0) {
  194. // release the scratch buffer back to the pool
  195. Mutex::Autolock lock(mMutex);
  196. int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, mFbProducerSlot);
  197. VDS_LOGV("onFrameCommitted: release scratch sslot=%d", sslot);
  198. addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot], fbFence);
  199. releaseBufferLocked(sslot, mProducerBuffers[mFbProducerSlot],
  200. EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
  201. }
  202. if (mOutputProducerSlot >= 0) {
  203. int sslot = mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot);
  204. QueueBufferOutput qbo;
  205. sp<Fence> outFence = mHwc.getLastRetireFence(mDisplayId);
  206. VDS_LOGV("onFrameCommitted: queue sink sslot=%d", sslot);
  207. if (mMustRecompose) {
  208. status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot,
  209. QueueBufferInput(
  210. systemTime(), false /* isAutoTimestamp */,
  211. HAL_DATASPACE_UNKNOWN,
  212. Rect(mSinkBufferWidth, mSinkBufferHeight),
  213. NATIVE_WINDOW_SCALING_MODE_FREEZE, 0 /* transform */,
  214. true /* async*/,
  215. outFence),
  216. &qbo);
  217. if (result == NO_ERROR) {
  218. updateQueueBufferOutput(qbo);
  219. }
  220. } else {
  221. // If the surface hadn't actually been updated, then we only went
  222. // through the motions of updating the display to keep our state
  223. // machine happy. We cancel the buffer to avoid triggering another
  224. // re-composition and causing an infinite loop.
  225. mSource[SOURCE_SINK]->cancelBuffer(sslot, outFence);
  226. }
  227. }
  228. resetPerFrameState();
  229. }
  230. void VirtualDisplaySurface::dumpAsString(String8& /* result */) const {
  231. }
  232. void VirtualDisplaySurface::resizeBuffers(const uint32_t w, const uint32_t h) {
  233. uint32_t tmpW, tmpH, transformHint, numPendingBuffers;
  234. mQueueBufferOutput.deflate(&tmpW, &tmpH, &transformHint, &numPendingBuffers);
  235. mQueueBufferOutput.inflate(w, h, transformHint, numPendingBuffers);
  236. mSinkBufferWidth = w;
  237. mSinkBufferHeight = h;
  238. }
  239. status_t VirtualDisplaySurface::requestBuffer(int pslot,
  240. sp<GraphicBuffer>* outBuf) {
  241. if (mDisplayId < 0)
  242. return mSource[SOURCE_SINK]->requestBuffer(pslot, outBuf);
  243. VDS_LOGW_IF(mDbgState != DBG_STATE_GLES,
  244. "Unexpected requestBuffer pslot=%d in %s state",
  245. pslot, dbgStateStr());
  246. *outBuf = mProducerBuffers[pslot];
  247. return NO_ERROR;
  248. }
  249. status_t VirtualDisplaySurface::setBufferCount(int bufferCount) {
  250. return mSource[SOURCE_SINK]->setBufferCount(bufferCount);
  251. }
  252. status_t VirtualDisplaySurface::dequeueBuffer(Source source,
  253. PixelFormat format, uint32_t usage, int* sslot, sp<Fence>* fence) {
  254. LOG_FATAL_IF(mDisplayId < 0, "mDisplayId=%d but should not be < 0.", mDisplayId);
  255. // Don't let a slow consumer block us
  256. bool async = (source == SOURCE_SINK);
  257. status_t result = mSource[source]->dequeueBuffer(sslot, fence, async,
  258. mSinkBufferWidth, mSinkBufferHeight, format, usage);
  259. if (result < 0)
  260. return result;
  261. int pslot = mapSource2ProducerSlot(source, *sslot);
  262. VDS_LOGV("dequeueBuffer(%s): sslot=%d pslot=%d result=%d",
  263. dbgSourceStr(source), *sslot, pslot, result);
  264. uint64_t sourceBit = static_cast<uint64_t>(source) << pslot;
  265. if ((mProducerSlotSource & (1ULL << pslot)) != sourceBit) {
  266. // This slot was previously dequeued from the other source; must
  267. // re-request the buffer.
  268. result |= BUFFER_NEEDS_REALLOCATION;
  269. mProducerSlotSource &= ~(1ULL << pslot);
  270. mProducerSlotSource |= sourceBit;
  271. }
  272. if (result & RELEASE_ALL_BUFFERS) {
  273. for (uint32_t i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
  274. if ((mProducerSlotSource & (1ULL << i)) == sourceBit)
  275. mProducerBuffers[i].clear();
  276. }
  277. }
  278. if (result & BUFFER_NEEDS_REALLOCATION) {
  279. result = mSource[source]->requestBuffer(*sslot, &mProducerBuffers[pslot]);
  280. if (result < 0) {
  281. mProducerBuffers[pslot].clear();
  282. mSource[source]->cancelBuffer(*sslot, *fence);
  283. return result;
  284. }
  285. VDS_LOGV("dequeueBuffer(%s): buffers[%d]=%p fmt=%d usage=%#x",
  286. dbgSourceStr(source), pslot, mProducerBuffers[pslot].get(),
  287. mProducerBuffers[pslot]->getPixelFormat(),
  288. mProducerBuffers[pslot]->getUsage());
  289. }
  290. return result;
  291. }
  292. status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, bool async,
  293. uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) {
  294. if (mDisplayId < 0)
  295. return mSource[SOURCE_SINK]->dequeueBuffer(pslot, fence, async, w, h, format, usage);
  296. VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED,
  297. "Unexpected dequeueBuffer() in %s state", dbgStateStr());
  298. mDbgState = DBG_STATE_GLES;
  299. VDS_LOGW_IF(!async, "EGL called dequeueBuffer with !async despite eglSwapInterval(0)");
  300. VDS_LOGV("dequeueBuffer %dx%d fmt=%d usage=%#x", w, h, format, usage);
  301. status_t result = NO_ERROR;
  302. Source source = fbSourceForCompositionType(mCompositionType);
  303. if (source == SOURCE_SINK) {
  304. if (mOutputProducerSlot < 0) {
  305. // Last chance bailout if something bad happened earlier. For example,
  306. // in a GLES configuration, if the sink disappears then dequeueBuffer
  307. // will fail, the GLES driver won't queue a buffer, but SurfaceFlinger
  308. // will soldier on. So we end up here without a buffer. There should
  309. // be lots of scary messages in the log just before this.
  310. VDS_LOGE("dequeueBuffer: no buffer, bailing out");
  311. return NO_MEMORY;
  312. }
  313. // We already dequeued the output buffer. If the GLES driver wants
  314. // something incompatible, we have to cancel and get a new one. This
  315. // will mean that HWC will see a different output buffer between
  316. // prepare and set, but since we're in GLES-only mode already it
  317. // shouldn't matter.
  318. usage |= GRALLOC_USAGE_HW_COMPOSER;
  319. const sp<GraphicBuffer>& buf = mProducerBuffers[mOutputProducerSlot];
  320. if ((usage & ~buf->getUsage()) != 0 ||
  321. (format != 0 && format != buf->getPixelFormat()) ||
  322. (w != 0 && w != mSinkBufferWidth) ||
  323. (h != 0 && h != mSinkBufferHeight)) {
  324. VDS_LOGV("dequeueBuffer: dequeueing new output buffer: "
  325. "want %dx%d fmt=%d use=%#x, "
  326. "have %dx%d fmt=%d use=%#x",
  327. w, h, format, usage,
  328. mSinkBufferWidth, mSinkBufferHeight,
  329. buf->getPixelFormat(), buf->getUsage());
  330. mOutputFormat = format;
  331. setOutputUsage(usage);
  332. result = refreshOutputBuffer();
  333. if (result < 0)
  334. return result;
  335. }
  336. }
  337. if (source == SOURCE_SINK) {
  338. *pslot = mOutputProducerSlot;
  339. *fence = mOutputFence;
  340. } else {
  341. int sslot;
  342. result = dequeueBuffer(source, format, usage, &sslot, fence);
  343. if (result >= 0) {
  344. *pslot = mapSource2ProducerSlot(source, sslot);
  345. }
  346. }
  347. return result;
  348. }
  349. status_t VirtualDisplaySurface::detachBuffer(int /* slot */) {
  350. VDS_LOGE("detachBuffer is not available for VirtualDisplaySurface");
  351. return INVALID_OPERATION;
  352. }
  353. status_t VirtualDisplaySurface::detachNextBuffer(
  354. sp<GraphicBuffer>* /* outBuffer */, sp<Fence>* /* outFence */) {
  355. VDS_LOGE("detachNextBuffer is not available for VirtualDisplaySurface");
  356. return INVALID_OPERATION;
  357. }
  358. status_t VirtualDisplaySurface::attachBuffer(int* /* outSlot */,
  359. const sp<GraphicBuffer>& /* buffer */) {
  360. VDS_LOGE("attachBuffer is not available for VirtualDisplaySurface");
  361. return INVALID_OPERATION;
  362. }
  363. status_t VirtualDisplaySurface::queueBuffer(int pslot,
  364. const QueueBufferInput& input, QueueBufferOutput* output) {
  365. if (mDisplayId < 0)
  366. return mSource[SOURCE_SINK]->queueBuffer(pslot, input, output);
  367. VDS_LOGW_IF(mDbgState != DBG_STATE_GLES,
  368. "Unexpected queueBuffer(pslot=%d) in %s state", pslot,
  369. dbgStateStr());
  370. mDbgState = DBG_STATE_GLES_DONE;
  371. VDS_LOGV("queueBuffer pslot=%d", pslot);
  372. status_t result;
  373. if (mCompositionType == COMPOSITION_MIXED) {
  374. // Queue the buffer back into the scratch pool
  375. QueueBufferOutput scratchQBO;
  376. int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, pslot);
  377. result = mSource[SOURCE_SCRATCH]->queueBuffer(sslot, input, &scratchQBO);
  378. if (result != NO_ERROR)
  379. return result;
  380. // Now acquire the buffer from the scratch pool -- should be the same
  381. // slot and fence as we just queued.
  382. Mutex::Autolock lock(mMutex);
  383. BufferItem item;
  384. result = acquireBufferLocked(&item, 0);
  385. if (result != NO_ERROR)
  386. return result;
  387. VDS_LOGW_IF(item.mBuf != sslot,
  388. "queueBuffer: acquired sslot %d from SCRATCH after queueing sslot %d",
  389. item.mBuf, sslot);
  390. mFbProducerSlot = mapSource2ProducerSlot(SOURCE_SCRATCH, item.mBuf);
  391. mFbFence = mSlots[item.mBuf].mFence;
  392. } else {
  393. LOG_FATAL_IF(mCompositionType != COMPOSITION_GLES,
  394. "Unexpected queueBuffer in state %s for compositionType %s",
  395. dbgStateStr(), dbgCompositionTypeStr(mCompositionType));
  396. // Extract the GLES release fence for HWC to acquire
  397. int64_t timestamp;
  398. bool isAutoTimestamp;
  399. android_dataspace dataSpace;
  400. Rect crop;
  401. int scalingMode;
  402. uint32_t transform;
  403. bool async;
  404. input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop,
  405. &scalingMode, &transform, &async, &mFbFence);
  406. mFbProducerSlot = pslot;
  407. mOutputFence = mFbFence;
  408. }
  409. *output = mQueueBufferOutput;
  410. return NO_ERROR;
  411. }
  412. void VirtualDisplaySurface::cancelBuffer(int pslot, const sp<Fence>& fence) {
  413. if (mDisplayId < 0)
  414. return mSource[SOURCE_SINK]->cancelBuffer(mapProducer2SourceSlot(SOURCE_SINK, pslot), fence);
  415. VDS_LOGW_IF(mDbgState != DBG_STATE_GLES,
  416. "Unexpected cancelBuffer(pslot=%d) in %s state", pslot,
  417. dbgStateStr());
  418. VDS_LOGV("cancelBuffer pslot=%d", pslot);
  419. Source source = fbSourceForCompositionType(mCompositionType);
  420. return mSource[source]->cancelBuffer(
  421. mapProducer2SourceSlot(source, pslot), fence);
  422. }
  423. int VirtualDisplaySurface::query(int what, int* value) {
  424. switch (what) {
  425. case NATIVE_WINDOW_WIDTH:
  426. *value = mSinkBufferWidth;
  427. break;
  428. case NATIVE_WINDOW_HEIGHT:
  429. *value = mSinkBufferHeight;
  430. break;
  431. default:
  432. return mSource[SOURCE_SINK]->query(what, value);
  433. }
  434. return NO_ERROR;
  435. }
  436. status_t VirtualDisplaySurface::connect(const sp<IProducerListener>& listener,
  437. int api, bool producerControlledByApp,
  438. QueueBufferOutput* output) {
  439. QueueBufferOutput qbo;
  440. status_t result = mSource[SOURCE_SINK]->connect(listener, api,
  441. producerControlledByApp, &qbo);
  442. if (result == NO_ERROR) {
  443. updateQueueBufferOutput(qbo);
  444. *output = mQueueBufferOutput;
  445. }
  446. return result;
  447. }
  448. status_t VirtualDisplaySurface::disconnect(int api) {
  449. return mSource[SOURCE_SINK]->disconnect(api);
  450. }
  451. status_t VirtualDisplaySurface::setSidebandStream(const sp<NativeHandle>& /*stream*/) {
  452. return INVALID_OPERATION;
  453. }
  454. void VirtualDisplaySurface::allocateBuffers(bool /* async */,
  455. uint32_t /* width */, uint32_t /* height */, PixelFormat /* format */,
  456. uint32_t /* usage */) {
  457. // TODO: Should we actually allocate buffers for a virtual display?
  458. }
  459. status_t VirtualDisplaySurface::allowAllocation(bool /* allow */) {
  460. return INVALID_OPERATION;
  461. }
  462. status_t VirtualDisplaySurface::setGenerationNumber(uint32_t /* generation */) {
  463. ALOGE("setGenerationNumber not supported on VirtualDisplaySurface");
  464. return INVALID_OPERATION;
  465. }
  466. String8 VirtualDisplaySurface::getConsumerName() const {
  467. return String8("VirtualDisplaySurface");
  468. }
  469. void VirtualDisplaySurface::updateQueueBufferOutput(
  470. const QueueBufferOutput& qbo) {
  471. uint32_t w, h, transformHint, numPendingBuffers;
  472. qbo.deflate(&w, &h, &transformHint, &numPendingBuffers);
  473. mQueueBufferOutput.inflate(w, h, 0, numPendingBuffers);
  474. }
  475. void VirtualDisplaySurface::resetPerFrameState() {
  476. mCompositionType = COMPOSITION_UNKNOWN;
  477. mFbFence = Fence::NO_FENCE;
  478. mOutputFence = Fence::NO_FENCE;
  479. mOutputProducerSlot = -1;
  480. mFbProducerSlot = -1;
  481. }
  482. status_t VirtualDisplaySurface::refreshOutputBuffer() {
  483. if (mOutputProducerSlot >= 0) {
  484. mSource[SOURCE_SINK]->cancelBuffer(
  485. mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot),
  486. mOutputFence);
  487. }
  488. int sslot;
  489. status_t result = dequeueBuffer(SOURCE_SINK, mOutputFormat, mOutputUsage,
  490. &sslot, &mOutputFence);
  491. if (result < 0)
  492. return result;
  493. mOutputProducerSlot = mapSource2ProducerSlot(SOURCE_SINK, sslot);
  494. // On GLES-only frames, we don't have the right output buffer acquire fence
  495. // until after GLES calls queueBuffer(). So here we just set the buffer
  496. // (for use in HWC prepare) but not the fence; we'll call this again with
  497. // the proper fence once we have it.
  498. result = mHwc.setOutputBuffer(mDisplayId, Fence::NO_FENCE,
  499. mProducerBuffers[mOutputProducerSlot]);
  500. return result;
  501. }
  502. // This slot mapping function is its own inverse, so two copies are unnecessary.
  503. // Both are kept to make the intent clear where the function is called, and for
  504. // the (unlikely) chance that we switch to a different mapping function.
  505. int VirtualDisplaySurface::mapSource2ProducerSlot(Source source, int sslot) {
  506. if (source == SOURCE_SCRATCH) {
  507. return BufferQueue::NUM_BUFFER_SLOTS - sslot - 1;
  508. } else {
  509. return sslot;
  510. }
  511. }
  512. int VirtualDisplaySurface::mapProducer2SourceSlot(Source source, int pslot) {
  513. return mapSource2ProducerSlot(source, pslot);
  514. }
  515. VirtualDisplaySurface::Source
  516. VirtualDisplaySurface::fbSourceForCompositionType(CompositionType type) {
  517. return type == COMPOSITION_MIXED ? SOURCE_SCRATCH : SOURCE_SINK;
  518. }
  519. const char* VirtualDisplaySurface::dbgStateStr() const {
  520. switch (mDbgState) {
  521. case DBG_STATE_IDLE: return "IDLE";
  522. case DBG_STATE_PREPARED: return "PREPARED";
  523. case DBG_STATE_GLES: return "GLES";
  524. case DBG_STATE_GLES_DONE: return "GLES_DONE";
  525. case DBG_STATE_HWC: return "HWC";
  526. default: return "INVALID";
  527. }
  528. }
  529. const char* VirtualDisplaySurface::dbgSourceStr(Source s) {
  530. switch (s) {
  531. case SOURCE_SINK: return "SINK";
  532. case SOURCE_SCRATCH: return "SCRATCH";
  533. default: return "INVALID";
  534. }
  535. }
  536. void VirtualDisplaySurface::setOutputUsage(uint32_t usage) {
  537. mOutputUsage = usage;
  538. }
  539. // ---------------------------------------------------------------------------
  540. } // namespace android
  541. // ---------------------------------------------------------------------------