1
0
Fork 0

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:
Sean Paul 2015-11-19 21:46:11 -05:00
parent 35301f498c
commit 04b47ea435
5 changed files with 107 additions and 101 deletions

View file

@ -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";

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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)

View file

@ -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) {