OSDN Git Service

Treat composition frames with no layers as using GLES composition
[android-x86/frameworks-native.git] / services / surfaceflinger / DisplayHardware / VirtualDisplaySurface.cpp
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
17 // #define LOG_NDEBUG 0
18 #include "VirtualDisplaySurface.h"
19 #include "HWComposer.h"
20
21 // ---------------------------------------------------------------------------
22 namespace android {
23 // ---------------------------------------------------------------------------
24
25 #define VDS_LOGE(msg, ...) ALOGE("[%s] "msg, \
26         mDisplayName.string(), ##__VA_ARGS__)
27 #define VDS_LOGW_IF(cond, msg, ...) ALOGW_IF(cond, "[%s] "msg, \
28         mDisplayName.string(), ##__VA_ARGS__)
29 #define VDS_LOGV(msg, ...) ALOGV("[%s] "msg, \
30         mDisplayName.string(), ##__VA_ARGS__)
31
32 static const char* dbgCompositionTypeStr(DisplaySurface::CompositionType type) {
33     switch (type) {
34         case DisplaySurface::COMPOSITION_UNKNOWN: return "UNKNOWN";
35         case DisplaySurface::COMPOSITION_GLES:    return "GLES";
36         case DisplaySurface::COMPOSITION_HWC:     return "HWC";
37         case DisplaySurface::COMPOSITION_MIXED:   return "MIXED";
38         default:                                  return "<INVALID>";
39     }
40 }
41
42 VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
43         const sp<IGraphicBufferProducer>& sink,
44         const sp<BufferQueue>& bq,
45         const String8& name)
46 :   ConsumerBase(bq),
47     mHwc(hwc),
48     mDisplayId(dispId),
49     mDisplayName(name),
50     mProducerUsage(GRALLOC_USAGE_HW_COMPOSER),
51     mProducerSlotSource(0),
52     mDbgState(DBG_STATE_IDLE),
53     mDbgLastCompositionType(COMPOSITION_UNKNOWN)
54 {
55     mSource[SOURCE_SINK] = sink;
56     mSource[SOURCE_SCRATCH] = bq;
57
58     resetPerFrameState();
59
60     int sinkWidth, sinkHeight;
61     mSource[SOURCE_SINK]->query(NATIVE_WINDOW_WIDTH, &sinkWidth);
62     mSource[SOURCE_SINK]->query(NATIVE_WINDOW_HEIGHT, &sinkHeight);
63
64     ConsumerBase::mName = String8::format("VDS: %s", mDisplayName.string());
65     mConsumer->setConsumerName(ConsumerBase::mName);
66     mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
67     mConsumer->setDefaultBufferSize(sinkWidth, sinkHeight);
68     mConsumer->setDefaultMaxBufferCount(2);
69 }
70
71 VirtualDisplaySurface::~VirtualDisplaySurface() {
72 }
73
74 status_t VirtualDisplaySurface::beginFrame() {
75     if (mDisplayId < 0)
76         return NO_ERROR;
77
78     VDS_LOGW_IF(mDbgState != DBG_STATE_IDLE,
79             "Unexpected beginFrame() in %s state", dbgStateStr());
80     mDbgState = DBG_STATE_BEGUN;
81
82     uint32_t transformHint, numPendingBuffers;
83     mQueueBufferOutput.deflate(&mSinkBufferWidth, &mSinkBufferHeight,
84             &transformHint, &numPendingBuffers);
85
86     return refreshOutputBuffer();
87 }
88
89 status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
90     if (mDisplayId < 0)
91         return NO_ERROR;
92
93     VDS_LOGW_IF(mDbgState != DBG_STATE_BEGUN,
94             "Unexpected prepareFrame() in %s state", dbgStateStr());
95     mDbgState = DBG_STATE_PREPARED;
96
97     mCompositionType = compositionType;
98
99     if (mCompositionType != mDbgLastCompositionType) {
100         VDS_LOGV("prepareFrame: composition type changed to %s",
101                 dbgCompositionTypeStr(mCompositionType));
102         mDbgLastCompositionType = mCompositionType;
103     }
104
105     return NO_ERROR;
106 }
107
108 status_t VirtualDisplaySurface::compositionComplete() {
109     return NO_ERROR;
110 }
111
112 status_t VirtualDisplaySurface::advanceFrame() {
113     if (mDisplayId < 0)
114         return NO_ERROR;
115
116     if (mCompositionType == COMPOSITION_HWC) {
117         VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED,
118                 "Unexpected advanceFrame() in %s state on HWC frame",
119                 dbgStateStr());
120     } else {
121         VDS_LOGW_IF(mDbgState != DBG_STATE_GLES_DONE,
122                 "Unexpected advanceFrame() in %s state on GLES/MIXED frame",
123                 dbgStateStr());
124     }
125     mDbgState = DBG_STATE_HWC;
126
127     if (mCompositionType == COMPOSITION_HWC) {
128         // Use the output buffer for the FB as well, though conceptually the
129         // FB is unused on this frame.
130         mFbProducerSlot = mOutputProducerSlot;
131         mFbFence = mOutputFence;
132     }
133
134     if (mFbProducerSlot < 0 || mOutputProducerSlot < 0) {
135         // Last chance bailout if something bad happened earlier. For example,
136         // in a GLES configuration, if the sink disappears then dequeueBuffer
137         // will fail, the GLES driver won't queue a buffer, but SurfaceFlinger
138         // will soldier on. So we end up here without a buffer. There should
139         // be lots of scary messages in the log just before this.
140         VDS_LOGE("advanceFrame: no buffer, bailing out");
141         return NO_MEMORY;
142     }
143
144     sp<GraphicBuffer> fbBuffer = mProducerBuffers[mFbProducerSlot];
145     sp<GraphicBuffer> outBuffer = mProducerBuffers[mOutputProducerSlot];
146     VDS_LOGV("advanceFrame: fb=%d(%p) out=%d(%p)",
147             mFbProducerSlot, fbBuffer.get(),
148             mOutputProducerSlot, outBuffer.get());
149
150     return mHwc.fbPost(mDisplayId, mFbFence, fbBuffer);
151 }
152
153 void VirtualDisplaySurface::onFrameCommitted() {
154     if (mDisplayId < 0)
155         return;
156
157     VDS_LOGW_IF(mDbgState != DBG_STATE_HWC,
158             "Unexpected onFrameCommitted() in %s state", dbgStateStr());
159     mDbgState = DBG_STATE_IDLE;
160
161     sp<Fence> fbFence = mHwc.getAndResetReleaseFence(mDisplayId);
162     if (mCompositionType == COMPOSITION_MIXED && mFbProducerSlot >= 0) {
163         // release the scratch buffer back to the pool
164         Mutex::Autolock lock(mMutex);
165         int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, mFbProducerSlot);
166         VDS_LOGV("onFrameCommitted: release scratch sslot=%d", sslot);
167         addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot], fbFence);
168         releaseBufferLocked(sslot, mProducerBuffers[mFbProducerSlot],
169                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
170     }
171
172     if (mOutputProducerSlot >= 0) {
173         int sslot = mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot);
174         QueueBufferOutput qbo;
175         sp<Fence> outFence = mHwc.getLastRetireFence(mDisplayId);
176         VDS_LOGV("onFrameCommitted: queue sink sslot=%d", sslot);
177         status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot,
178                 QueueBufferInput(
179                     systemTime(), false /* isAutoTimestamp */,
180                     Rect(mSinkBufferWidth, mSinkBufferHeight),
181                     NATIVE_WINDOW_SCALING_MODE_FREEZE, 0 /* transform */,
182                     true /* async*/,
183                     outFence),
184                 &qbo);
185         if (result == NO_ERROR) {
186             updateQueueBufferOutput(qbo);
187         }
188     }
189
190     resetPerFrameState();
191 }
192
193 void VirtualDisplaySurface::dump(String8& result) const {
194 }
195
196 status_t VirtualDisplaySurface::requestBuffer(int pslot,
197         sp<GraphicBuffer>* outBuf) {
198     VDS_LOGW_IF(mDbgState != DBG_STATE_GLES,
199             "Unexpected requestBuffer pslot=%d in %s state",
200             pslot, dbgStateStr());
201
202     *outBuf = mProducerBuffers[pslot];
203     return NO_ERROR;
204 }
205
206 status_t VirtualDisplaySurface::setBufferCount(int bufferCount) {
207     return mSource[SOURCE_SINK]->setBufferCount(bufferCount);
208 }
209
210 status_t VirtualDisplaySurface::dequeueBuffer(Source source,
211         uint32_t format, int* sslot, sp<Fence>* fence) {
212     // Don't let a slow consumer block us
213     bool async = (source == SOURCE_SINK);
214
215     status_t result = mSource[source]->dequeueBuffer(sslot, fence, async,
216             mSinkBufferWidth, mSinkBufferHeight, format, mProducerUsage);
217     if (result < 0)
218         return result;
219     int pslot = mapSource2ProducerSlot(source, *sslot);
220     VDS_LOGV("dequeueBuffer(%s): sslot=%d pslot=%d result=%d",
221             dbgSourceStr(source), *sslot, pslot, result);
222     uint32_t sourceBit = static_cast<uint32_t>(source) << pslot;
223
224     if ((mProducerSlotSource & (1u << pslot)) != sourceBit) {
225         // This slot was previously dequeued from the other source; must
226         // re-request the buffer.
227         result |= BUFFER_NEEDS_REALLOCATION;
228         mProducerSlotSource &= ~(1u << pslot);
229         mProducerSlotSource |= sourceBit;
230     }
231
232     if (result & RELEASE_ALL_BUFFERS) {
233         for (uint32_t i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
234             if ((mProducerSlotSource & (1u << i)) == sourceBit)
235                 mProducerBuffers[i].clear();
236         }
237     }
238     if (result & BUFFER_NEEDS_REALLOCATION) {
239         mSource[source]->requestBuffer(*sslot, &mProducerBuffers[pslot]);
240         VDS_LOGV("dequeueBuffer(%s): buffers[%d]=%p",
241                 dbgSourceStr(source), pslot, mProducerBuffers[pslot].get());
242     }
243
244     return result;
245 }
246
247 status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, bool async,
248         uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
249     VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED,
250             "Unexpected dequeueBuffer() in %s state", dbgStateStr());
251     mDbgState = DBG_STATE_GLES;
252
253     VDS_LOGW_IF(!async, "EGL called dequeueBuffer with !async despite eglSwapInterval(0)");
254     VDS_LOGV("dequeueBuffer %dx%d fmt=%d usage=%#x", w, h, format, usage);
255
256     status_t result = NO_ERROR;
257     mProducerUsage = usage | GRALLOC_USAGE_HW_COMPOSER;
258     Source source = fbSourceForCompositionType(mCompositionType);
259
260     if (source == SOURCE_SINK) {
261
262         if (mOutputProducerSlot < 0) {
263             // Last chance bailout if something bad happened earlier. For example,
264             // in a GLES configuration, if the sink disappears then dequeueBuffer
265             // will fail, the GLES driver won't queue a buffer, but SurfaceFlinger
266             // will soldier on. So we end up here without a buffer. There should
267             // be lots of scary messages in the log just before this.
268             VDS_LOGE("dequeueBuffer: no buffer, bailing out");
269             return NO_MEMORY;
270         }
271
272         // We already dequeued the output buffer. If the GLES driver wants
273         // something incompatible, we have to cancel and get a new one. This
274         // will mean that HWC will see a different output buffer between
275         // prepare and set, but since we're in GLES-only mode already it
276         // shouldn't matter.
277
278         const sp<GraphicBuffer>& buf = mProducerBuffers[mOutputProducerSlot];
279         if ((mProducerUsage & ~buf->getUsage()) != 0 ||
280                 (format != 0 && format != (uint32_t)buf->getPixelFormat()) ||
281                 (w != 0 && w != mSinkBufferWidth) ||
282                 (h != 0 && h != mSinkBufferHeight)) {
283             VDS_LOGV("dequeueBuffer: output buffer doesn't satisfy GLES "
284                     "request, getting a new buffer");
285             result = refreshOutputBuffer();
286             if (result < 0)
287                 return result;
288         }
289     }
290
291     if (source == SOURCE_SINK) {
292         *pslot = mOutputProducerSlot;
293         *fence = mOutputFence;
294     } else {
295         int sslot;
296         result = dequeueBuffer(source, format, &sslot, fence);
297         if (result >= 0) {
298             *pslot = mapSource2ProducerSlot(source, sslot);
299         }
300     }
301     return result;
302 }
303
304 status_t VirtualDisplaySurface::queueBuffer(int pslot,
305         const QueueBufferInput& input, QueueBufferOutput* output) {
306     VDS_LOGW_IF(mDbgState != DBG_STATE_GLES,
307             "Unexpected queueBuffer(pslot=%d) in %s state", pslot,
308             dbgStateStr());
309     mDbgState = DBG_STATE_GLES_DONE;
310
311     VDS_LOGV("queueBuffer pslot=%d", pslot);
312
313     status_t result;
314     if (mCompositionType == COMPOSITION_MIXED) {
315         // Queue the buffer back into the scratch pool
316         QueueBufferOutput scratchQBO;
317         int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, pslot);
318         result = mSource[SOURCE_SCRATCH]->queueBuffer(sslot, input, &scratchQBO);
319         if (result != NO_ERROR)
320             return result;
321
322         // Now acquire the buffer from the scratch pool -- should be the same
323         // slot and fence as we just queued.
324         Mutex::Autolock lock(mMutex);
325         BufferQueue::BufferItem item;
326         result = acquireBufferLocked(&item, 0);
327         if (result != NO_ERROR)
328             return result;
329         VDS_LOGW_IF(item.mBuf != sslot,
330                 "queueBuffer: acquired sslot %d from SCRATCH after queueing sslot %d",
331                 item.mBuf, sslot);
332         mFbProducerSlot = mapSource2ProducerSlot(SOURCE_SCRATCH, item.mBuf);
333         mFbFence = mSlots[item.mBuf].mFence;
334
335     } else {
336         LOG_FATAL_IF(mCompositionType != COMPOSITION_GLES,
337                 "Unexpected queueBuffer in state %s for compositionType %s",
338                 dbgStateStr(), dbgCompositionTypeStr(mCompositionType));
339
340         // Extract the GLES release fence for HWC to acquire
341         int64_t timestamp;
342         bool isAutoTimestamp;
343         Rect crop;
344         int scalingMode;
345         uint32_t transform;
346         bool async;
347         input.deflate(&timestamp, &isAutoTimestamp, &crop, &scalingMode,
348                 &transform, &async, &mFbFence);
349
350         mFbProducerSlot = pslot;
351         mOutputFence = mFbFence;
352     }
353
354     *output = mQueueBufferOutput;
355     return NO_ERROR;
356 }
357
358 void VirtualDisplaySurface::cancelBuffer(int pslot, const sp<Fence>& fence) {
359     VDS_LOGW_IF(mDbgState != DBG_STATE_GLES,
360             "Unexpected cancelBuffer(pslot=%d) in %s state", pslot,
361             dbgStateStr());
362     VDS_LOGV("cancelBuffer pslot=%d", pslot);
363     Source source = fbSourceForCompositionType(mCompositionType);
364     return mSource[source]->cancelBuffer(
365             mapProducer2SourceSlot(source, pslot), fence);
366 }
367
368 int VirtualDisplaySurface::query(int what, int* value) {
369     return mSource[SOURCE_SINK]->query(what, value);
370 }
371
372 status_t VirtualDisplaySurface::connect(const sp<IBinder>& token,
373         int api, bool producerControlledByApp,
374         QueueBufferOutput* output) {
375     QueueBufferOutput qbo;
376     status_t result = mSource[SOURCE_SINK]->connect(token, api, producerControlledByApp, &qbo);
377     if (result == NO_ERROR) {
378         updateQueueBufferOutput(qbo);
379         *output = mQueueBufferOutput;
380     }
381     return result;
382 }
383
384 status_t VirtualDisplaySurface::disconnect(int api) {
385     return mSource[SOURCE_SINK]->disconnect(api);
386 }
387
388 void VirtualDisplaySurface::updateQueueBufferOutput(
389         const QueueBufferOutput& qbo) {
390     uint32_t w, h, transformHint, numPendingBuffers;
391     qbo.deflate(&w, &h, &transformHint, &numPendingBuffers);
392     mQueueBufferOutput.inflate(w, h, 0, numPendingBuffers);
393 }
394
395 void VirtualDisplaySurface::resetPerFrameState() {
396     mCompositionType = COMPOSITION_UNKNOWN;
397     mSinkBufferWidth = 0;
398     mSinkBufferHeight = 0;
399     mFbFence = Fence::NO_FENCE;
400     mOutputFence = Fence::NO_FENCE;
401     mFbProducerSlot = -1;
402     mOutputProducerSlot = -1;
403 }
404
405 status_t VirtualDisplaySurface::refreshOutputBuffer() {
406     if (mOutputProducerSlot >= 0) {
407         mSource[SOURCE_SINK]->cancelBuffer(
408                 mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot),
409                 mOutputFence);
410     }
411
412     int sslot;
413     status_t result = dequeueBuffer(SOURCE_SINK, 0, &sslot, &mOutputFence);
414     if (result < 0)
415         return result;
416     mOutputProducerSlot = mapSource2ProducerSlot(SOURCE_SINK, sslot);
417
418     result = mHwc.setOutputBuffer(mDisplayId, mOutputFence,
419             mProducerBuffers[mOutputProducerSlot]);
420
421     return result;
422 }
423
424 // This slot mapping function is its own inverse, so two copies are unnecessary.
425 // Both are kept to make the intent clear where the function is called, and for
426 // the (unlikely) chance that we switch to a different mapping function.
427 int VirtualDisplaySurface::mapSource2ProducerSlot(Source source, int sslot) {
428     if (source == SOURCE_SCRATCH) {
429         return BufferQueue::NUM_BUFFER_SLOTS - sslot - 1;
430     } else {
431         return sslot;
432     }
433 }
434 int VirtualDisplaySurface::mapProducer2SourceSlot(Source source, int pslot) {
435     return mapSource2ProducerSlot(source, pslot);
436 }
437
438 VirtualDisplaySurface::Source
439 VirtualDisplaySurface::fbSourceForCompositionType(CompositionType type) {
440     return type == COMPOSITION_MIXED ? SOURCE_SCRATCH : SOURCE_SINK;
441 }
442
443 const char* VirtualDisplaySurface::dbgStateStr() const {
444     switch (mDbgState) {
445         case DBG_STATE_IDLE:      return "IDLE";
446         case DBG_STATE_PREPARED:  return "PREPARED";
447         case DBG_STATE_GLES:      return "GLES";
448         case DBG_STATE_GLES_DONE: return "GLES_DONE";
449         case DBG_STATE_HWC:       return "HWC";
450         default:                  return "INVALID";
451     }
452 }
453
454 const char* VirtualDisplaySurface::dbgSourceStr(Source s) {
455     switch (s) {
456         case SOURCE_SINK:    return "SINK";
457         case SOURCE_SCRATCH: return "SCRATCH";
458         default:             return "INVALID";
459     }
460 }
461
462 // ---------------------------------------------------------------------------
463 } // namespace android
464 // ---------------------------------------------------------------------------