Loading libs/gui/include/gui/ISurfaceComposer.h +19 −2 Original line number Diff line number Diff line Loading @@ -174,8 +174,25 @@ public: virtual status_t setActiveColorMode(const sp<IBinder>& display, ui::ColorMode colorMode) = 0; /* Capture the specified screen. requires READ_FRAME_BUFFER permission * This function will fail if there is a secure window on screen. /** * Capture the specified screen. This requires READ_FRAME_BUFFER * permission. This function will fail if there is a secure window on * screen. * * This function can capture a subregion (the source crop) of the screen. * The subregion can be optionally rotated. It will also be scaled to * match the size of the output buffer. * * At the moment, sourceCrop is ignored and is always set to the visible * region (projected display viewport) of the screen. * * reqWidth and reqHeight specifies the size of the buffer. When either * of them is 0, they are set to the size of the logical display viewport. * * When useIdentityTransform is true, layer transformations are disabled. * * rotation specifies the rotation of the source crop (and the pixels in * it) around its center. */ virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Loading libs/gui/include/gui/LayerState.h +14 −0 Original line number Diff line number Diff line Loading @@ -152,10 +152,24 @@ struct DisplayState { sp<IBinder> token; sp<IGraphicBufferProducer> surface; uint32_t layerStack; // These states define how layers are projected onto the physical display. // // Layers are first clipped to `viewport'. They are then translated and // scaled from `viewport' to `frame'. Finally, they are rotated according // to `orientation', `width', and `height'. // // For example, assume viewport is Rect(0, 0, 200, 100), frame is Rect(20, // 10, 420, 210), and the size of the display is WxH. When orientation is // 0, layers will be scaled by a factor of 2 and translated by (20, 10). // When orientation is 1, layers will be additionally rotated by 90 // degrees around the origin clockwise and translated by (W, 0). uint32_t orientation; Rect viewport; Rect frame; uint32_t width, height; status_t write(Parcel& output) const; status_t read(const Parcel& input); }; Loading services/surfaceflinger/BufferLayer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -204,7 +204,7 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, if (!blackOutLayer) { // TODO: we could be more subtle with isFixedSize() const bool useFiltering = getFiltering() || needsFiltering(renderArea) || isFixedSize(); const bool useFiltering = needsFiltering(renderArea) || isFixedSize(); // Query the texture matrix given our current filtering mode. float textureMatrix[16]; Loading services/surfaceflinger/DisplayDevice.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -224,6 +224,7 @@ DisplayDevice::DisplayDevice( std::unique_ptr<RE::Surface> renderSurface, int displayWidth, int displayHeight, int displayInstallOrientation, bool hasWideColorGamut, const HdrCapabilities& hdrCapabilities, const int32_t supportedPerFrameMetadata, Loading @@ -239,6 +240,7 @@ DisplayDevice::DisplayDevice( mSurface{std::move(renderSurface)}, mDisplayWidth(displayWidth), mDisplayHeight(displayHeight), mDisplayInstallOrientation(displayInstallOrientation), mPageFlipCount(0), mIsSecure(isSecure), mLayerStack(NO_LAYER_STACK), Loading Loading @@ -610,9 +612,8 @@ void DisplayDevice::setProjection(int orientation, // need to take care of primary display rotation for mGlobalTransform // for case if the panel is not installed aligned with device orientation if (mType == DisplayType::DISPLAY_PRIMARY) { int primaryDisplayOrientation = mFlinger->getPrimaryDisplayOrientation(); DisplayDevice::orientationToTransfrom( (orientation + primaryDisplayOrientation) % (DisplayState::eOrientation270 + 1), (orientation + mDisplayInstallOrientation) % (DisplayState::eOrientation270 + 1), w, h, &R); } Loading services/surfaceflinger/DisplayDevice.h +97 −9 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ #include <math/mat4.h> #include <binder/IBinder.h> #include <gui/ISurfaceComposer.h> #include <gui/LayerState.h> #include <hardware/hwcomposer_defs.h> #include <ui/GraphicTypes.h> #include <ui/HdrCapabilities.h> Loading Loading @@ -88,6 +88,7 @@ public: std::unique_ptr<RE::Surface> renderSurface, int displayWidth, int displayHeight, int displayInstallOrientation, bool hasWideColorGamut, const HdrCapabilities& hdrCapabilities, const int32_t supportedPerFrameMetadata, Loading @@ -111,6 +112,7 @@ public: int getWidth() const; int getHeight() const; int getInstallOrientation() const { return mDisplayInstallOrientation; } void setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers); const Vector< sp<Layer> >& getVisibleLayersSortedByZ() const; Loading Loading @@ -234,6 +236,7 @@ private: std::unique_ptr<RE::Surface> mSurface; int mDisplayWidth; int mDisplayHeight; const int mDisplayInstallOrientation; mutable uint32_t mPageFlipCount; String8 mDisplayName; bool mIsSecure; Loading Loading @@ -337,12 +340,14 @@ struct DisplayDeviceState { class DisplayRenderArea : public RenderArea { public: DisplayRenderArea(const sp<const DisplayDevice> device, ISurfaceComposer::Rotation rotation = ISurfaceComposer::eRotateNone) : DisplayRenderArea(device, device->getBounds(), device->getHeight(), device->getWidth(), Transform::orientation_flags rotation = Transform::ROT_0) : DisplayRenderArea(device, device->getBounds(), device->getWidth(), device->getHeight(), rotation) {} DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqHeight, uint32_t reqWidth, ISurfaceComposer::Rotation rotation) : RenderArea(reqHeight, reqWidth, CaptureFill::OPAQUE, rotation), mDevice(device), DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Transform::orientation_flags rotation) : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, getDisplayRotation(rotation, device->getInstallOrientation())), mDevice(device), mSourceCrop(sourceCrop) {} const Transform& getTransform() const override { return mDevice->getTransform(); } Loading @@ -350,10 +355,93 @@ public: int getHeight() const override { return mDevice->getHeight(); } int getWidth() const override { return mDevice->getWidth(); } bool isSecure() const override { return mDevice->isSecure(); } bool needsFiltering() const override { return mDevice->needsFiltering(); } Rect getSourceCrop() const override { return mSourceCrop; } bool needsFiltering() const override { // check if the projection from the logical display to the physical // display needs filtering if (mDevice->needsFiltering()) { return true; } // check if the projection from the logical render area (i.e., the // physical display) to the physical render area requires filtering const Rect sourceCrop = getSourceCrop(); int width = sourceCrop.width(); int height = sourceCrop.height(); if (getRotationFlags() & Transform::ROT_90) { std::swap(width, height); } return width != getReqWidth() || height != getReqHeight(); } Rect getSourceCrop() const override { // use the (projected) logical display viewport by default if (mSourceCrop.isEmpty()) { return mDevice->getScissor(); } const int orientation = mDevice->getInstallOrientation(); if (orientation == DisplayState::eOrientationDefault) { return mSourceCrop; } // Install orientation is transparent to the callers. Apply it now. uint32_t flags = 0x00; switch (orientation) { case DisplayState::eOrientation90: flags = Transform::ROT_90; break; case DisplayState::eOrientation180: flags = Transform::ROT_180; break; case DisplayState::eOrientation270: flags = Transform::ROT_270; break; } Transform tr; tr.set(flags, getWidth(), getHeight()); return tr.transform(mSourceCrop); } private: // Install orientation is transparent to the callers. We need to cancel // it out by modifying rotation flags. static Transform::orientation_flags getDisplayRotation( Transform::orientation_flags rotation, int orientation) { if (orientation == DisplayState::eOrientationDefault) { return rotation; } // convert hw orientation into flag presentation // here inverse transform needed uint8_t hw_rot_90 = 0x00; uint8_t hw_flip_hv = 0x00; switch (orientation) { case DisplayState::eOrientation90: hw_rot_90 = Transform::ROT_90; hw_flip_hv = Transform::ROT_180; break; case DisplayState::eOrientation180: hw_flip_hv = Transform::ROT_180; break; case DisplayState::eOrientation270: hw_rot_90 = Transform::ROT_90; break; } // transform flags operation // 1) flip H V if both have ROT_90 flag // 2) XOR these flags uint8_t rotation_rot_90 = rotation & Transform::ROT_90; uint8_t rotation_flip_hv = rotation & Transform::ROT_180; if (rotation_rot_90 & hw_rot_90) { rotation_flip_hv = (~rotation_flip_hv) & Transform::ROT_180; } return static_cast<Transform::orientation_flags>( (rotation_rot_90 ^ hw_rot_90) | (rotation_flip_hv ^ hw_flip_hv)); } const sp<const DisplayDevice> mDevice; const Rect mSourceCrop; }; Loading Loading
libs/gui/include/gui/ISurfaceComposer.h +19 −2 Original line number Diff line number Diff line Loading @@ -174,8 +174,25 @@ public: virtual status_t setActiveColorMode(const sp<IBinder>& display, ui::ColorMode colorMode) = 0; /* Capture the specified screen. requires READ_FRAME_BUFFER permission * This function will fail if there is a secure window on screen. /** * Capture the specified screen. This requires READ_FRAME_BUFFER * permission. This function will fail if there is a secure window on * screen. * * This function can capture a subregion (the source crop) of the screen. * The subregion can be optionally rotated. It will also be scaled to * match the size of the output buffer. * * At the moment, sourceCrop is ignored and is always set to the visible * region (projected display viewport) of the screen. * * reqWidth and reqHeight specifies the size of the buffer. When either * of them is 0, they are set to the size of the logical display viewport. * * When useIdentityTransform is true, layer transformations are disabled. * * rotation specifies the rotation of the source crop (and the pixels in * it) around its center. */ virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Loading
libs/gui/include/gui/LayerState.h +14 −0 Original line number Diff line number Diff line Loading @@ -152,10 +152,24 @@ struct DisplayState { sp<IBinder> token; sp<IGraphicBufferProducer> surface; uint32_t layerStack; // These states define how layers are projected onto the physical display. // // Layers are first clipped to `viewport'. They are then translated and // scaled from `viewport' to `frame'. Finally, they are rotated according // to `orientation', `width', and `height'. // // For example, assume viewport is Rect(0, 0, 200, 100), frame is Rect(20, // 10, 420, 210), and the size of the display is WxH. When orientation is // 0, layers will be scaled by a factor of 2 and translated by (20, 10). // When orientation is 1, layers will be additionally rotated by 90 // degrees around the origin clockwise and translated by (W, 0). uint32_t orientation; Rect viewport; Rect frame; uint32_t width, height; status_t write(Parcel& output) const; status_t read(const Parcel& input); }; Loading
services/surfaceflinger/BufferLayer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -204,7 +204,7 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, if (!blackOutLayer) { // TODO: we could be more subtle with isFixedSize() const bool useFiltering = getFiltering() || needsFiltering(renderArea) || isFixedSize(); const bool useFiltering = needsFiltering(renderArea) || isFixedSize(); // Query the texture matrix given our current filtering mode. float textureMatrix[16]; Loading
services/surfaceflinger/DisplayDevice.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -224,6 +224,7 @@ DisplayDevice::DisplayDevice( std::unique_ptr<RE::Surface> renderSurface, int displayWidth, int displayHeight, int displayInstallOrientation, bool hasWideColorGamut, const HdrCapabilities& hdrCapabilities, const int32_t supportedPerFrameMetadata, Loading @@ -239,6 +240,7 @@ DisplayDevice::DisplayDevice( mSurface{std::move(renderSurface)}, mDisplayWidth(displayWidth), mDisplayHeight(displayHeight), mDisplayInstallOrientation(displayInstallOrientation), mPageFlipCount(0), mIsSecure(isSecure), mLayerStack(NO_LAYER_STACK), Loading Loading @@ -610,9 +612,8 @@ void DisplayDevice::setProjection(int orientation, // need to take care of primary display rotation for mGlobalTransform // for case if the panel is not installed aligned with device orientation if (mType == DisplayType::DISPLAY_PRIMARY) { int primaryDisplayOrientation = mFlinger->getPrimaryDisplayOrientation(); DisplayDevice::orientationToTransfrom( (orientation + primaryDisplayOrientation) % (DisplayState::eOrientation270 + 1), (orientation + mDisplayInstallOrientation) % (DisplayState::eOrientation270 + 1), w, h, &R); } Loading
services/surfaceflinger/DisplayDevice.h +97 −9 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ #include <math/mat4.h> #include <binder/IBinder.h> #include <gui/ISurfaceComposer.h> #include <gui/LayerState.h> #include <hardware/hwcomposer_defs.h> #include <ui/GraphicTypes.h> #include <ui/HdrCapabilities.h> Loading Loading @@ -88,6 +88,7 @@ public: std::unique_ptr<RE::Surface> renderSurface, int displayWidth, int displayHeight, int displayInstallOrientation, bool hasWideColorGamut, const HdrCapabilities& hdrCapabilities, const int32_t supportedPerFrameMetadata, Loading @@ -111,6 +112,7 @@ public: int getWidth() const; int getHeight() const; int getInstallOrientation() const { return mDisplayInstallOrientation; } void setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers); const Vector< sp<Layer> >& getVisibleLayersSortedByZ() const; Loading Loading @@ -234,6 +236,7 @@ private: std::unique_ptr<RE::Surface> mSurface; int mDisplayWidth; int mDisplayHeight; const int mDisplayInstallOrientation; mutable uint32_t mPageFlipCount; String8 mDisplayName; bool mIsSecure; Loading Loading @@ -337,12 +340,14 @@ struct DisplayDeviceState { class DisplayRenderArea : public RenderArea { public: DisplayRenderArea(const sp<const DisplayDevice> device, ISurfaceComposer::Rotation rotation = ISurfaceComposer::eRotateNone) : DisplayRenderArea(device, device->getBounds(), device->getHeight(), device->getWidth(), Transform::orientation_flags rotation = Transform::ROT_0) : DisplayRenderArea(device, device->getBounds(), device->getWidth(), device->getHeight(), rotation) {} DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqHeight, uint32_t reqWidth, ISurfaceComposer::Rotation rotation) : RenderArea(reqHeight, reqWidth, CaptureFill::OPAQUE, rotation), mDevice(device), DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Transform::orientation_flags rotation) : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, getDisplayRotation(rotation, device->getInstallOrientation())), mDevice(device), mSourceCrop(sourceCrop) {} const Transform& getTransform() const override { return mDevice->getTransform(); } Loading @@ -350,10 +355,93 @@ public: int getHeight() const override { return mDevice->getHeight(); } int getWidth() const override { return mDevice->getWidth(); } bool isSecure() const override { return mDevice->isSecure(); } bool needsFiltering() const override { return mDevice->needsFiltering(); } Rect getSourceCrop() const override { return mSourceCrop; } bool needsFiltering() const override { // check if the projection from the logical display to the physical // display needs filtering if (mDevice->needsFiltering()) { return true; } // check if the projection from the logical render area (i.e., the // physical display) to the physical render area requires filtering const Rect sourceCrop = getSourceCrop(); int width = sourceCrop.width(); int height = sourceCrop.height(); if (getRotationFlags() & Transform::ROT_90) { std::swap(width, height); } return width != getReqWidth() || height != getReqHeight(); } Rect getSourceCrop() const override { // use the (projected) logical display viewport by default if (mSourceCrop.isEmpty()) { return mDevice->getScissor(); } const int orientation = mDevice->getInstallOrientation(); if (orientation == DisplayState::eOrientationDefault) { return mSourceCrop; } // Install orientation is transparent to the callers. Apply it now. uint32_t flags = 0x00; switch (orientation) { case DisplayState::eOrientation90: flags = Transform::ROT_90; break; case DisplayState::eOrientation180: flags = Transform::ROT_180; break; case DisplayState::eOrientation270: flags = Transform::ROT_270; break; } Transform tr; tr.set(flags, getWidth(), getHeight()); return tr.transform(mSourceCrop); } private: // Install orientation is transparent to the callers. We need to cancel // it out by modifying rotation flags. static Transform::orientation_flags getDisplayRotation( Transform::orientation_flags rotation, int orientation) { if (orientation == DisplayState::eOrientationDefault) { return rotation; } // convert hw orientation into flag presentation // here inverse transform needed uint8_t hw_rot_90 = 0x00; uint8_t hw_flip_hv = 0x00; switch (orientation) { case DisplayState::eOrientation90: hw_rot_90 = Transform::ROT_90; hw_flip_hv = Transform::ROT_180; break; case DisplayState::eOrientation180: hw_flip_hv = Transform::ROT_180; break; case DisplayState::eOrientation270: hw_rot_90 = Transform::ROT_90; break; } // transform flags operation // 1) flip H V if both have ROT_90 flag // 2) XOR these flags uint8_t rotation_rot_90 = rotation & Transform::ROT_90; uint8_t rotation_flip_hv = rotation & Transform::ROT_180; if (rotation_rot_90 & hw_rot_90) { rotation_flip_hv = (~rotation_flip_hv) & Transform::ROT_180; } return static_cast<Transform::orientation_flags>( (rotation_rot_90 ^ hw_rot_90) | (rotation_flip_hv ^ hw_flip_hv)); } const sp<const DisplayDevice> mDevice; const Rect mSourceCrop; }; Loading