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;