diff options
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 77 |
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(), |