surfaceflinger: respect install orientation in DisplayRenderArea
DisplayRenderArea getTransform takes install orientation into
consideration. Fix getSourceCrop and getRotationFlags to respect
install orientation as well.
This results in some changes
- source crop is no longer rotated by install orientation for
LayerRenderArea
- rotation flags is no longer rotated by install orientation for
LayerRenderArea
- source crop is no longer set to getBounds by default for
LayerRenderArea (it is already done in captureLayers)
- source crop is always rotated by install orientation for
DisplayRenderArea
AFAICT, all the changes are actually fixes. Quickly verified by
forcing primaryDisplayOrientation to DisplayState::eOrientation90.
Bug: 113041375
Test: take screenshot, rotate screen, screencap
Change-Id: If19df222ae52f6b276f9b0572e7b9bec872e3ae4
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index c7ed927..3613e1a 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -24,6 +24,7 @@
#include <unordered_map>
#include <binder/IBinder.h>
+#include <gui/LayerState.h>
#include <hardware/hwcomposer_defs.h>
#include <math/mat4.h>
#include <renderengine/Surface.h>
@@ -342,8 +343,10 @@
rotation) {}
DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth,
uint32_t reqHeight, ui::Transform::orientation_flags rotation)
- : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, rotation), mDevice(device),
- mSourceCrop(sourceCrop) {}
+ : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE,
+ getDisplayRotation(rotation, device->getInstallOrientation())),
+ mDevice(device),
+ mSourceCrop(sourceCrop) {}
const ui::Transform& getTransform() const override { return mDevice->getTransform(); }
Rect getBounds() const override { return mDevice->getBounds(); }
@@ -351,9 +354,67 @@
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; }
+
+ Rect getSourceCrop() const override {
+ const int orientation = mDevice->getInstallOrientation();
+ if (orientation == DisplayState::eOrientationDefault) {
+ return mSourceCrop;
+ }
+
+ uint32_t flags = 0x00;
+ switch (orientation) {
+ case DisplayState::eOrientation90:
+ flags = ui::Transform::ROT_90;
+ break;
+ case DisplayState::eOrientation180:
+ flags = ui::Transform::ROT_180;
+ break;
+ case DisplayState::eOrientation270:
+ flags = ui::Transform::ROT_270;
+ break;
+ }
+ ui::Transform tr;
+ tr.set(flags, getWidth(), getHeight());
+ return tr.transform(mSourceCrop);
+ }
private:
+ static ui::Transform::orientation_flags getDisplayRotation(
+ ui::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 = ui::Transform::ROT_90;
+ hw_flip_hv = ui::Transform::ROT_180;
+ break;
+ case DisplayState::eOrientation180:
+ hw_flip_hv = ui::Transform::ROT_180;
+ break;
+ case DisplayState::eOrientation270:
+ hw_rot_90 = ui::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 & ui::Transform::ROT_90;
+ uint8_t rotation_flip_hv = rotation & ui::Transform::ROT_180;
+ if (rotation_rot_90 & hw_rot_90) {
+ rotation_flip_hv = (~rotation_flip_hv) & ui::Transform::ROT_180;
+ }
+
+ return static_cast<ui::Transform::orientation_flags>(
+ (rotation_rot_90 ^ hw_rot_90) | (rotation_flip_hv ^ hw_flip_hv));
+ }
+
const sp<const DisplayDevice> mDevice;
const Rect mSourceCrop;
};