we now correctly set-up connected screens during boot

Change-Id: Ie8b1a3b97ad1821cc970e43abe96c8cec7135b66
This commit is contained in:
Mathias Agopian 2012-09-19 18:16:22 -07:00
parent 148994e5f3
commit f5a3392834
5 changed files with 53 additions and 41 deletions

View File

@ -46,8 +46,9 @@ namespace android {
*
*/
FramebufferSurface::FramebufferSurface(HWComposer& hwc) :
FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp) :
ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())),
mDisplayType(disp),
mCurrentBufferSlot(-1),
mCurrentBuffer(0),
mHwc(hwc)
@ -55,10 +56,10 @@ FramebufferSurface::FramebufferSurface(HWComposer& hwc) :
mName = "FramebufferSurface";
mBufferQueue->setConsumerName(mName);
mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER);
mBufferQueue->setDefaultBufferFormat(mHwc.getFormat(HWC_DISPLAY_PRIMARY));
mBufferQueue->setDefaultBufferSize(mHwc.getWidth(HWC_DISPLAY_PRIMARY),
mHwc.getHeight(HWC_DISPLAY_PRIMARY));
GRALLOC_USAGE_HW_RENDER |
GRALLOC_USAGE_HW_COMPOSER);
mBufferQueue->setDefaultBufferFormat(mHwc.getFormat(disp));
mBufferQueue->setDefaultBufferSize(mHwc.getWidth(disp), mHwc.getHeight(disp));
mBufferQueue->setSynchronousMode(true);
mBufferQueue->setDefaultMaxBufferCount(NUM_FRAME_BUFFERS);
}
@ -111,7 +112,7 @@ void FramebufferSurface::onFrameAvailable() {
strerror(-err), err);
return;
}
err = mHwc.fbPost(0, acquireFence, buf); // FIXME: use real display id
err = mHwc.fbPost(mDisplayType, acquireFence, buf);
if (err != NO_ERROR) {
ALOGE("error posting framebuffer: %d", err);
}

View File

@ -36,7 +36,7 @@ class HWComposer;
class FramebufferSurface : public ConsumerBase {
public:
FramebufferSurface(HWComposer& hwc);
FramebufferSurface(HWComposer& hwc, int disp);
bool isUpdateOnDemand() const { return false; }
status_t setUpdateRectangle(const Rect& updateRect);
@ -63,6 +63,9 @@ private:
// BufferQueue. The new buffer is returned in the 'buffer' argument.
status_t nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence);
// mDisplayType must match one of the HWC display types
int mDisplayType;
// mCurrentBufferIndex is the slot index of the current buffer or
// INVALID_BUFFER_SLOT to indicate that either there is no current buffer
// or the buffer is not associated with a slot.

View File

@ -301,10 +301,7 @@ void HWComposer::hotplug(int disp, int connected) {
disp, connected);
return;
}
if (connected)
queryDisplayProperties(disp);
queryDisplayProperties(disp);
mEventHandler.onHotplugReceived(disp, bool(connected));
}
@ -335,6 +332,7 @@ status_t HWComposer::queryDisplayProperties(int disp) {
status_t err = mHwc->getDisplayConfigs(mHwc, disp, &config, &numConfigs);
if (err != NO_ERROR) {
// this can happen if an unpluggable display is not connected
mDisplayData[disp].connected = false;
return err;
}
@ -365,6 +363,9 @@ status_t HWComposer::queryDisplayProperties(int disp) {
}
}
// FIXME: what should we set the format to?
mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888;
mDisplayData[disp].connected = true;
if (mDisplayData[disp].xdpi == 0.0f || mDisplayData[disp].ydpi == 0.0f) {
// is there anything smarter we can do?
if (h >= 1080) {
@ -432,6 +433,10 @@ float HWComposer::getDpiY(int disp) const {
return mDisplayData[disp].ydpi;
}
bool HWComposer::isConnected(int disp) const {
return mDisplayData[disp].connected;
}
void HWComposer::eventControl(int event, int enabled) {
status_t err = NO_ERROR;
if (mHwc) {
@ -503,9 +508,9 @@ status_t HWComposer::setFramebufferTarget(int32_t id,
// triggers a SurfaceTextureClient::queueBuffer() on some
// devices (!?) -- log and ignore.
ALOGE("HWComposer: framebufferTarget is null");
CallStack stack;
stack.update();
stack.dump("");
// CallStack stack;
// stack.update();
// stack.dump("");
return NO_ERROR;
}

View File

@ -234,6 +234,7 @@ public:
uint32_t getFormat(int disp) const;
float getDpiX(int disp) const;
float getDpiY(int disp) const;
bool isConnected(int disp) const;
// this class is only used to fake the VSync event on systems that don't
// have it.
@ -283,7 +284,7 @@ private:
struct DisplayData {
DisplayData() : xdpi(0), ydpi(0), refresh(0),
hasFbComp(false), hasOvComp(false),
connected(false), hasFbComp(false), hasOvComp(false),
capacity(0), list(NULL),
framebufferTarget(NULL), fbTargetHandle(NULL) { }
~DisplayData() {
@ -295,6 +296,7 @@ private:
float xdpi;
float ydpi;
nsecs_t refresh;
bool connected;
bool hasFbComp;
bool hasOvComp;
size_t capacity;

View File

@ -405,34 +405,35 @@ status_t SurfaceFlinger::readyToRun()
// initialize our non-virtual displays
for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
mDefaultDisplays[i] = new BBinder();
mCurrentState.displays.add(mDefaultDisplays[i],
DisplayDeviceState(DisplayDevice::DisplayType(i)));
wp<IBinder> token = mDefaultDisplays[i];
mCurrentState.displays.add(token, DisplayDeviceState(type));
// set-up the displays that are already connected
if (mHwc->isConnected(i)) {
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i);
sp<SurfaceTextureClient> stc = new SurfaceTextureClient(
static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
sp<DisplayDevice> hw = new DisplayDevice(this,
type, token, stc, fbs, mEGLConfig);
if (i > DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: currently we don't really handle blank/unblank
// for displays other than the main display, so we always
// assume a connected display is unblanked.
hw->acquireScreen();
}
mDisplays.add(token, hw);
}
}
// The main display is a bit special and always exists
//
// if we didn't add it here, it would be added automatically during the
// first transaction, however this would also create some difficulties:
//
// - there would be a race where a client could call getDisplayInfo(),
// for instance before the DisplayDevice is created.
//
// - we need a GL context current in a few places, when initializing
// OpenGL ES (see below), or creating a layer,
// or when a texture is (asynchronously) destroyed, and for that
// we need a valid surface, so it's conveniant to use the main display
// for that.
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc);
sp<SurfaceTextureClient> stc = new SurfaceTextureClient(
static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
sp<DisplayDevice> hw = new DisplayDevice(this,
DisplayDevice::DISPLAY_PRIMARY,
mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY],
stc, fbs, mEGLConfig);
mDisplays.add(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], hw);
// we need a GL context current in a few places, when initializing
// OpenGL ES (see below), or creating a layer,
// or when a texture is (asynchronously) destroyed, and for that
// we need a valid surface, so it's convenient to use the main display
// for that.
sp<const DisplayDevice> hw = getDefaultDisplayDevice();
// initialize OpenGL ES
DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
@ -1076,7 +1077,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
// for supported (by hwc) displays we provide our
// own rendering surface
fbs = new FramebufferSurface(*mHwc);
fbs = new FramebufferSurface(*mHwc, state.type);
stc = new SurfaceTextureClient(
static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
} else {