drm_hwcomposer: have DrmDisplayCompositor do its own OpenGL composition
To accomplish this a few things changed:
- DrmComposition::GetRemainingLayers always returns the number of planes needed
- DrmComposition::AddLayer succeeds even if no DrmPlane was found for it
- DrmDisplayComposition::AddLayer has overload that imports the given buffer
- GLWorkerCompositor has a function to finish its composite before returning
Put together this change makes DrmComposition always accepts all layers given to
it even if it means some of those layers are assigned a NULL DrmPlane. The
DrmDisplayCompositor will scan its given layers for any that are missing planes.
In such a case, a DrmPlane is stolen from the last layer to receive a plane.
Then all layers in the DrmDisplayComposition that have no planes (including the
one stolen from) are composited synchronously using a GLWorkerCompositor and a
new layer is generated from the results. That layer is added to the
DrmDisplayComposition using the new import AddLayer function and the stolen
DrmPlane. DrmDisplayCompostior then continues as usual.
Change-Id: Ia6477c210c8f1307a4e537bec46889110d79ca18
diff --git a/drmframebuffer.h b/drmframebuffer.h
new file mode 100644
index 0000000..6f078d9
--- /dev/null
+++ b/drmframebuffer.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_DRM_FRAMEBUFFER_
+#define ANDROID_DRM_FRAMEBUFFER_
+
+#include <stdint.h>
+
+#include <sync/sync.h>
+
+#include <ui/GraphicBuffer.h>
+
+namespace android {
+
+struct DrmFramebuffer {
+ DrmFramebuffer() : release_fence_fd_(-1) {
+ }
+
+ ~DrmFramebuffer() {
+ if (release_fence_fd() >= 0)
+ close(release_fence_fd());
+ }
+
+ bool is_valid() {
+ return buffer_ != NULL;
+ }
+
+ sp<GraphicBuffer> buffer() {
+ return buffer_;
+ }
+
+ int release_fence_fd() {
+ return release_fence_fd_;
+ }
+
+ void set_release_fence_fd(int fd) {
+ if (release_fence_fd_ >= 0)
+ close(release_fence_fd_);
+ release_fence_fd_ = fd;
+ }
+
+ bool Allocate(uint32_t w, uint32_t h) {
+ if (is_valid()) {
+ if (buffer_->getWidth() == w && buffer_->getHeight() == h)
+ return true;
+
+ if (release_fence_fd_ >= 0) {
+ if (sync_wait(release_fence_fd_, -1) != 0) {
+ return false;
+ }
+ }
+ Clear();
+ }
+ buffer_ = new GraphicBuffer(w, h, PIXEL_FORMAT_RGBA_8888,
+ GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER |
+ GRALLOC_USAGE_HW_COMPOSER);
+ release_fence_fd_ = -1;
+ return is_valid();
+ }
+
+ void Clear() {
+ if (!is_valid())
+ return;
+
+ if (release_fence_fd_ >= 0) {
+ close(release_fence_fd_);
+ release_fence_fd_ = -1;
+ }
+
+ buffer_.clear();
+ }
+
+ int WaitReleased(int timeout_milliseconds) {
+ if (!is_valid())
+ return 0;
+ if (release_fence_fd_ < 0)
+ return 0;
+
+ int ret = sync_wait(release_fence_fd_, timeout_milliseconds);
+ return ret;
+ }
+
+ private:
+ sp<GraphicBuffer> buffer_;
+ int release_fence_fd_;
+};
+}
+
+#endif // ANDROID_DRM_FRAMEBUFFER_