summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp77
1 files changed, 64 insertions, 13 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 37d014686e..5acfe59c4e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -143,6 +143,21 @@ bool isWideColorMode(const ColorMode colorMode) {
return false;
}
+ui::Transform::orientation_flags fromSurfaceComposerRotation(ISurfaceComposer::Rotation rotation) {
+ switch (rotation) {
+ case ISurfaceComposer::eRotateNone:
+ return ui::Transform::ROT_0;
+ case ISurfaceComposer::eRotate90:
+ return ui::Transform::ROT_90;
+ case ISurfaceComposer::eRotate180:
+ return ui::Transform::ROT_180;
+ case ISurfaceComposer::eRotate270:
+ return ui::Transform::ROT_270;
+ }
+ ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
+ return ui::Transform::ROT_0;
+}
+
#pragma clang diagnostic pop
class ConditionalLock {
@@ -4902,20 +4917,50 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& displayToken,
if (!displayToken) return BAD_VALUE;
- const auto display = getDisplayDeviceLocked(displayToken);
- if (!display) return BAD_VALUE;
+ auto renderAreaRotation = fromSurfaceComposerRotation(rotation);
+
+ sp<DisplayDevice> display;
+ {
+ Mutex::Autolock _l(mStateLock);
+
+ display = getDisplayDeviceLocked(displayToken);
+ if (!display) return BAD_VALUE;
+
+ const Rect& dispScissor = display->getScissor();
+ if (!dispScissor.isEmpty()) {
+ sourceCrop.set(dispScissor);
+ // adb shell screencap will default reqWidth and reqHeight to zeros.
+ if (reqWidth == 0 || reqHeight == 0) {
+ reqWidth = uint32_t(display->getViewport().width());
+ reqHeight = uint32_t(display->getViewport().height());
+ }
+ }
+
+ // get screen geometry
+ uint32_t width = display->getWidth();
+ uint32_t height = display->getHeight();
- const Rect& dispScissor = display->getScissor();
- if (!dispScissor.isEmpty()) {
- sourceCrop.set(dispScissor);
- // adb shell screencap will default reqWidth and reqHeight to zeros.
- if (reqWidth == 0 || reqHeight == 0) {
- reqWidth = uint32_t(display->getViewport().width());
- reqHeight = uint32_t(display->getViewport().height());
+ if (renderAreaRotation & ui::Transform::ROT_90) {
+ std::swap(width, height);
+ }
+
+ if (mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) {
+ std::swap(width, height);
+ }
+
+ if ((reqWidth > width) || (reqHeight > height)) {
+ ALOGE("size mismatch (%d, %d) > (%d, %d)", reqWidth, reqHeight, width, height);
+ } else {
+ if (reqWidth == 0) {
+ reqWidth = width;
+ }
+ if (reqHeight == 0) {
+ reqHeight = height;
+ }
}
}
- DisplayRenderArea renderArea(display, sourceCrop, reqHeight, reqWidth, rotation);
+ DisplayRenderArea renderArea(display, sourceCrop, reqWidth, reqHeight, renderAreaRotation);
auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
display, minLayerZ, maxLayerZ, std::placeholders::_1);
@@ -4931,7 +4976,7 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
public:
LayerRenderArea(SurfaceFlinger* flinger, const sp<Layer>& layer, const Rect crop,
int32_t reqWidth, int32_t reqHeight, bool childrenOnly)
- : RenderArea(reqHeight, reqWidth, CaptureFill::CLEAR),
+ : RenderArea(reqWidth, reqHeight, CaptureFill::CLEAR),
mLayer(layer),
mCrop(crop),
mFlinger(flinger),
@@ -5023,6 +5068,14 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
int32_t reqWidth = crop.width() * frameScale;
int32_t reqHeight = crop.height() * frameScale;
+ // really small crop or frameScale
+ if (reqWidth <= 0) {
+ reqWidth = 1;
+ }
+ if (reqHeight <= 0) {
+ reqHeight = 1;
+ }
+
LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, childrenOnly);
auto traverseLayers = [parent, childrenOnly](const LayerVector::Visitor& visitor) {
@@ -5044,8 +5097,6 @@ status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
bool useIdentityTransform) {
ATRACE_CALL();
- renderArea.updateDimensions(mPrimaryDisplayOrientation);
-
const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
*outBuffer = new GraphicBuffer(renderArea.getReqWidth(), renderArea.getReqHeight(),