VirtualDisplaySurface.cpp 26 KB

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