Allow for resizing of Virtual Displays.
Modify SurfaceFlinger to use VirtualDisplaySurface in all cases when a virtual
display is used. Add functionality in VirtualDisplaySurface to resize the
buffers aquired in the QueueBufferOutput. Add transaction support in
SurfaceFlinger for resize. Add the modification of the size in DisplayDevice.
Change-Id: Iae7e3556dc06fd18d470adbbd76f7255f6e6dd6b
Tested: None
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index ad7cd25..ca04495 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -68,6 +68,8 @@
int sinkWidth, sinkHeight;
sink->query(NATIVE_WINDOW_WIDTH, &sinkWidth);
sink->query(NATIVE_WINDOW_HEIGHT, &sinkHeight);
+ mSinkBufferWidth = sinkWidth;
+ mSinkBufferHeight = sinkHeight;
// Pick the buffer format to request from the sink when not rendering to it
// with GLES. If the consumer needs CPU access, use the default format
@@ -104,10 +106,6 @@
"Unexpected beginFrame() in %s state", dbgStateStr());
mDbgState = DBG_STATE_BEGUN;
- uint32_t transformHint, numPendingBuffers;
- mQueueBufferOutput.deflate(&mSinkBufferWidth, &mSinkBufferHeight,
- &transformHint, &numPendingBuffers);
-
return refreshOutputBuffer();
}
@@ -259,8 +257,20 @@
void VirtualDisplaySurface::dump(String8& /* result */) const {
}
+void VirtualDisplaySurface::resizeBuffers(const uint32_t w, const uint32_t h) {
+ uint32_t tmpW, tmpH, transformHint, numPendingBuffers;
+ mQueueBufferOutput.deflate(&tmpW, &tmpH, &transformHint, &numPendingBuffers);
+ mQueueBufferOutput.inflate(w, h, transformHint, numPendingBuffers);
+
+ mSinkBufferWidth = w;
+ mSinkBufferHeight = h;
+}
+
status_t VirtualDisplaySurface::requestBuffer(int pslot,
sp<GraphicBuffer>* outBuf) {
+ if (mDisplayId < 0)
+ return mSource[SOURCE_SINK]->requestBuffer(pslot, outBuf);
+
VDS_LOGW_IF(mDbgState != DBG_STATE_GLES,
"Unexpected requestBuffer pslot=%d in %s state",
pslot, dbgStateStr());
@@ -275,6 +285,7 @@
status_t VirtualDisplaySurface::dequeueBuffer(Source source,
uint32_t format, uint32_t usage, int* sslot, sp<Fence>* fence) {
+ LOG_FATAL_IF(mDisplayId < 0, "mDisplayId=%d but should not be < 0.", mDisplayId);
// Don't let a slow consumer block us
bool async = (source == SOURCE_SINK);
@@ -319,6 +330,9 @@
status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, bool async,
uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
+ if (mDisplayId < 0)
+ return mSource[SOURCE_SINK]->dequeueBuffer(pslot, fence, async, w, h, format, usage);
+
VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED,
"Unexpected dequeueBuffer() in %s state", dbgStateStr());
mDbgState = DBG_STATE_GLES;
@@ -399,6 +413,9 @@
status_t VirtualDisplaySurface::queueBuffer(int pslot,
const QueueBufferInput& input, QueueBufferOutput* output) {
+ if (mDisplayId < 0)
+ return mSource[SOURCE_SINK]->queueBuffer(pslot, input, output);
+
VDS_LOGW_IF(mDbgState != DBG_STATE_GLES,
"Unexpected queueBuffer(pslot=%d) in %s state", pslot,
dbgStateStr());
@@ -452,6 +469,9 @@
}
void VirtualDisplaySurface::cancelBuffer(int pslot, const sp<Fence>& fence) {
+ if (mDisplayId < 0)
+ return mSource[SOURCE_SINK]->cancelBuffer(mapProducer2SourceSlot(source, pslot), fence);
+
VDS_LOGW_IF(mDbgState != DBG_STATE_GLES,
"Unexpected cancelBuffer(pslot=%d) in %s state", pslot,
dbgStateStr());
@@ -462,7 +482,17 @@
}
int VirtualDisplaySurface::query(int what, int* value) {
- return mSource[SOURCE_SINK]->query(what, value);
+ switch (what) {
+ case NATIVE_WINDOW_WIDTH:
+ *value = mSinkBufferWidth;
+ break;
+ case NATIVE_WINDOW_HEIGHT:
+ *value = mSinkBufferHeight;
+ break;
+ default:
+ return mSource[SOURCE_SINK]->query(what, value);
+ }
+ return NO_ERROR;
}
status_t VirtualDisplaySurface::connect(const sp<IProducerListener>& listener,
@@ -501,8 +531,6 @@
void VirtualDisplaySurface::resetPerFrameState() {
mCompositionType = COMPOSITION_UNKNOWN;
- mSinkBufferWidth = 0;
- mSinkBufferHeight = 0;
mFbFence = Fence::NO_FENCE;
mOutputFence = Fence::NO_FENCE;
mOutputProducerSlot = -1;