From 3ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2a Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 27 Aug 2012 16:28:24 -0700 Subject: [PATCH] Eradicate DisplayID. DisplayDevices are now keyed of the wp the client uses. DisplayID has now become DisplayType which is just used to identify physical displays (as opposed to virtual displays such as wifi displays). Change-Id: I0c5968f2c902dcd699a7e0afacf833ff070c12ea --- include/gui/ISurfaceComposerClient.h | 6 - services/surfaceflinger/Client.cpp | 3 +- services/surfaceflinger/DisplayDevice.cpp | 11 +- services/surfaceflinger/DisplayDevice.h | 24 ++-- services/surfaceflinger/EventThread.cpp | 2 +- services/surfaceflinger/EventThread.h | 2 +- services/surfaceflinger/Layer.cpp | 5 +- services/surfaceflinger/Layer.h | 4 +- services/surfaceflinger/LayerBase.cpp | 8 +- services/surfaceflinger/LayerBase.h | 6 +- services/surfaceflinger/LayerDim.cpp | 5 +- services/surfaceflinger/LayerDim.h | 3 +- services/surfaceflinger/LayerScreenshot.cpp | 11 +- services/surfaceflinger/LayerScreenshot.h | 5 +- services/surfaceflinger/SurfaceFlinger.cpp | 145 ++++++++------------ services/surfaceflinger/SurfaceFlinger.h | 40 +++--- 16 files changed, 125 insertions(+), 155 deletions(-) diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h index 39cf09029..e256e3345 100644 --- a/include/gui/ISurfaceComposerClient.h +++ b/include/gui/ISurfaceComposerClient.h @@ -30,12 +30,6 @@ #include namespace android { - -// ---------------------------------------------------------------------------- - -// TODO: Remove this declaration, it is only used internally by SurfaceFlinger. -typedef int32_t DisplayID; - // ---------------------------------------------------------------------------- class ISurfaceComposerClient : public IInterface diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index b0f23305e..c28254f6f 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -140,9 +140,8 @@ sp Client::createSurface( } sp getResult() const { return result; } virtual bool handler() { - // TODO don't require display id to create a layer result = flinger->createLayer(params, name, client, - ISurfaceComposer::eDisplayIdMain, w, h, format, flags); + w, h, format, flags); return true; } }; diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 821a3295c..16e55471a 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -68,12 +68,12 @@ void checkGLErrors() DisplayDevice::DisplayDevice( const sp& flinger, - int32_t display, int32_t hwcDisplayId, + DisplayType type, const wp& displayToken, const sp& nativeWindow, const sp& framebufferSurface, EGLConfig config) : mFlinger(flinger), - mId(display), mHwcDisplayId(hwcDisplayId), + mType(type), mHwcDisplayId(-1), mNativeWindow(nativeWindow), mFramebufferSurface(framebufferSurface), mDisplay(EGL_NO_DISPLAY), @@ -141,7 +141,10 @@ void DisplayDevice::init(EGLConfig config) mPageFlipCount = 0; // external displays are always considered enabled - mScreenAcquired = mId >= DisplayDevice::DISPLAY_ID_COUNT; + mScreenAcquired = (mType >= DisplayDevice::NUM_DISPLAY_TYPES); + + // get an h/w composer ID + mHwcDisplayId = mFlinger->allocateHwcDisplayId(mType); // initialize the display orientation transform. DisplayDevice::setOrientation(DisplayState::eOrientationDefault); @@ -210,7 +213,7 @@ void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp >& lay } } -Vector< sp > DisplayDevice::getVisibleLayersSortedByZ() const { +const Vector< sp >& DisplayDevice::getVisibleLayersSortedByZ() const { return mVisibleLayersSortedByZ; } diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index ea56d90af..b742b1329 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -51,10 +51,12 @@ public: // region in screen space Region undefinedRegion; - enum { - DISPLAY_ID_MAIN = HWC_DISPLAY_PRIMARY, - DISPLAY_ID_HDMI = HWC_DISPLAY_EXTERNAL, - DISPLAY_ID_COUNT = HWC_NUM_DISPLAY_TYPES + enum DisplayType { + DISPLAY_ID_INVALID = -1, + DISPLAY_PRIMARY = HWC_DISPLAY_PRIMARY, + DISPLAY_EXTERNAL = HWC_DISPLAY_EXTERNAL, + NUM_DISPLAY_TYPES = HWC_NUM_DISPLAY_TYPES, + DISPLAY_VIRTUAL = HWC_NUM_DISPLAY_TYPES }; enum { @@ -64,7 +66,7 @@ public: DisplayDevice( const sp& flinger, - int32_t dpy, int32_t hwcDisplayId, + DisplayType type, const wp& displayToken, const sp& nativeWindow, const sp& framebufferSurface, EGLConfig config); @@ -87,7 +89,7 @@ public: EGLSurface getEGLSurface() const; void setVisibleLayersSortedByZ(const Vector< sp >& layers); - Vector< sp > getVisibleLayersSortedByZ() const; + const Vector< sp >& getVisibleLayersSortedByZ() const; bool getSecureLayerVisible() const; Region getDirtyRegion(bool repaintEverything) const; @@ -97,8 +99,9 @@ public: int getOrientation() const { return mOrientation; } const Transform& getTransform() const { return mGlobalTransform; } uint32_t getLayerStack() const { return mLayerStack; } - int32_t getDisplayId() const { return mId; } + int32_t getDisplayType() const { return mType; } int32_t getHwcDisplayId() const { return mHwcDisplayId; } + const wp& getDisplayToken() const { return mDisplayToken; } status_t compositionComplete() const; @@ -123,10 +126,6 @@ public: uint32_t getPageFlipCount() const; void dump(String8& res) const; - inline bool operator < (const DisplayDevice& rhs) const { - return mId < rhs.mId; - } - private: void init(EGLConfig config); @@ -134,8 +133,9 @@ private: * Constants, set during initialization */ sp mFlinger; - int32_t mId; + DisplayType mType; int32_t mHwcDisplayId; + wp mDisplayToken; // ANativeWindow this display is rendering into sp mNativeWindow; diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp index a39b7d8c5..dcda67ef1 100644 --- a/services/surfaceflinger/EventThread.cpp +++ b/services/surfaceflinger/EventThread.cpp @@ -106,7 +106,7 @@ void EventThread::onScreenAcquired() { } -void EventThread::onVSyncReceived(int, nsecs_t timestamp) { +void EventThread::onVSyncReceived(const wp&, nsecs_t timestamp) { Mutex::Autolock _l(mLock); mVSyncTimestamp = timestamp; mVSyncCount++; diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h index 20ea34d36..c8bb312cd 100644 --- a/services/surfaceflinger/EventThread.h +++ b/services/surfaceflinger/EventThread.h @@ -76,7 +76,7 @@ public: void onScreenAcquired(); // called when receiving a vsync event - void onVSyncReceived(int display, nsecs_t timestamp); + void onVSyncReceived(const wp& display, nsecs_t timestamp); Vector< sp > waitForEvent( DisplayEventReceiver::Event* event); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 0825ec6f6..4c82f91b1 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -50,9 +50,8 @@ namespace android { // --------------------------------------------------------------------------- -Layer::Layer(SurfaceFlinger* flinger, - DisplayID display, const sp& client) - : LayerBaseClient(flinger, display, client), +Layer::Layer(SurfaceFlinger* flinger, const sp& client) + : LayerBaseClient(flinger, client), mTextureName(-1U), mQueuedFrames(0), mCurrentTransform(0), diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index d24013b47..78fe32122 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -50,9 +50,7 @@ class GLExtensions; class Layer : public LayerBaseClient { public: - Layer(SurfaceFlinger* flinger, DisplayID display, - const sp& client); - + Layer(SurfaceFlinger* flinger, const sp& client); virtual ~Layer(); virtual const char* getTypeId() const { return "Layer"; } diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp index 2311e6db4..a2513a2c0 100644 --- a/services/surfaceflinger/LayerBase.cpp +++ b/services/surfaceflinger/LayerBase.cpp @@ -41,8 +41,8 @@ namespace android { int32_t LayerBase::sSequence = 1; -LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) - : dpy(display), contentDirty(false), +LayerBase::LayerBase(SurfaceFlinger* flinger) + : contentDirty(false), sequence(uint32_t(android_atomic_inc(&sSequence))), mFlinger(flinger), mFiltering(false), mNeedsFiltering(false), @@ -461,9 +461,9 @@ sp LayerBase::getLayer() const { int32_t LayerBaseClient::sIdentity = 1; -LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, +LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, const sp& client) - : LayerBase(flinger, display), + : LayerBase(flinger), mHasSurface(false), mClientRef(client), mIdentity(uint32_t(android_atomic_inc(&sIdentity))) diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h index 6394542d4..c18f397c3 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -54,9 +54,8 @@ class LayerBase : public RefBase static int32_t sSequence; public: - LayerBase(SurfaceFlinger* flinger, DisplayID display); + LayerBase(SurfaceFlinger* flinger); - DisplayID dpy; mutable bool contentDirty; // regions below are in window-manager space Region visibleRegion; @@ -293,8 +292,7 @@ private: class LayerBaseClient : public LayerBase { public: - LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, - const sp& client); + LayerBaseClient(SurfaceFlinger* flinger, const sp& client); virtual ~LayerBaseClient(); diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp index 087d85168..25caa0a6d 100644 --- a/services/surfaceflinger/LayerDim.cpp +++ b/services/surfaceflinger/LayerDim.cpp @@ -33,9 +33,8 @@ namespace android { // --------------------------------------------------------------------------- -LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display, - const sp& client) - : LayerBaseClient(flinger, display, client) +LayerDim::LayerDim(SurfaceFlinger* flinger, const sp& client) + : LayerBaseClient(flinger, client) { } diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h index fbfb2fbe0..06f312d6f 100644 --- a/services/surfaceflinger/LayerDim.h +++ b/services/surfaceflinger/LayerDim.h @@ -32,8 +32,7 @@ namespace android { class LayerDim : public LayerBaseClient { public: - LayerDim(SurfaceFlinger* flinger, DisplayID display, - const sp& client); + LayerDim(SurfaceFlinger* flinger, const sp& client); virtual ~LayerDim(); virtual void onDraw(const sp& hw, const Region& clip) const; diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp index 799ecdcb7..5c18ebd53 100644 --- a/services/surfaceflinger/LayerScreenshot.cpp +++ b/services/surfaceflinger/LayerScreenshot.cpp @@ -34,9 +34,9 @@ namespace android { // --------------------------------------------------------------------------- -LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, DisplayID display, +LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, const sp& client) - : LayerBaseClient(flinger, display, client), + : LayerBaseClient(flinger, client), mTextureName(0), mFlinger(flinger) { } @@ -48,9 +48,10 @@ LayerScreenshot::~LayerScreenshot() } } -status_t LayerScreenshot::captureLocked() { +status_t LayerScreenshot::captureLocked(int32_t layerStack) { GLfloat u, v; - status_t result = mFlinger->renderScreenToTextureLocked(0, &mTextureName, &u, &v); + status_t result = mFlinger->renderScreenToTextureLocked(layerStack, + &mTextureName, &u, &v); if (result != NO_ERROR) { return result; } @@ -93,7 +94,7 @@ uint32_t LayerScreenshot::doTransaction(uint32_t flags) if (draw.flags & layer_state_t::eLayerHidden) { if (!(curr.flags & layer_state_t::eLayerHidden)) { // we're going from hidden to visible - status_t err = captureLocked(); + status_t err = captureLocked(curr.layerStack); if (err != NO_ERROR) { ALOGW("createScreenshotSurface failed (%s)", strerror(-err)); } diff --git a/services/surfaceflinger/LayerScreenshot.h b/services/surfaceflinger/LayerScreenshot.h index c06c23ca0..7807ffc5b 100644 --- a/services/surfaceflinger/LayerScreenshot.h +++ b/services/surfaceflinger/LayerScreenshot.h @@ -35,8 +35,7 @@ class LayerScreenshot : public LayerBaseClient GLfloat mTexCoords[8]; sp mFlinger; public: - LayerScreenshot(SurfaceFlinger* flinger, DisplayID display, - const sp& client); + LayerScreenshot(SurfaceFlinger* flinger, const sp& client); virtual ~LayerScreenshot(); status_t capture(); @@ -51,7 +50,7 @@ public: virtual const char* getTypeId() const { return "LayerScreenshot"; } private: - status_t captureLocked(); + status_t captureLocked(int32_t layerStack); void initTexture(GLfloat u, GLfloat v); }; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index ed687e313..09ade121b 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -155,24 +155,6 @@ sp SurfaceFlinger::createConnection() return bclient; } -int32_t SurfaceFlinger::chooseNewDisplayIdLocked() const -{ - int32_t id = DisplayDevice::DISPLAY_ID_COUNT - 1; - bool available; - do { - id++; - available = true; - for (size_t i = 0; i < mCurrentState.displays.size(); i++) { - const DisplayDeviceState& dds(mCurrentState.displays.valueAt(i)); - if (dds.id == id) { - available = false; - break; - } - } - } while (!available); - return id; -} - sp SurfaceFlinger::createDisplay() { class DisplayToken : public BBinder { @@ -192,15 +174,14 @@ sp SurfaceFlinger::createDisplay() sp token = new DisplayToken(this); Mutex::Autolock _l(mStateLock); - int32_t id = chooseNewDisplayIdLocked(); - DisplayDeviceState info(id); + DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL); mCurrentState.displays.add(token, info); return token; } sp SurfaceFlinger::getBuiltInDisplay(int32_t id) { - if (uint32_t(id) >= DisplayDevice::DISPLAY_ID_COUNT) { + if (uint32_t(id) >= DisplayDevice::NUM_DISPLAY_TYPES) { ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); return NULL; } @@ -416,14 +397,16 @@ status_t SurfaceFlinger::readyToRun() // initialize our main display hardware - for (size_t i=0 ; i hw = new DisplayDevice(this, - DisplayDevice::DISPLAY_ID_MAIN, HWC_DISPLAY_PRIMARY, + DisplayDevice::DISPLAY_PRIMARY, + mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], anw, fbs, mEGLConfig); - mDisplays.add(hw->getDisplayId(), hw); + mDisplays.add(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], hw); // initialize OpenGL ES EGLSurface surface = hw->getEGLSurface(); @@ -453,6 +436,11 @@ status_t SurfaceFlinger::readyToRun() return NO_ERROR; } +int32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) { + return (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) ? + type : mHwc->allocateDisplayId(); +} + void SurfaceFlinger::startBootAnim() { // start boot animation property_set("service.bootanim.exit", "0"); @@ -637,8 +625,12 @@ bool SurfaceFlinger::threadLoop() { return true; } -void SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) { - mEventThread->onVSyncReceived(dpy, timestamp); +void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) { + if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) { + // we should only receive DisplayDevice::DisplayType from the vsync callback + const wp& token(mDefaultDisplays[type]); + mEventThread->onVSyncReceived(token, timestamp); + } } void SurfaceFlinger::eventControl(int event, int enabled) { @@ -718,7 +710,7 @@ void SurfaceFlinger::doDebugFlashRegions() } hw->compositionComplete(); // FIXME - if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) { + if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { eglSwapBuffers(mEGLDisplay, hw->getEGLSurface()); } } @@ -863,8 +855,7 @@ void SurfaceFlinger::postFramebuffer() // FIXME: EGL spec says: // "surface must be bound to the calling thread's current context, // for the current rendering API." - DisplayDevice::makeCurrent( - getDisplayDevice(DisplayDevice::DISPLAY_ID_MAIN), mEGLContext); + DisplayDevice::makeCurrent(getDefaultDisplayDevice(), mEGLContext); hwc.commit(); } @@ -958,40 +949,36 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) const ssize_t j = curr.indexOfKey(draw.keyAt(i)); if (j < 0) { // in drawing state but not in current state - if (draw[i].id != DisplayDevice::DISPLAY_ID_MAIN) { - mDisplays.removeItem(draw[i].id); + if (!draw[i].isMainDisplay()) { + mDisplays.removeItem(draw.keyAt(i)); } else { ALOGW("trying to remove the main display"); } } else { // this display is in both lists. see if something changed. const DisplayDeviceState& state(curr[j]); + const wp& display(curr.keyAt(j)); if (state.surface->asBinder() != draw[i].surface->asBinder()) { // changing the surface is like destroying and // recreating the DisplayDevice - const int32_t hwcDisplayId = - (uint32_t(state.id) < DisplayDevice::DISPLAY_ID_COUNT) ? - state.id : getHwComposer().allocateDisplayId(); - sp stc( new SurfaceTextureClient(state.surface)); - sp disp = new DisplayDevice(this, - state.id, hwcDisplayId, stc, 0, mEGLConfig); + state.type, display, stc, NULL, mEGLConfig); disp->setLayerStack(state.layerStack); disp->setOrientation(state.orientation); // TODO: take viewport and frame into account - mDisplays.replaceValueFor(state.id, disp); + mDisplays.replaceValueFor(display, disp); } if (state.layerStack != draw[i].layerStack) { - const sp& disp(getDisplayDevice(state.id)); + const sp& disp(getDisplayDevice(display)); disp->setLayerStack(state.layerStack); } if (state.orientation != draw[i].orientation || state.viewport != draw[i].viewport || state.frame != draw[i].frame) { - const sp& disp(getDisplayDevice(state.id)); + const sp& disp(getDisplayDevice(display)); disp->setOrientation(state.orientation); // TODO: take viewport and frame into account } @@ -1003,15 +990,12 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) for (size_t i=0 ; i stc( new SurfaceTextureClient(state.surface)); + const wp& display(curr.keyAt(i)); sp disp = new DisplayDevice(this, - state.id, hwcDisplayId, stc, 0, mEGLConfig); - mDisplays.add(state.id, disp); + state.type, display, stc, 0, mEGLConfig); + mDisplays.add(display, disp); } } } @@ -1262,7 +1246,7 @@ void SurfaceFlinger::doDisplayComposition(const sp& hw, // GL composition and only on those. // however, currently hwc.commit() already does that for the main // display and never for the other ones - if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) { + if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { // FIXME: EGL spec says: // "surface must be bound to the calling thread's current context, // for the current rendering API." @@ -1485,7 +1469,7 @@ uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) { uint32_t flags = 0; DisplayDeviceState& disp(mCurrentState.displays.editValueFor(s.token)); - if (disp.id >= 0) { + if (disp.isValid()) { const uint32_t what = s.what; if (what & DisplayState::eSurfaceChanged) { if (disp.surface->asBinder() != s.surface->asBinder()) { @@ -1588,7 +1572,7 @@ sp SurfaceFlinger::createLayer( ISurfaceComposerClient::surface_data_t* params, const String8& name, const sp& client, - DisplayID d, uint32_t w, uint32_t h, PixelFormat format, + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { sp layer; @@ -1603,14 +1587,14 @@ sp SurfaceFlinger::createLayer( //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { case ISurfaceComposerClient::eFXSurfaceNormal: - layer = createNormalLayer(client, d, w, h, flags, format); + layer = createNormalLayer(client, w, h, flags, format); break; case ISurfaceComposerClient::eFXSurfaceBlur: case ISurfaceComposerClient::eFXSurfaceDim: - layer = createDimLayer(client, d, w, h, flags); + layer = createDimLayer(client, w, h, flags); break; case ISurfaceComposerClient::eFXSurfaceScreenshot: - layer = createScreenshotLayer(client, d, w, h, flags); + layer = createScreenshotLayer(client, w, h, flags); break; } @@ -1630,7 +1614,7 @@ sp SurfaceFlinger::createLayer( } sp SurfaceFlinger::createNormalLayer( - const sp& client, DisplayID display, + const sp& client, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format) { @@ -1654,7 +1638,7 @@ sp SurfaceFlinger::createNormalLayer( format = PIXEL_FORMAT_RGBA_8888; #endif - sp layer = new Layer(this, display, client); + sp layer = new Layer(this, client); status_t err = layer->setBuffers(w, h, format, flags); if (CC_LIKELY(err != NO_ERROR)) { ALOGE("createNormalLayer() failed (%s)", strerror(-err)); @@ -1664,18 +1648,18 @@ sp SurfaceFlinger::createNormalLayer( } sp SurfaceFlinger::createDimLayer( - const sp& client, DisplayID display, + const sp& client, uint32_t w, uint32_t h, uint32_t flags) { - sp layer = new LayerDim(this, display, client); + sp layer = new LayerDim(this, client); return layer; } sp SurfaceFlinger::createScreenshotLayer( - const sp& client, DisplayID display, + const sp& client, uint32_t w, uint32_t h, uint32_t flags) { - sp layer = new LayerScreenshot(this, display, client); + sp layer = new LayerScreenshot(this, client); return layer; } @@ -1733,7 +1717,7 @@ void SurfaceFlinger::onInitializeDisplays() { Vector displays; DisplayState d; d.what = DisplayState::eOrientationChanged; - d.token = mDefaultDisplays[DisplayDevice::DISPLAY_ID_MAIN]; + d.token = mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY]; d.orientation = DisplayState::eOrientationDefault; displays.add(d); setTransactionState(state, displays, 0); @@ -1973,7 +1957,7 @@ void SurfaceFlinger::dumpAllLocked( " id=%x, layerStack=%u, (%4dx%4d), orient=%2d, tr=%08x, " "flips=%u, secure=%d, numLayers=%u\n", dpy, - hw->getDisplayId(), hw->getLayerStack(), + hw->getDisplayType(), hw->getLayerStack(), hw->getWidth(), hw->getHeight(), hw->getOrientation(), hw->getTransform().getType(), hw->getPageFlipCount(), @@ -2169,14 +2153,14 @@ void SurfaceFlinger::repaintEverything() { // --------------------------------------------------------------------------- -status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, +status_t SurfaceFlinger::renderScreenToTexture(uint32_t layerStack, GLuint* textureName, GLfloat* uOut, GLfloat* vOut) { Mutex::Autolock _l(mStateLock); - return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); + return renderScreenToTextureLocked(layerStack, textureName, uOut, vOut); } -status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, +status_t SurfaceFlinger::renderScreenToTextureLocked(uint32_t layerStack, GLuint* textureName, GLfloat* uOut, GLfloat* vOut) { ATRACE_CALL(); @@ -2185,7 +2169,8 @@ status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, return INVALID_OPERATION; // get screen geometry - sp hw(getDisplayDevice(dpy)); + // FIXME: figure out what it means to have a screenshot texture w/ multi-display + sp hw(getDefaultDisplayDevice()); const uint32_t hw_w = hw->getWidth(); const uint32_t hw_h = hw->getHeight(); GLfloat u = 1; @@ -2254,17 +2239,12 @@ status_t SurfaceFlinger::captureScreenImplLocked(const sp& display, status_t result = PERMISSION_DENIED; - const DisplayDeviceState& disp(mDrawingState.displays.valueFor(display)); - if (CC_UNLIKELY(disp.id < 0)) { - return BAD_VALUE; - } - if (!GLExtensions::getInstance().haveFramebufferObject()) { return INVALID_OPERATION; } // get screen geometry - sp hw(getDisplayDevice(disp.id)); + sp hw(getDisplayDevice(display)); const uint32_t hw_w = hw->getWidth(); const uint32_t hw_h = hw->getHeight(); @@ -2317,19 +2297,15 @@ status_t SurfaceFlinger::captureScreenImplLocked(const sp& display, glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); - // TODO: filter the layers that are drawn based on the layer stack of the display. - const LayerVector& layers(mDrawingState.layersSortedByZ); + const Vector< sp >& layers(hw->getVisibleLayersSortedByZ()); const size_t count = layers.size(); for (size_t i=0 ; i& layer(layers[i]); - const uint32_t flags = layer->drawingState().flags; - if (!(flags & layer_state_t::eLayerHidden)) { - const uint32_t z = layer->drawingState().z; - if (z >= minLayerZ && z <= maxLayerZ) { - if (filtering) layer->setFiltering(true); - layer->draw(hw); - if (filtering) layer->setFiltering(false); - } + const uint32_t z = layer->drawingState().z; + if (z >= minLayerZ && z <= maxLayerZ) { + if (filtering) layer->setFiltering(true); + layer->draw(hw); + if (filtering) layer->setFiltering(false); } } @@ -2465,11 +2441,12 @@ int SurfaceFlinger::LayerVector::do_compare(const void* lhs, // --------------------------------------------------------------------------- -SurfaceFlinger::DisplayDeviceState::DisplayDeviceState() : id(-1) { +SurfaceFlinger::DisplayDeviceState::DisplayDeviceState() + : type(DisplayDevice::DISPLAY_ID_INVALID) { } -SurfaceFlinger::DisplayDeviceState::DisplayDeviceState(int32_t id) - : id(id), layerStack(0), orientation(0) { +SurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type) + : type(type), layerStack(0), orientation(0) { } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 653a631dd..f0af3d645 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -113,21 +113,23 @@ public: void repaintEverything(); // renders content on given display to a texture. thread-safe version. - status_t renderScreenToTexture(DisplayID dpy, GLuint* textureName, + status_t renderScreenToTexture(uint32_t layerStack, GLuint* textureName, GLfloat* uOut, GLfloat* vOut); // renders content on given display to a texture, w/o acquiring main lock - status_t renderScreenToTextureLocked(DisplayID dpy, GLuint* textureName, + status_t renderScreenToTextureLocked(uint32_t layerStack, GLuint* textureName, GLfloat* uOut, GLfloat* vOut); // returns the default Display sp getDefaultDisplayDevice() const { - return getDisplayDevice(DisplayDevice::DISPLAY_ID_MAIN); + return getDisplayDevice(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY]); } // utility function to delete a texture on the main thread void deleteTextureAsync(GLuint texture); + // allocate a h/w composer display id + int32_t allocateHwcDisplayId(DisplayDevice::DisplayType type); // enable/disable h/w composer event // TODO: this should be made accessible only to EventThread @@ -161,8 +163,10 @@ private: struct DisplayDeviceState { DisplayDeviceState(); - DisplayDeviceState(int32_t id); - int32_t id; + DisplayDeviceState(DisplayDevice::DisplayType type); + bool isValid() const { return type >= 0; } + bool isMainDisplay() const { return type == DisplayDevice::DISPLAY_PRIMARY; } + DisplayDevice::DisplayType type; sp surface; uint32_t layerStack; Rect viewport; @@ -221,7 +225,7 @@ private: /* ------------------------------------------------------------------------ * HWComposer::EventHandler interface */ - virtual void onVSyncReceived(int dpy, nsecs_t timestamp); + virtual void onVSyncReceived(int type, nsecs_t timestamp); /* ------------------------------------------------------------------------ * Message handling @@ -265,17 +269,17 @@ private: * Layer management */ sp createLayer(ISurfaceComposerClient::surface_data_t* params, - const String8& name, const sp& client, DisplayID display, - uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); + const String8& name, const sp& client, + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); - sp createNormalLayer(const sp& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format); + sp createNormalLayer(const sp& client, + uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format); - sp createDimLayer(const sp& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags); + sp createDimLayer(const sp& client, + uint32_t w, uint32_t h, uint32_t flags); sp createScreenshotLayer(const sp& client, - DisplayID display, uint32_t w, uint32_t h, uint32_t flags); + uint32_t w, uint32_t h, uint32_t flags); // called in response to the window-manager calling // ISurfaceComposerClient::destroySurface() @@ -326,10 +330,10 @@ private: // called when starting, or restarting after system_server death void initializeDisplays(); - sp getDisplayDevice(DisplayID dpy) const { + sp getDisplayDevice(const wp& dpy) const { return mDisplays.valueFor(dpy); } - const sp& getDisplayDevice(DisplayID dpy) { + const sp& getDisplayDevice(const wp& dpy) { return mDisplays.valueFor(dpy); } @@ -371,7 +375,7 @@ private: /* ------------------------------------------------------------------------ * Display management */ - int32_t chooseNewDisplayIdLocked() const; + /* ------------------------------------------------------------------------ * Debugging & dumpsys @@ -413,14 +417,14 @@ private: EGLContext mEGLContext; EGLConfig mEGLConfig; EGLDisplay mEGLDisplay; - sp mDefaultDisplays[DisplayDevice::DISPLAY_ID_COUNT]; + sp mDefaultDisplays[DisplayDevice::NUM_DISPLAY_TYPES]; // Can only accessed from the main thread, these members // don't need synchronization State mDrawingState; bool mVisibleRegionsDirty; bool mHwWorkListDirty; - DefaultKeyedVector > mDisplays; + DefaultKeyedVector< wp, sp > mDisplays; // don't use a lock for these, we don't care int mDebugRegion;