mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 903562 - Honor horizontal and vertical reflection. r=ncameron, r=vliu
This commit is contained in:
parent
be4dcfced2
commit
578dc5345d
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012, 2013 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -319,6 +319,15 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
||||
return true;
|
||||
}
|
||||
|
||||
// HWC supports only the following 2D transformations:
|
||||
//
|
||||
// Scaling via the sourceCrop and displayFrame in hwc_layer_t
|
||||
// Translation via the sourceCrop and displayFrame in hwc_layer_t
|
||||
// Rotation (in square angles only) via the HWC_TRANSFORM_ROT_* flags
|
||||
// Reflection (horizontal and vertical) via the HWC_TRANSFORM_FLIP_* flags
|
||||
//
|
||||
// A 2D transform with PreservesAxisAlignedRectangles() has all the attributes
|
||||
// above
|
||||
gfxMatrix transform;
|
||||
const gfx3DMatrix& transform3D = aLayer->GetEffectiveTransform();
|
||||
if (!transform3D.Is2D(&transform) || !transform.PreservesAxisAlignedRectangles()) {
|
||||
@ -356,6 +365,8 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Buffer rotation is not to be confused with the angled rotation done by a transform matrix
|
||||
// It's a fancy ThebesLayer feature used for scrolling
|
||||
if (state.BufferRotated()) {
|
||||
LOGD("%s Layer has a rotated buffer", aLayer->Name());
|
||||
return false;
|
||||
@ -413,24 +424,122 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
||||
hwcLayer.flags |= HWC_FORMAT_RB_SWAP;
|
||||
}
|
||||
|
||||
// Translation and scaling have been addressed in PrepareLayerRects().
|
||||
// Given the above and that we checked for PreservesAxisAlignedRectangles()
|
||||
// the only possible transformations left to address are
|
||||
// square angle rotation and horizontal/vertical reflection.
|
||||
//
|
||||
// The rotation and reflection permutations total 16 but can be
|
||||
// reduced to 8 transformations after eliminating redundancies.
|
||||
//
|
||||
// All matrices represented here are in the form
|
||||
//
|
||||
// | xx xy |
|
||||
// | yx yy |
|
||||
//
|
||||
// And ignore scaling.
|
||||
//
|
||||
// Reflection is applied before rotation
|
||||
gfxMatrix rotation = transform * aGLWorldTransform;
|
||||
// Compute fuzzy equal like PreservesAxisAlignedRectangles()
|
||||
// Compute fuzzy zero like PreservesAxisAlignedRectangles()
|
||||
if (fabs(rotation.xx) < 1e-6) {
|
||||
if (rotation.xy < 0) {
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_90;
|
||||
LOGD("Layer buffer rotated 90 degrees");
|
||||
if (rotation.yx > 0) {
|
||||
// 90 degree rotation
|
||||
//
|
||||
// | 0 -1 |
|
||||
// | 1 0 |
|
||||
//
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_90;
|
||||
LOGD("Layer rotated 90 degrees");
|
||||
}
|
||||
else {
|
||||
// Horizontal reflection then 90 degree rotation
|
||||
//
|
||||
// | 0 -1 | | -1 0 | = | 0 -1 |
|
||||
// | 1 0 | | 0 1 | | -1 0 |
|
||||
//
|
||||
// same as vertical reflection then 270 degree rotation
|
||||
//
|
||||
// | 0 1 | | 1 0 | = | 0 -1 |
|
||||
// | -1 0 | | 0 -1 | | -1 0 |
|
||||
//
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_90 | HWC_TRANSFORM_FLIP_H;
|
||||
LOGD("Layer vertically reflected then rotated 270 degrees");
|
||||
}
|
||||
} else {
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_270;
|
||||
LOGD("Layer buffer rotated 270 degrees");
|
||||
if (rotation.yx < 0) {
|
||||
// 270 degree rotation
|
||||
//
|
||||
// | 0 1 |
|
||||
// | -1 0 |
|
||||
//
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_270;
|
||||
LOGD("Layer rotated 270 degrees");
|
||||
}
|
||||
else {
|
||||
// Vertical reflection then 90 degree rotation
|
||||
//
|
||||
// | 0 1 | | -1 0 | = | 0 1 |
|
||||
// | -1 0 | | 0 1 | | 1 0 |
|
||||
//
|
||||
// Same as horizontal reflection then 270 degree rotation
|
||||
//
|
||||
// | 0 -1 | | 1 0 | = | 0 1 |
|
||||
// | 1 0 | | 0 -1 | | 1 0 |
|
||||
//
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_90 | HWC_TRANSFORM_FLIP_V;
|
||||
LOGD("Layer horizontally reflected then rotated 270 degrees");
|
||||
}
|
||||
}
|
||||
} else if (rotation.xx < 0) {
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_180;
|
||||
LOGD("Layer buffer rotated 180 degrees");
|
||||
if (rotation.yy > 0) {
|
||||
// Horizontal reflection
|
||||
//
|
||||
// | -1 0 |
|
||||
// | 0 1 |
|
||||
//
|
||||
hwcLayer.transform = HWC_TRANSFORM_FLIP_H;
|
||||
LOGD("Layer rotated 180 degrees");
|
||||
}
|
||||
else {
|
||||
// 180 degree rotation
|
||||
//
|
||||
// | -1 0 |
|
||||
// | 0 -1 |
|
||||
//
|
||||
// Same as horizontal and vertical reflection
|
||||
//
|
||||
// | -1 0 | | 1 0 | = | -1 0 |
|
||||
// | 0 1 | | 0 -1 | | 0 -1 |
|
||||
//
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_180;
|
||||
LOGD("Layer rotated 180 degrees");
|
||||
}
|
||||
} else {
|
||||
hwcLayer.transform = 0;
|
||||
if (rotation.yy < 0) {
|
||||
// Vertical reflection
|
||||
//
|
||||
// | 1 0 |
|
||||
// | 0 -1 |
|
||||
//
|
||||
hwcLayer.transform = HWC_TRANSFORM_FLIP_V;
|
||||
LOGD("Layer rotated 180 degrees");
|
||||
}
|
||||
else {
|
||||
// No rotation or reflection
|
||||
//
|
||||
// | 1 0 |
|
||||
// | 0 1 |
|
||||
//
|
||||
hwcLayer.transform = 0;
|
||||
}
|
||||
}
|
||||
|
||||
hwcLayer.transform |= state.YFlipped() ? HWC_TRANSFORM_FLIP_V : 0;
|
||||
if (state.YFlipped()) {
|
||||
// Invert vertical reflection flag if it was already set
|
||||
hwcLayer.transform ^= HWC_TRANSFORM_FLIP_V;
|
||||
}
|
||||
hwc_region_t region;
|
||||
if (visibleRegion.GetNumRects() > 1) {
|
||||
mVisibleRegions.push_back(RectVector());
|
||||
|
Loading…
Reference in New Issue
Block a user