diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h index 382cbdaeb..693fbfbaf 100644 --- a/include/surfaceflinger/ISurfaceComposer.h +++ b/include/surfaceflinger/ISurfaceComposer.h @@ -121,7 +121,8 @@ public: virtual status_t captureScreen(DisplayID dpy, sp* heap, uint32_t* width, uint32_t* height, PixelFormat* format, - uint32_t reqWidth, uint32_t reqHeight) = 0; + uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ) = 0; virtual status_t turnElectronBeamOff(int32_t mode) = 0; virtual status_t turnElectronBeamOn(int32_t mode) = 0; diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h index a80832d5d..25b2ebf5a 100644 --- a/include/surfaceflinger/SurfaceComposerClient.h +++ b/include/surfaceflinger/SurfaceComposerClient.h @@ -183,6 +183,8 @@ public: // frees the previous screenshot and capture a new one status_t update(); status_t update(uint32_t reqWidth, uint32_t reqHeight); + status_t update(uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ); // release memory occupied by the screenshot void release(); diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp index 969ee7985..b8a7a794d 100644 --- a/libs/surfaceflinger_client/ISurfaceComposer.cpp +++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp @@ -127,13 +127,16 @@ public: virtual status_t captureScreen(DisplayID dpy, sp* heap, uint32_t* width, uint32_t* height, PixelFormat* format, - uint32_t reqWidth, uint32_t reqHeight) + uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeInt32(dpy); data.writeInt32(reqWidth); data.writeInt32(reqHeight); + data.writeInt32(minLayerZ); + data.writeInt32(maxLayerZ); remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); *heap = interface_cast(reply.readStrongBinder()); *width = reply.readInt32(); @@ -231,11 +234,13 @@ status_t BnSurfaceComposer::onTransact( DisplayID dpy = data.readInt32(); uint32_t reqWidth = data.readInt32(); uint32_t reqHeight = data.readInt32(); + uint32_t minLayerZ = data.readInt32(); + uint32_t maxLayerZ = data.readInt32(); sp heap; uint32_t w, h; PixelFormat f; status_t res = captureScreen(dpy, &heap, &w, &h, &f, - reqWidth, reqHeight); + reqWidth, reqHeight, minLayerZ, maxLayerZ); reply->writeStrongBinder(heap->asBinder()); reply->writeInt32(w); reply->writeInt32(h); diff --git a/libs/surfaceflinger_client/SurfaceComposerClient.cpp b/libs/surfaceflinger_client/SurfaceComposerClient.cpp index f27046160..d3367246a 100644 --- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp +++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp @@ -555,7 +555,8 @@ status_t ScreenshotClient::update() { if (s == NULL) return NO_INIT; mHeap = 0; return s->captureScreen(0, &mHeap, - &mWidth, &mHeight, &mFormat, 0, 0); + &mWidth, &mHeight, &mFormat, 0, 0, + 0, -1UL); } status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) { @@ -563,7 +564,18 @@ status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) { if (s == NULL) return NO_INIT; mHeap = 0; return s->captureScreen(0, &mHeap, - &mWidth, &mHeight, &mFormat, reqWidth, reqHeight); + &mWidth, &mHeight, &mFormat, reqWidth, reqHeight, + 0, -1UL); +} + +status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ) { + sp s(ComposerService::getComposerService()); + if (s == NULL) return NO_INIT; + mHeap = 0; + return s->captureScreen(0, &mHeap, + &mWidth, &mHeight, &mFormat, reqWidth, reqHeight, + minLayerZ, maxLayerZ); } void ScreenshotClient::release() { diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 7980dfa21..61d08aabd 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2078,7 +2078,8 @@ status_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, sp* heap, uint32_t* w, uint32_t* h, PixelFormat* f, - uint32_t sw, uint32_t sh) + uint32_t sw, uint32_t sh, + uint32_t minLayerZ, uint32_t maxLayerZ) { status_t result = PERMISSION_DENIED; @@ -2132,7 +2133,10 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, const size_t count = layers.size(); for (size_t i=0 ; i& layer(layers[i]); - layer->drawForSreenShot(); + const uint32_t z = layer->drawingState().z; + if (z >= minLayerZ && z <= maxLayerZ) { + layer->drawForSreenShot(); + } } // XXX: this is needed on tegra @@ -2185,7 +2189,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, status_t SurfaceFlinger::captureScreen(DisplayID dpy, sp* heap, uint32_t* width, uint32_t* height, PixelFormat* format, - uint32_t sw, uint32_t sh) + uint32_t sw, uint32_t sh, + uint32_t minLayerZ, uint32_t maxLayerZ) { // only one display supported for now if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) @@ -2203,13 +2208,18 @@ status_t SurfaceFlinger::captureScreen(DisplayID dpy, PixelFormat* f; uint32_t sw; uint32_t sh; + uint32_t minLayerZ; + uint32_t maxLayerZ; status_t result; public: MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, sp* heap, uint32_t* w, uint32_t* h, PixelFormat* f, - uint32_t sw, uint32_t sh) + uint32_t sw, uint32_t sh, + uint32_t minLayerZ, uint32_t maxLayerZ) : flinger(flinger), dpy(dpy), - heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), result(PERMISSION_DENIED) + heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), + minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), + result(PERMISSION_DENIED) { } status_t getResult() const { @@ -2223,14 +2233,14 @@ status_t SurfaceFlinger::captureScreen(DisplayID dpy, return true; result = flinger->captureScreenImplLocked(dpy, - heap, w, h, f, sw, sh); + heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); return true; } }; sp msg = new MessageCaptureScreen(this, - dpy, heap, width, height, format, sw, sh); + dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); status_t res = postMessageSync(msg); if (res == NO_ERROR) { res = static_cast( msg.get() )->getResult(); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index c0e5acd28..ca7d27d86 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -192,13 +192,13 @@ public: virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags); virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags); virtual void signal() const; - virtual status_t captureScreen(DisplayID dpy, - sp* heap, - uint32_t* width, - uint32_t* height, - PixelFormat* format, - uint32_t reqWidth, - uint32_t reqHeight); + + virtual status_t captureScreen(DisplayID dpy, + sp* heap, + uint32_t* width, uint32_t* height, + PixelFormat* format, uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ); + virtual status_t turnElectronBeamOff(int32_t mode); virtual status_t turnElectronBeamOn(int32_t mode); @@ -313,7 +313,8 @@ private: status_t captureScreenImplLocked(DisplayID dpy, sp* heap, uint32_t* width, uint32_t* height, PixelFormat* format, - uint32_t reqWidth = 0, uint32_t reqHeight = 0); + uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ); status_t turnElectronBeamOffImplLocked(int32_t mode); status_t turnElectronBeamOnImplLocked(int32_t mode);