Merge "Use implementation-defined format when HWC writes to output buffer" into klp-dev
This commit is contained in:
commit
c5807f90f8
@ -47,7 +47,8 @@ VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
|
|||||||
mHwc(hwc),
|
mHwc(hwc),
|
||||||
mDisplayId(dispId),
|
mDisplayId(dispId),
|
||||||
mDisplayName(name),
|
mDisplayName(name),
|
||||||
mProducerUsage(GRALLOC_USAGE_HW_COMPOSER),
|
mOutputFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED),
|
||||||
|
mOutputUsage(GRALLOC_USAGE_HW_COMPOSER),
|
||||||
mProducerSlotSource(0),
|
mProducerSlotSource(0),
|
||||||
mDbgState(DBG_STATE_IDLE),
|
mDbgState(DBG_STATE_IDLE),
|
||||||
mDbgLastCompositionType(COMPOSITION_UNKNOWN)
|
mDbgLastCompositionType(COMPOSITION_UNKNOWN)
|
||||||
@ -95,13 +96,30 @@ status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
|
|||||||
mDbgState = DBG_STATE_PREPARED;
|
mDbgState = DBG_STATE_PREPARED;
|
||||||
|
|
||||||
mCompositionType = compositionType;
|
mCompositionType = compositionType;
|
||||||
|
|
||||||
if (mCompositionType != mDbgLastCompositionType) {
|
if (mCompositionType != mDbgLastCompositionType) {
|
||||||
VDS_LOGV("prepareFrame: composition type changed to %s",
|
VDS_LOGV("prepareFrame: composition type changed to %s",
|
||||||
dbgCompositionTypeStr(mCompositionType));
|
dbgCompositionTypeStr(mCompositionType));
|
||||||
mDbgLastCompositionType = mCompositionType;
|
mDbgLastCompositionType = mCompositionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mCompositionType != COMPOSITION_GLES &&
|
||||||
|
(mOutputFormat != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
|
||||||
|
mOutputUsage != GRALLOC_USAGE_HW_COMPOSER)) {
|
||||||
|
// We must have just switched from GLES-only to MIXED or HWC
|
||||||
|
// composition. Stop using the format and usage requested by the GLES
|
||||||
|
// driver; they may be suboptimal when HWC is writing to the output
|
||||||
|
// buffer. For example, if the output is going to a video encoder, and
|
||||||
|
// HWC can write directly to YUV, some hardware can skip a
|
||||||
|
// memory-to-memory RGB-to-YUV conversion step.
|
||||||
|
//
|
||||||
|
// If we just switched *to* GLES-only mode, we'll change the
|
||||||
|
// format/usage and get a new buffer when the GLES driver calls
|
||||||
|
// dequeueBuffer().
|
||||||
|
mOutputFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
|
||||||
|
mOutputUsage = GRALLOC_USAGE_HW_COMPOSER;
|
||||||
|
refreshOutputBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,12 +230,12 @@ status_t VirtualDisplaySurface::setBufferCount(int bufferCount) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t VirtualDisplaySurface::dequeueBuffer(Source source,
|
status_t VirtualDisplaySurface::dequeueBuffer(Source source,
|
||||||
uint32_t format, int* sslot, sp<Fence>* fence) {
|
uint32_t format, uint32_t usage, int* sslot, sp<Fence>* fence) {
|
||||||
// Don't let a slow consumer block us
|
// Don't let a slow consumer block us
|
||||||
bool async = (source == SOURCE_SINK);
|
bool async = (source == SOURCE_SINK);
|
||||||
|
|
||||||
status_t result = mSource[source]->dequeueBuffer(sslot, fence, async,
|
status_t result = mSource[source]->dequeueBuffer(sslot, fence, async,
|
||||||
mSinkBufferWidth, mSinkBufferHeight, format, mProducerUsage);
|
mSinkBufferWidth, mSinkBufferHeight, format, usage);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
int pslot = mapSource2ProducerSlot(source, *sslot);
|
int pslot = mapSource2ProducerSlot(source, *sslot);
|
||||||
@ -258,7 +276,6 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, bool
|
|||||||
VDS_LOGV("dequeueBuffer %dx%d fmt=%d usage=%#x", w, h, format, usage);
|
VDS_LOGV("dequeueBuffer %dx%d fmt=%d usage=%#x", w, h, format, usage);
|
||||||
|
|
||||||
status_t result = NO_ERROR;
|
status_t result = NO_ERROR;
|
||||||
mProducerUsage = usage | GRALLOC_USAGE_HW_COMPOSER;
|
|
||||||
Source source = fbSourceForCompositionType(mCompositionType);
|
Source source = fbSourceForCompositionType(mCompositionType);
|
||||||
|
|
||||||
if (source == SOURCE_SINK) {
|
if (source == SOURCE_SINK) {
|
||||||
@ -279,13 +296,20 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, bool
|
|||||||
// prepare and set, but since we're in GLES-only mode already it
|
// prepare and set, but since we're in GLES-only mode already it
|
||||||
// shouldn't matter.
|
// shouldn't matter.
|
||||||
|
|
||||||
|
usage |= GRALLOC_USAGE_HW_COMPOSER;
|
||||||
const sp<GraphicBuffer>& buf = mProducerBuffers[mOutputProducerSlot];
|
const sp<GraphicBuffer>& buf = mProducerBuffers[mOutputProducerSlot];
|
||||||
if ((mProducerUsage & ~buf->getUsage()) != 0 ||
|
if ((usage & ~buf->getUsage()) != 0 ||
|
||||||
(format != 0 && format != (uint32_t)buf->getPixelFormat()) ||
|
(format != 0 && format != (uint32_t)buf->getPixelFormat()) ||
|
||||||
(w != 0 && w != mSinkBufferWidth) ||
|
(w != 0 && w != mSinkBufferWidth) ||
|
||||||
(h != 0 && h != mSinkBufferHeight)) {
|
(h != 0 && h != mSinkBufferHeight)) {
|
||||||
VDS_LOGV("dequeueBuffer: output buffer doesn't satisfy GLES "
|
VDS_LOGV("dequeueBuffer: dequeueing new output buffer: "
|
||||||
"request, getting a new buffer");
|
"want %dx%d fmt=%d use=%#x, "
|
||||||
|
"have %dx%d fmt=%d use=%#x",
|
||||||
|
w, h, format, usage,
|
||||||
|
mSinkBufferWidth, mSinkBufferHeight,
|
||||||
|
buf->getPixelFormat(), buf->getUsage());
|
||||||
|
mOutputFormat = format;
|
||||||
|
mOutputUsage = usage;
|
||||||
result = refreshOutputBuffer();
|
result = refreshOutputBuffer();
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
@ -297,7 +321,7 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, bool
|
|||||||
*fence = mOutputFence;
|
*fence = mOutputFence;
|
||||||
} else {
|
} else {
|
||||||
int sslot;
|
int sslot;
|
||||||
result = dequeueBuffer(source, format, &sslot, fence);
|
result = dequeueBuffer(source, format, usage, &sslot, fence);
|
||||||
if (result >= 0) {
|
if (result >= 0) {
|
||||||
*pslot = mapSource2ProducerSlot(source, sslot);
|
*pslot = mapSource2ProducerSlot(source, sslot);
|
||||||
}
|
}
|
||||||
@ -414,7 +438,8 @@ status_t VirtualDisplaySurface::refreshOutputBuffer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int sslot;
|
int sslot;
|
||||||
status_t result = dequeueBuffer(SOURCE_SINK, 0, &sslot, &mOutputFence);
|
status_t result = dequeueBuffer(SOURCE_SINK, mOutputFormat, mOutputUsage,
|
||||||
|
&sslot, &mOutputFence);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
mOutputProducerSlot = mapSource2ProducerSlot(SOURCE_SINK, sslot);
|
mOutputProducerSlot = mapSource2ProducerSlot(SOURCE_SINK, sslot);
|
||||||
|
@ -110,7 +110,7 @@ private:
|
|||||||
// Utility methods
|
// Utility methods
|
||||||
//
|
//
|
||||||
static Source fbSourceForCompositionType(CompositionType type);
|
static Source fbSourceForCompositionType(CompositionType type);
|
||||||
status_t dequeueBuffer(Source source, uint32_t format,
|
status_t dequeueBuffer(Source source, uint32_t format, uint32_t usage,
|
||||||
int* sslot, sp<Fence>* fence);
|
int* sslot, sp<Fence>* fence);
|
||||||
void updateQueueBufferOutput(const QueueBufferOutput& qbo);
|
void updateQueueBufferOutput(const QueueBufferOutput& qbo);
|
||||||
void resetPerFrameState();
|
void resetPerFrameState();
|
||||||
@ -137,10 +137,12 @@ private:
|
|||||||
// Inter-frame state
|
// Inter-frame state
|
||||||
//
|
//
|
||||||
|
|
||||||
// To avoid buffer reallocations, we track the buffer usage requested by
|
// To avoid buffer reallocations, we track the buffer usage and format
|
||||||
// the GLES driver in dequeueBuffer so we can use the same flags on
|
// we used on the previous frame and use it again on the new frame. If
|
||||||
// HWC-only frames.
|
// the composition type changes or the GLES driver starts requesting
|
||||||
uint32_t mProducerUsage;
|
// different usage/format, we'll get a new buffer.
|
||||||
|
uint32_t mOutputFormat;
|
||||||
|
uint32_t mOutputUsage;
|
||||||
|
|
||||||
// Since we present a single producer interface to the GLES driver, but
|
// Since we present a single producer interface to the GLES driver, but
|
||||||
// are internally muxing between the sink and scratch producers, we have
|
// are internally muxing between the sink and scratch producers, we have
|
||||||
|
Loading…
Reference in New Issue
Block a user