Merge "drm_hwcomposer: add transform support to OpenGL compositor" into mnc-dr-dev
diff --git a/drmdisplaycomposition.cpp b/drmdisplaycomposition.cpp
index 364a64e..d8dc886 100644
--- a/drmdisplaycomposition.cpp
+++ b/drmdisplaycomposition.cpp
@@ -85,9 +85,6 @@
int DrmDisplayComposition::AddLayer(hwc_layer_1_t *layer, hwc_drm_bo_t *bo,
DrmCrtc *crtc, DrmPlane *plane) {
- if (layer->transform != 0)
- return -EINVAL;
-
if (!validate_composition_type(DRM_COMPOSITION_TYPE_FRAME))
return -EINVAL;
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index 10b4480..0fd6874 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -28,6 +28,7 @@
#include <time.h>
#include <vector>
+#include <drm/drm_mode.h>
#include <cutils/log.h>
#include <sync/sync.h>
#include <utils/Trace.h>
@@ -95,22 +96,22 @@
int DrmDisplayCompositor::QueueComposition(
std::unique_ptr<DrmDisplayComposition> composition) {
switch (composition->type()) {
- case DRM_COMPOSITION_TYPE_FRAME:
- if (!active_)
- return -ENODEV;
- break;
- case DRM_COMPOSITION_TYPE_DPMS:
- /*
- * Update the state as soon as we get it so we can start/stop queuing
- * frames asap.
- */
- active_ = (composition->dpms_mode() == DRM_MODE_DPMS_ON);
- break;
- case DRM_COMPOSITION_TYPE_EMPTY:
- return 0;
- default:
- ALOGE("Unknown composition type %d/%d", composition->type(), display_);
- return -ENOENT;
+ case DRM_COMPOSITION_TYPE_FRAME:
+ if (!active_)
+ return -ENODEV;
+ break;
+ case DRM_COMPOSITION_TYPE_DPMS:
+ /*
+ * Update the state as soon as we get it so we can start/stop queuing
+ * frames asap.
+ */
+ active_ = (composition->dpms_mode() == DRM_MODE_DPMS_ON);
+ break;
+ case DRM_COMPOSITION_TYPE_EMPTY:
+ return 0;
+ default:
+ ALOGE("Unknown composition type %d/%d", composition->type(), display_);
+ return -ENOENT;
}
int ret = pthread_mutex_lock(&lock_);
@@ -173,6 +174,38 @@
continue;
}
+ uint64_t rotation;
+ switch (layer->transform) {
+ case HWC_TRANSFORM_FLIP_H:
+ rotation = 1 << DRM_REFLECT_X;
+ break;
+ case HWC_TRANSFORM_FLIP_V:
+ rotation = 1 << DRM_REFLECT_Y;
+ break;
+ case HWC_TRANSFORM_ROT_90:
+ rotation = 1 << DRM_ROTATE_90;
+ break;
+ case HWC_TRANSFORM_ROT_180:
+ rotation = 1 << DRM_ROTATE_180;
+ break;
+ case HWC_TRANSFORM_ROT_270:
+ rotation = 1 << DRM_ROTATE_270;
+ break;
+ case 0:
+ rotation = 0;
+ break;
+ default:
+ ALOGE("Invalid transform value 0x%x given", layer->transform);
+ ret = -EINVAL;
+ break;
+ }
+ // TODO: Once we have atomic test, this should fall back to GL
+ if (rotation && plane->rotation_property().id() == 0) {
+ ALOGE("Rotation is not supported on plane %d", plane->id());
+ ret = -EINVAL;
+ break;
+ }
+
ret =
drmModePropertySetAdd(pset, plane->id(), plane->crtc_property().id(),
crtc->id()) ||
@@ -202,6 +235,16 @@
ALOGE("Failed to add plane %d to set", plane->id());
break;
}
+
+ if (plane->rotation_property().id()) {
+ ret = drmModePropertySetAdd(
+ pset, plane->id(), plane->rotation_property().id(), rotation);
+ if (ret) {
+ ALOGE("Failed to add rotation property %d to plane %d",
+ plane->rotation_property().id(), plane->id());
+ break;
+ }
+ }
}
if (!ret) {
@@ -257,22 +300,22 @@
}
switch (composition->type()) {
- case DRM_COMPOSITION_TYPE_FRAME:
- ret = ApplyFrame(composition.get());
- if (ret) {
- ALOGE("Composite failed for display %d", display_);
+ case DRM_COMPOSITION_TYPE_FRAME:
+ ret = ApplyFrame(composition.get());
+ if (ret) {
+ ALOGE("Composite failed for display %d", display_);
+ return ret;
+ }
+ ++dump_frames_composited_;
+ break;
+ case DRM_COMPOSITION_TYPE_DPMS:
+ ret = ApplyDpms(composition.get());
+ if (ret)
+ ALOGE("Failed to apply dpms for display %d", display_);
return ret;
- }
- ++dump_frames_composited_;
- break;
- case DRM_COMPOSITION_TYPE_DPMS:
- ret = ApplyDpms(composition.get());
- if (ret)
- ALOGE("Failed to apply dpms for display %d", display_);
- return ret;
- default:
- ALOGE("Unknown composition type %d", composition->type());
- return -EINVAL;
+ default:
+ ALOGE("Unknown composition type %d", composition->type());
+ return -EINVAL;
}
if (active_composition_)
@@ -364,7 +407,8 @@
" src[x/y/w/h]=" << layer->sourceCropf.left << "/" <<
layer->sourceCropf.top << "/" <<
layer->sourceCropf.right - layer->sourceCropf.left << "/" <<
- layer->sourceCropf.bottom - layer->sourceCropf.top << "\n";
+ layer->sourceCropf.bottom - layer->sourceCropf.top << " transform=" <<
+ layer->transform << "\n";
}
}
diff --git a/drmplane.cpp b/drmplane.cpp
index d6ac875..3f17d7c 100644
--- a/drmplane.cpp
+++ b/drmplane.cpp
@@ -120,6 +120,10 @@
return ret;
}
+ ret = drm_->GetPlaneProperty(*this, "rotation", &rotation_property_);
+ if (ret)
+ ALOGE("Could not get rotation property");
+
return 0;
}
@@ -174,4 +178,8 @@
const DrmProperty &DrmPlane::src_h_property() const {
return src_h_property_;
}
+
+const DrmProperty &DrmPlane::rotation_property() const {
+ return rotation_property_;
+}
}
diff --git a/drmplane.h b/drmplane.h
index 96cd85c..1969d52 100644
--- a/drmplane.h
+++ b/drmplane.h
@@ -51,6 +51,7 @@
const DrmProperty &src_y_property() const;
const DrmProperty &src_w_property() const;
const DrmProperty &src_h_property() const;
+ const DrmProperty &rotation_property() const;
private:
DrmPlane(const DrmPlane &);
@@ -72,6 +73,7 @@
DrmProperty src_y_property_;
DrmProperty src_w_property_;
DrmProperty src_h_property_;
+ DrmProperty rotation_property_;
};
}
diff --git a/glworker.cpp b/glworker.cpp
index e093a73..c737c45 100644
--- a/glworker.cpp
+++ b/glworker.cpp
@@ -453,11 +453,11 @@
return 0;
}
-GLWorker::Compositor::Compositor()
+GLWorkerCompositor::GLWorkerCompositor()
: egl_display_(EGL_NO_DISPLAY), egl_ctx_(EGL_NO_CONTEXT) {
}
-int GLWorker::Compositor::Init() {
+int GLWorkerCompositor::Init() {
int ret = 0;
const char *egl_extensions;
const char *gl_extensions;
@@ -548,14 +548,14 @@
return 0;
}
-GLWorker::Compositor::~Compositor() {
+GLWorkerCompositor::~GLWorkerCompositor() {
if (egl_display_ != EGL_NO_DISPLAY && egl_ctx_ != EGL_NO_CONTEXT)
if (eglDestroyContext(egl_display_, egl_ctx_) == EGL_FALSE)
ALOGE("Failed to destroy OpenGL ES Context: %s", GetEGLError());
}
-int GLWorker::Compositor::Composite(hwc_layer_1 *layers, size_t num_layers,
- sp<GraphicBuffer> framebuffer) {
+int GLWorkerCompositor::Composite(hwc_layer_1 *layers, size_t num_layers,
+ sp<GraphicBuffer> framebuffer) {
ATRACE_CALL();
int ret = 0;
size_t i;
@@ -702,7 +702,7 @@
return ret;
}
-int GLWorker::DoComposition(Compositor &compositor, Work *work) {
+int GLWorker::DoComposition(GLWorkerCompositor &compositor, Work *work) {
int ret =
compositor.Composite(work->layers, work->num_layers, work->framebuffer);
@@ -848,7 +848,7 @@
TRY(pthread_mutex_lock(&lock_), "lock GLThread", return );
- Compositor compositor;
+ GLWorkerCompositor compositor;
TRY(compositor.Init(), "initialize GL", goto out_signal_done);
diff --git a/glworker.h b/glworker.h
index 4ac0e7d..e9febec 100644
--- a/glworker.h
+++ b/glworker.h
@@ -30,6 +30,8 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+#include <ui/GraphicBuffer.h>
+
struct hwc_layer_1;
namespace android {
@@ -77,6 +79,24 @@
}
};
+class GLWorkerCompositor {
+ public:
+ GLWorkerCompositor();
+ ~GLWorkerCompositor();
+
+ int Init();
+
+ int Composite(hwc_layer_1 *layers, size_t num_layers,
+ sp<GraphicBuffer> framebuffer);
+
+ private:
+ EGLDisplay egl_display_;
+ EGLContext egl_ctx_;
+
+ std::vector<AutoGLProgram> blend_programs_;
+ AutoGLBuffer vertex_buffer_;
+};
+
class GLWorker {
public:
struct Work {
@@ -89,24 +109,6 @@
Work(const Work &rhs) = delete;
};
- class Compositor {
- public:
- Compositor();
- ~Compositor();
-
- int Init();
-
- int Composite(hwc_layer_1 *layers, size_t num_layers,
- sp<GraphicBuffer> framebuffer);
-
- private:
- EGLDisplay egl_display_;
- EGLContext egl_ctx_;
-
- std::vector<AutoGLProgram> blend_programs_;
- AutoGLBuffer vertex_buffer_;
- };
-
GLWorker();
~GLWorker();
@@ -126,7 +128,7 @@
int worker_ret_;
void WorkerRoutine();
- int DoComposition(Compositor &compositor, Work *work);
+ int DoComposition(GLWorkerCompositor &compositor, Work *work);
int SignalWorker(Work *work, bool worker_exit);