summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
author Alec Mouri <alecmouri@google.com> 2019-03-20 23:48:20 -0700
committer android-build-merger <android-build-merger@google.com> 2019-03-20 23:48:20 -0700
commit445c7b36406aecd467d1444d63add110a320fefc (patch)
treee81b0c1918ae3dffe9101f03f30e5a56e5abadc8 /services/surfaceflinger/SurfaceFlinger.cpp
parentc754cfcdc720045940c2e0073e4d3d1f80d5019e (diff)
parent3b14b7db6fb94e2cd812bf15a72723839aa756c4 (diff)
Merge changes from topic "RenderArea"
am: 3b14b7db6f Change-Id: I6eea9c398eae9b8f67e20eb115e644bb0f7dd481
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp162
1 files changed, 63 insertions, 99 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4ec1e7f166..78d751a212 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -75,6 +75,7 @@
#include "LayerVector.h"
#include "MonitoredProducer.h"
#include "SurfaceFlinger.h"
+#include "Transform.h"
#include "clz.h"
#include "DisplayHardware/ComposerHal.h"
@@ -112,6 +113,27 @@ using ui::Hdr;
using ui::RenderIntent;
namespace {
+
+#pragma clang diagnostic push
+#pragma clang diagnostic error "-Wswitch-enum"
+
+Transform::orientation_flags fromSurfaceComposerRotation(ISurfaceComposer::Rotation rotation) {
+ switch (rotation) {
+ case ISurfaceComposer::eRotateNone:
+ return Transform::ROT_0;
+ case ISurfaceComposer::eRotate90:
+ return Transform::ROT_90;
+ case ISurfaceComposer::eRotate180:
+ return Transform::ROT_180;
+ case ISurfaceComposer::eRotate270:
+ return Transform::ROT_270;
+ }
+ ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
+ return Transform::ROT_0;
+}
+
+#pragma clang diagnostic pop
+
class ConditionalLock {
public:
ConditionalLock(Mutex& mutex, bool lock) : mMutex(mutex), mLocked(lock) {
@@ -144,7 +166,7 @@ bool SurfaceFlinger::useVrFlinger;
int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers;
// TODO(courtneygo): Rename hasWideColorDisplay to clarify its actual meaning.
bool SurfaceFlinger::hasWideColorDisplay;
-
+int SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientationDefault;
std::string getHwcServiceName() {
char value[PROPERTY_VALUE_MAX] = {};
@@ -278,19 +300,19 @@ SurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) {
switch (primaryDisplayOrientation) {
case V1_1::DisplayOrientation::ORIENTATION_90:
- mPrimaryDisplayOrientation = DisplayState::eOrientation90;
+ SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation90;
break;
case V1_1::DisplayOrientation::ORIENTATION_180:
- mPrimaryDisplayOrientation = DisplayState::eOrientation180;
+ SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation180;
break;
case V1_1::DisplayOrientation::ORIENTATION_270:
- mPrimaryDisplayOrientation = DisplayState::eOrientation270;
+ SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation270;
break;
default:
- mPrimaryDisplayOrientation = DisplayState::eOrientationDefault;
+ SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientationDefault;
break;
}
- ALOGV("Primary Display Orientation is set to %2d.", mPrimaryDisplayOrientation);
+ ALOGV("Primary Display Orientation is set to %2d.", SurfaceFlinger::primaryDisplayOrientation);
mPrimaryDispSync.init(SurfaceFlinger::hasSyncFramework, SurfaceFlinger::dispSyncPresentTimeOffset);
@@ -952,7 +974,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
info.secure = true;
if (type == DisplayDevice::DISPLAY_PRIMARY &&
- mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) {
+ primaryDisplayOrientation & DisplayState::eOrientationSwapMask) {
std::swap(info.w, info.h);
}
@@ -2395,6 +2417,9 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
nativeWindow->setSwapInterval(nativeWindow.get(), 0);
}
+ const int displayInstallOrientation = state.type == DisplayDevice::DISPLAY_PRIMARY ?
+ primaryDisplayOrientation : DisplayState::eOrientationDefault;
+
// virtual displays are always considered enabled
auto initialPowerMode = (state.type >= DisplayDevice::DISPLAY_VIRTUAL) ? HWC_POWER_MODE_NORMAL
: HWC_POWER_MODE_OFF;
@@ -2402,7 +2427,7 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
sp<DisplayDevice> hw =
new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow,
dispSurface, std::move(renderSurface), displayWidth, displayHeight,
- hasWideColorGamut, hdrCapabilities,
+ displayInstallOrientation, hasWideColorGamut, hdrCapabilities,
supportedPerFrameMetadata, hwcColorModes, initialPowerMode);
if (maxFrameBufferAcquiredBuffers >= 3) {
@@ -4832,20 +4857,24 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, sp<GraphicBuf
if (CC_UNLIKELY(display == 0)) return BAD_VALUE;
- const sp<const DisplayDevice> device(getDisplayDeviceLocked(display));
- if (CC_UNLIKELY(device == 0)) return BAD_VALUE;
+ auto renderAreaRotation = fromSurfaceComposerRotation(rotation);
- const Rect& dispScissor = device->getScissor();
- if (!dispScissor.isEmpty()) {
- sourceCrop.set(dispScissor);
- // adb shell screencap will default reqWidth and reqHeight to zeros.
+ sp<DisplayDevice> device;
+ {
+ Mutex::Autolock _l(mStateLock);
+
+ device = getDisplayDeviceLocked(display);
+ if (!device) return BAD_VALUE;
+
+ // set the requested width/height to the logical display viewport size
+ // by default
if (reqWidth == 0 || reqHeight == 0) {
reqWidth = uint32_t(device->getViewport().width());
reqHeight = uint32_t(device->getViewport().height());
}
}
- DisplayRenderArea renderArea(device, sourceCrop, reqHeight, reqWidth, rotation);
+ DisplayRenderArea renderArea(device, sourceCrop, reqWidth, reqHeight, renderAreaRotation);
auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
device, minLayerZ, maxLayerZ, std::placeholders::_1);
@@ -4861,9 +4890,10 @@ 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),
+ mNeedsFiltering(false),
mFlinger(flinger),
mChildrenOnly(childrenOnly) {}
const Transform& getTransform() const override { return mTransform; }
@@ -4874,7 +4904,7 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
int getHeight() const override { return mLayer->getDrawingState().active.h; }
int getWidth() const override { return mLayer->getDrawingState().active.w; }
bool isSecure() const override { return false; }
- bool needsFiltering() const override { return false; }
+ bool needsFiltering() const override { return mNeedsFiltering; }
Rect getSourceCrop() const override {
if (mCrop.isEmpty()) {
return getBounds();
@@ -4895,6 +4925,11 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
};
void render(std::function<void()> drawLayers) override {
+ const Rect sourceCrop = getSourceCrop();
+ // no need to check rotation because there is none
+ mNeedsFiltering = sourceCrop.width() != getReqWidth() ||
+ sourceCrop.height() != getReqHeight();
+
if (!mChildrenOnly) {
mTransform = mLayer->getTransform().inverse();
drawLayers();
@@ -4917,6 +4952,7 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
// layer which has no properties set and which does not draw.
sp<ContainerLayer> screenshotParentLayer;
Transform mTransform;
+ bool mNeedsFiltering;
SurfaceFlinger* mFlinger;
const bool mChildrenOnly;
@@ -4951,6 +4987,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) {
@@ -4972,8 +5016,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(),
@@ -5049,57 +5091,12 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
auto& engine(getRenderEngine());
// get screen geometry
- const auto raWidth = renderArea.getWidth();
const auto raHeight = renderArea.getHeight();
const auto reqWidth = renderArea.getReqWidth();
const auto reqHeight = renderArea.getReqHeight();
- Rect sourceCrop = renderArea.getSourceCrop();
-
- bool filtering = false;
- if (mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) {
- filtering = static_cast<int32_t>(reqWidth) != raHeight ||
- static_cast<int32_t>(reqHeight) != raWidth;
- } else {
- filtering = static_cast<int32_t>(reqWidth) != raWidth ||
- static_cast<int32_t>(reqHeight) != raHeight;
- }
-
- // if a default or invalid sourceCrop is passed in, set reasonable values
- if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || !sourceCrop.isValid()) {
- sourceCrop.setLeftTop(Point(0, 0));
- sourceCrop.setRightBottom(Point(raWidth, raHeight));
- } else if (mPrimaryDisplayOrientation != DisplayState::eOrientationDefault) {
- Transform tr;
- uint32_t flags = 0x00;
- switch (mPrimaryDisplayOrientation) {
- case DisplayState::eOrientation90:
- flags = Transform::ROT_90;
- break;
- case DisplayState::eOrientation180:
- flags = Transform::ROT_180;
- break;
- case DisplayState::eOrientation270:
- flags = Transform::ROT_270;
- break;
- }
- tr.set(flags, raWidth, raHeight);
- sourceCrop = tr.transform(sourceCrop);
- }
-
- // ensure that sourceCrop is inside screen
- if (sourceCrop.left < 0) {
- ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
- }
- if (sourceCrop.right > raWidth) {
- ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, raWidth);
- }
- if (sourceCrop.top < 0) {
- ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
- }
- if (sourceCrop.bottom > raHeight) {
- ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, raHeight);
- }
+ const auto sourceCrop = renderArea.getSourceCrop();
+ const auto rotation = renderArea.getRotationFlags();
// assume ColorMode::SRGB / RenderIntent::COLORIMETRIC
engine.setOutputDataSpace(Dataspace::SRGB);
@@ -5108,37 +5105,6 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
// make sure to clear all GL error flags
engine.checkErrors();
- Transform::orientation_flags rotation = renderArea.getRotationFlags();
- if (mPrimaryDisplayOrientation != DisplayState::eOrientationDefault) {
- // convert hw orientation into flag presentation
- // here inverse transform needed
- uint8_t hw_rot_90 = 0x00;
- uint8_t hw_flip_hv = 0x00;
- switch (mPrimaryDisplayOrientation) {
- 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;
- }
- rotation = static_cast<Transform::orientation_flags>
- ((rotation_rot_90 ^ hw_rot_90) | (rotation_flip_hv ^ hw_flip_hv));
- }
-
// set-up our viewport
engine.setViewportAndProjection(reqWidth, reqHeight, sourceCrop, raHeight, yswap,
rotation);
@@ -5149,9 +5115,7 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
engine.clearWithColor(0, 0, 0, alpha);
traverseLayers([&](Layer* layer) {
- if (filtering) layer->setFiltering(true);
layer->draw(renderArea, useIdentityTransform);
- if (filtering) layer->setFiltering(false);
});
}