drm_hwcomposer: Allow for multiple transforms at once
Because sometimes one just ain't enough, allow more than one transform at a time. Bug: chrome-os-partner:46710 Test: Tested with the CTS Verifier "Camera Orientation" test Change-Id: Ie5f9bbbc7c89964feafc78150e18512861c85b69 Signed-off-by: Sean Paul <seanpaul@chromium.org>
This commit is contained in:
parent
35301f498c
commit
04b47ea435
5 changed files with 107 additions and 101 deletions
|
|
@ -443,23 +443,52 @@ static void DumpBuffer(const DrmHwcBuffer &buffer, std::ostringstream *out) {
|
|||
*out << buffer->width << "/" << buffer->height << "/" << buffer->format;
|
||||
}
|
||||
|
||||
static const char *TransformToString(DrmHwcTransform transform) {
|
||||
switch (transform) {
|
||||
case DrmHwcTransform::kIdentity:
|
||||
return "IDENTITY";
|
||||
case DrmHwcTransform::kFlipH:
|
||||
return "FLIPH";
|
||||
case DrmHwcTransform::kFlipV:
|
||||
return "FLIPV";
|
||||
case DrmHwcTransform::kRotate90:
|
||||
return "ROTATE90";
|
||||
case DrmHwcTransform::kRotate180:
|
||||
return "ROTATE180";
|
||||
case DrmHwcTransform::kRotate270:
|
||||
return "ROTATE270";
|
||||
default:
|
||||
return "<invalid>";
|
||||
static void DumpTransform(uint32_t transform, std::ostringstream *out) {
|
||||
*out << "[";
|
||||
|
||||
if (transform == 0)
|
||||
*out << "IDENTITY";
|
||||
|
||||
bool separator = false;
|
||||
if (transform & DrmHwcTransform::kFlipH) {
|
||||
*out << "FLIPH";
|
||||
separator = true;
|
||||
}
|
||||
if (transform & DrmHwcTransform::kFlipV) {
|
||||
if (separator)
|
||||
*out << "|";
|
||||
*out << "FLIPV";
|
||||
separator = true;
|
||||
}
|
||||
if (transform & DrmHwcTransform::kRotate90) {
|
||||
if (separator)
|
||||
*out << "|";
|
||||
*out << "ROTATE90";
|
||||
separator = true;
|
||||
}
|
||||
if (transform & DrmHwcTransform::kRotate180) {
|
||||
if (separator)
|
||||
*out << "|";
|
||||
*out << "ROTATE180";
|
||||
separator = true;
|
||||
}
|
||||
if (transform & DrmHwcTransform::kRotate270) {
|
||||
if (separator)
|
||||
*out << "|";
|
||||
*out << "ROTATE270";
|
||||
separator = true;
|
||||
}
|
||||
|
||||
uint32_t valid_bits = DrmHwcTransform::kFlipH | DrmHwcTransform::kFlipH |
|
||||
DrmHwcTransform::kRotate90 |
|
||||
DrmHwcTransform::kRotate180 |
|
||||
DrmHwcTransform::kRotate270;
|
||||
if (transform & ~valid_bits) {
|
||||
if (separator)
|
||||
*out << "|";
|
||||
*out << "INVALID";
|
||||
}
|
||||
*out << "]";
|
||||
}
|
||||
|
||||
static const char *BlendingToString(DrmHwcBlending blending) {
|
||||
|
|
@ -523,8 +552,9 @@ void DrmDisplayComposition::Dump(std::ostringstream *out) const {
|
|||
if (layer.protected_usage())
|
||||
*out << " protected";
|
||||
|
||||
*out << " transform=" << TransformToString(layer.transform)
|
||||
<< " blending[a=" << (int)layer.alpha
|
||||
*out << " transform=";
|
||||
DumpTransform(layer.transform, out);
|
||||
*out << " blending[a=" << (int)layer.alpha
|
||||
<< "]=" << BlendingToString(layer.blending) << " source_crop";
|
||||
layer.source_crop.Dump(out);
|
||||
*out << " display_frame";
|
||||
|
|
|
|||
|
|
@ -683,30 +683,18 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp) {
|
|||
source_crop = layer.source_crop;
|
||||
if (layer.blending == DrmHwcBlending::kPreMult)
|
||||
alpha = layer.alpha;
|
||||
switch (layer.transform) {
|
||||
case DrmHwcTransform::kFlipH:
|
||||
rotation = 1 << DRM_REFLECT_X;
|
||||
break;
|
||||
case DrmHwcTransform::kFlipV:
|
||||
rotation = 1 << DRM_REFLECT_Y;
|
||||
break;
|
||||
case DrmHwcTransform::kRotate90:
|
||||
rotation = 1 << DRM_ROTATE_90;
|
||||
break;
|
||||
case DrmHwcTransform::kRotate180:
|
||||
rotation = 1 << DRM_ROTATE_180;
|
||||
break;
|
||||
case DrmHwcTransform::kRotate270:
|
||||
rotation = 1 << DRM_ROTATE_270;
|
||||
break;
|
||||
case DrmHwcTransform::kIdentity:
|
||||
rotation = 0;
|
||||
break;
|
||||
default:
|
||||
ALOGE("Invalid transform value 0x%x given", layer.transform);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
rotation = 0;
|
||||
if (layer.transform & DrmHwcTransform::kFlipH)
|
||||
rotation |= 1 << DRM_REFLECT_X;
|
||||
if (layer.transform & DrmHwcTransform::kFlipV)
|
||||
rotation |= 1 << DRM_REFLECT_Y;
|
||||
if (layer.transform & DrmHwcTransform::kRotate90)
|
||||
rotation |= 1 << DRM_ROTATE_90;
|
||||
else if (layer.transform & DrmHwcTransform::kRotate180)
|
||||
rotation |= 1 << DRM_ROTATE_180;
|
||||
else if (layer.transform & DrmHwcTransform::kRotate270)
|
||||
rotation |= 1 << DRM_ROTATE_270;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,13 +119,13 @@ class DrmHwcNativeHandle {
|
|||
template <typename T>
|
||||
using DrmHwcRect = separate_rects::Rect<T>;
|
||||
|
||||
enum class DrmHwcTransform : uint32_t {
|
||||
enum DrmHwcTransform {
|
||||
kIdentity = 0,
|
||||
kFlipH = HWC_TRANSFORM_FLIP_H,
|
||||
kFlipV = HWC_TRANSFORM_FLIP_V,
|
||||
kRotate90 = HWC_TRANSFORM_ROT_90,
|
||||
kRotate180 = HWC_TRANSFORM_ROT_180,
|
||||
kRotate270 = HWC_TRANSFORM_ROT_270,
|
||||
kFlipH = 1 << 0,
|
||||
kFlipV = 1 << 1,
|
||||
kRotate90 = 1 << 2,
|
||||
kRotate180 = 1 << 3,
|
||||
kRotate270 = 1 << 4,
|
||||
};
|
||||
|
||||
enum class DrmHwcBlending : int32_t {
|
||||
|
|
@ -139,7 +139,7 @@ struct DrmHwcLayer {
|
|||
int gralloc_buffer_usage = 0;
|
||||
DrmHwcBuffer buffer;
|
||||
DrmHwcNativeHandle handle;
|
||||
DrmHwcTransform transform = DrmHwcTransform::kIdentity;
|
||||
uint32_t transform;
|
||||
DrmHwcBlending blending = DrmHwcBlending::kNone;
|
||||
uint8_t alpha = 0xff;
|
||||
DrmHwcRect<float> source_crop;
|
||||
|
|
|
|||
54
glworker.cpp
54
glworker.cpp
|
|
@ -332,40 +332,34 @@ static void ConstructCommand(const DrmHwcLayer *layers,
|
|||
cmd.texture_count++;
|
||||
src.texture_index = texture_index;
|
||||
|
||||
bool swap_xy, flip_xy[2];
|
||||
switch (layer.transform) {
|
||||
case DrmHwcTransform::kFlipH:
|
||||
swap_xy = false;
|
||||
flip_xy[0] = true;
|
||||
flip_xy[1] = false;
|
||||
break;
|
||||
case DrmHwcTransform::kFlipV:
|
||||
swap_xy = false;
|
||||
flip_xy[0] = false;
|
||||
flip_xy[1] = true;
|
||||
break;
|
||||
case DrmHwcTransform::kRotate90:
|
||||
swap_xy = true;
|
||||
flip_xy[0] = false;
|
||||
flip_xy[1] = true;
|
||||
break;
|
||||
case DrmHwcTransform::kRotate180:
|
||||
swap_xy = false;
|
||||
bool swap_xy = false;
|
||||
bool flip_xy[2] = { false, false };
|
||||
|
||||
if (layer.transform == DrmHwcTransform::kRotate180) {
|
||||
swap_xy = false;
|
||||
flip_xy[0] = true;
|
||||
flip_xy[1] = true;
|
||||
} else if (layer.transform == DrmHwcTransform::kRotate270) {
|
||||
swap_xy = true;
|
||||
flip_xy[0] = true;
|
||||
flip_xy[1] = false;
|
||||
} else if (layer.transform & DrmHwcTransform::kRotate90) {
|
||||
swap_xy = true;
|
||||
if (layer.transform & DrmHwcTransform::kFlipH) {
|
||||
flip_xy[0] = true;
|
||||
flip_xy[1] = true;
|
||||
break;
|
||||
case DrmHwcTransform::kRotate270:
|
||||
swap_xy = true;
|
||||
flip_xy[0] = true;
|
||||
flip_xy[1] = false;
|
||||
break;
|
||||
default:
|
||||
ALOGE("Unknown transform for layer: defaulting to identity transform");
|
||||
case DrmHwcTransform::kIdentity:
|
||||
swap_xy = false;
|
||||
} else if (layer.transform & DrmHwcTransform::kFlipV) {
|
||||
flip_xy[0] = false;
|
||||
flip_xy[1] = false;
|
||||
break;
|
||||
} else {
|
||||
flip_xy[0] = false;
|
||||
flip_xy[1] = true;
|
||||
}
|
||||
} else {
|
||||
if (layer.transform & DrmHwcTransform::kFlipH)
|
||||
flip_xy[0] = true;
|
||||
if (layer.transform & DrmHwcTransform::kFlipV)
|
||||
flip_xy[1] = true;
|
||||
}
|
||||
|
||||
if (swap_xy)
|
||||
|
|
|
|||
|
|
@ -252,28 +252,22 @@ int DrmHwcLayer::InitFromHwcLayer(hwc_layer_1_t *sf_layer, Importer *importer,
|
|||
sf_layer->displayFrame.left, sf_layer->displayFrame.top,
|
||||
sf_layer->displayFrame.right, sf_layer->displayFrame.bottom);
|
||||
|
||||
switch (sf_layer->transform) {
|
||||
case 0:
|
||||
transform = DrmHwcTransform::kIdentity;
|
||||
break;
|
||||
case HWC_TRANSFORM_FLIP_H:
|
||||
transform = DrmHwcTransform::kFlipH;
|
||||
break;
|
||||
case HWC_TRANSFORM_FLIP_V:
|
||||
transform = DrmHwcTransform::kFlipV;
|
||||
break;
|
||||
case HWC_TRANSFORM_ROT_90:
|
||||
transform = DrmHwcTransform::kRotate90;
|
||||
break;
|
||||
case HWC_TRANSFORM_ROT_180:
|
||||
transform = DrmHwcTransform::kRotate180;
|
||||
break;
|
||||
case HWC_TRANSFORM_ROT_270:
|
||||
transform = DrmHwcTransform::kRotate270;
|
||||
break;
|
||||
default:
|
||||
ALOGE("Invalid transform in hwc_layer_1_t %d", sf_layer->transform);
|
||||
return -EINVAL;
|
||||
transform = 0;
|
||||
// 270* and 180* cannot be combined with flips. More specifically, they
|
||||
// already contain both horizontal and vertical flips, so those fields are
|
||||
// redundant in this case. 90* rotation can be combined with either horizontal
|
||||
// flip or vertical flip, so treat it differently
|
||||
if (sf_layer->transform == HWC_TRANSFORM_ROT_270) {
|
||||
transform = DrmHwcTransform::kRotate270;
|
||||
} else if (sf_layer->transform == HWC_TRANSFORM_ROT_180) {
|
||||
transform = DrmHwcTransform::kRotate180;
|
||||
} else {
|
||||
if (sf_layer->transform & HWC_TRANSFORM_FLIP_H)
|
||||
transform |= DrmHwcTransform::kFlipH;
|
||||
if (sf_layer->transform & HWC_TRANSFORM_FLIP_V)
|
||||
transform |= DrmHwcTransform::kFlipV;
|
||||
if (sf_layer->transform & HWC_TRANSFORM_ROT_90)
|
||||
transform |= DrmHwcTransform::kRotate90;
|
||||
}
|
||||
|
||||
switch (sf_layer->blending) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue