On Fri, May 04, 2018 at 02:18:33PM -0500, Rob Herring wrote: > The GL based compositing adds alot of complexity and was only ever well > tested on closed stacks. It also only supports GLES3.x and still relies > on sw_sync timeline which is now a debugfs feature. Those are just the > known issues. > > Removing the GL compositor means everything related to squashing layers > and pre-compositing can be removed. The planner is left as it may be > useful when adding back support for overlay planes. With this change, > only a single plane is supported until ValidateDisplay learns to do > atomic modesetting test for overlay planes. Hey Rob, Thanks for posting this so quickly, I think it's definitely a step in the right direction. I've posted this as a merge request on gitlab [1] with the reverts squashed into the change. I don't think this will conflict too badly with Alex's work, but I want him to take a look at it first before merging. Sean [1]- https://gitlab.freedesktop.org/drm-hwcomposer/drm-hwcomposer/merge_requests/6 > > Signed-off-by: Rob Herring <robh@xxxxxxxxxx> > --- > I've lightly tested this with virgl. John tested an earlier version on Hikey. > > This depends on reverting these commits: > "drm_hwcomposer: Cleanup gl precompositor init and provide uses_GL flag" > "drm_hwcomposer: Fall back to client compositon if the gl precompostior fails" > > Android.mk | 4 - > autogl.h | 110 ----- > drmcompositorworker.cpp | 78 ---- > drmdisplaycomposition.cpp | 315 +------------- > drmdisplaycomposition.h | 34 +- > drmdisplaycompositor.cpp | 529 +---------------------- > drmdisplaycompositor.h | 56 --- > drmhwctwo.cpp | 6 +- > glworker.cpp | 840 ----------------------------------- > glworker.h | 94 ---- > hwcomposer.cpp | 841 ------------------------------------ > platform.cpp | 93 +--- > platform.h | 49 +-- > platformdrmgeneric.cpp | 17 - > platformdrmgeneric.h | 1 - > platformhisi.cpp | 23 - > platformhisi.h | 1 - > platformminigbm.cpp | 16 - > platformminigbm.h | 1 - > virtualcompositorworker.cpp | 168 ------- > virtualcompositorworker.h | 56 --- > 21 files changed, 21 insertions(+), 3311 deletions(-) > delete mode 100644 autogl.h > delete mode 100644 drmcompositorworker.cpp > delete mode 100644 glworker.cpp > delete mode 100644 glworker.h > delete mode 100644 hwcomposer.cpp > delete mode 100644 virtualcompositorworker.cpp > delete mode 100644 virtualcompositorworker.h > > diff --git a/Android.mk b/Android.mk > index c0a1d0e7cdce..0d05f9c52de5 100644 > --- a/Android.mk > +++ b/Android.mk > @@ -37,8 +37,6 @@ include $(CLEAR_VARS) > LOCAL_SHARED_LIBRARIES := \ > libcutils \ > libdrm \ > - libEGL \ > - libGLESv2 \ > libhardware \ > liblog \ > libsync \ > @@ -63,12 +61,10 @@ LOCAL_SRC_FILES := \ > drmmode.cpp \ > drmplane.cpp \ > drmproperty.cpp \ > - glworker.cpp \ > hwcutils.cpp \ > platform.cpp \ > platformdrmgeneric.cpp \ > separate_rects.cpp \ > - virtualcompositorworker.cpp \ > vsyncworker.cpp > > LOCAL_CPPFLAGS += \ > diff --git a/autogl.h b/autogl.h > deleted file mode 100644 > index fc77fb0c1bf0..000000000000 > --- a/autogl.h > +++ /dev/null > @@ -1,110 +0,0 @@ > -/* > - * 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_AUTO_GL_H_ > -#define ANDROID_AUTO_GL_H_ > - > -#include <memory> > -#define EGL_EGLEXT_PROTOTYPES > -#define GL_GLEXT_PROTOTYPES > - > -#include <EGL/egl.h> > -#include <EGL/eglext.h> > -#include <GLES2/gl2.h> > -#include <GLES2/gl2ext.h> > - > -// TODO(zachr): use hwc_drm_bo to turn buffer handles into textures > -#ifndef EGL_NATIVE_HANDLE_ANDROID_NVX > -#define EGL_NATIVE_HANDLE_ANDROID_NVX 0x322A > -#endif > - > -namespace android { > - > -#define AUTO_GL_TYPE(name, type, zero, deleter) \ > - struct name##Deleter { \ > - typedef type pointer; \ > - \ > - void operator()(pointer p) const { \ > - if (p != zero) { \ > - deleter; \ > - } \ > - } \ > - }; \ > - typedef std::unique_ptr<type, name##Deleter> name; > - > -AUTO_GL_TYPE(AutoGLFramebuffer, GLuint, 0, glDeleteFramebuffers(1, &p)) > -AUTO_GL_TYPE(AutoGLBuffer, GLuint, 0, glDeleteBuffers(1, &p)) > -AUTO_GL_TYPE(AutoGLTexture, GLuint, 0, glDeleteTextures(1, &p)) > -AUTO_GL_TYPE(AutoGLShader, GLint, 0, glDeleteShader(p)) > -AUTO_GL_TYPE(AutoGLProgram, GLint, 0, glDeleteProgram(p)) > - > -struct AutoEGLDisplayImage { > - AutoEGLDisplayImage() = default; > - > - AutoEGLDisplayImage(EGLDisplay display, EGLImageKHR image) > - : display_(display), image_(image) { > - } > - > - AutoEGLDisplayImage(const AutoEGLDisplayImage& rhs) = delete; > - AutoEGLDisplayImage(AutoEGLDisplayImage&& rhs) { > - display_ = rhs.display_; > - image_ = rhs.image_; > - rhs.display_ = EGL_NO_DISPLAY; > - rhs.image_ = EGL_NO_IMAGE_KHR; > - } > - > - ~AutoEGLDisplayImage() { > - clear(); > - } > - > - AutoEGLDisplayImage& operator=(const AutoEGLDisplayImage& rhs) = delete; > - AutoEGLDisplayImage& operator=(AutoEGLDisplayImage&& rhs) { > - clear(); > - std::swap(display_, rhs.display_); > - std::swap(image_, rhs.image_); > - return *this; > - } > - > - void reset(EGLDisplay display, EGLImageKHR image) { > - clear(); > - display_ = display; > - image_ = image; > - } > - > - void clear() { > - if (image_ != EGL_NO_IMAGE_KHR) { > - eglDestroyImageKHR(display_, image_); > - display_ = EGL_NO_DISPLAY; > - image_ = EGL_NO_IMAGE_KHR; > - } > - } > - > - EGLImageKHR image() const { > - return image_; > - } > - > - private: > - EGLDisplay display_ = EGL_NO_DISPLAY; > - EGLImageKHR image_ = EGL_NO_IMAGE_KHR; > -}; > - > -struct AutoEGLImageAndGLTexture { > - AutoEGLDisplayImage image; > - AutoGLTexture texture; > -}; > -} > - > -#endif > diff --git a/drmcompositorworker.cpp b/drmcompositorworker.cpp > deleted file mode 100644 > index 695876d7ae70..000000000000 > --- a/drmcompositorworker.cpp > +++ /dev/null > @@ -1,78 +0,0 @@ > -/* > - * 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. > - */ > - > -#define LOG_TAG "hwc-drm-compositor-worker" > - > -#include "drmdisplaycompositor.h" > -#include "drmcompositorworker.h" > -#include "worker.h" > - > -#include <stdlib.h> > - > -#include <log/log.h> > -#include <hardware/hardware.h> > - > -namespace android { > - > -static const int64_t kSquashWait = 500000000LL; > - > -DrmCompositorWorker::DrmCompositorWorker(DrmDisplayCompositor *compositor) > - : Worker("drm-compositor", HAL_PRIORITY_URGENT_DISPLAY), > - compositor_(compositor) { > -} > - > -DrmCompositorWorker::~DrmCompositorWorker() { > -} > - > -int DrmCompositorWorker::Init() { > - return InitWorker(); > -} > - > -void DrmCompositorWorker::Routine() { > - int ret; > - if (!compositor_->HaveQueuedComposites()) { > - Lock(); > - > - // Only use a timeout if we didn't do a SquashAll last time. This will > - // prevent wait_ret == -ETIMEDOUT which would trigger a SquashAll and be a > - // pointless drain on resources. > - int wait_ret = did_squash_all_ ? WaitForSignalOrExitLocked() > - : WaitForSignalOrExitLocked(kSquashWait); > - Unlock(); > - > - switch (wait_ret) { > - case 0: > - break; > - case -EINTR: > - return; > - case -ETIMEDOUT: > - ret = compositor_->SquashAll(); > - if (ret) > - ALOGE("Failed to squash all %d", ret); > - did_squash_all_ = true; > - return; > - default: > - ALOGE("Failed to wait for signal, %d", wait_ret); > - return; > - } > - } > - > - ret = compositor_->Composite(); > - if (ret) > - ALOGE("Failed to composite! %d", ret); > - did_squash_all_ = false; > -} > -} > diff --git a/drmdisplaycomposition.cpp b/drmdisplaycomposition.cpp > index 24a8e9c9a043..75e01a67564e 100644 > --- a/drmdisplaycomposition.cpp > +++ b/drmdisplaycomposition.cpp > @@ -29,18 +29,12 @@ > #include <unordered_set> > > #include <log/log.h> > -#include <sw_sync.h> > #include <sync/sync.h> > #include <xf86drmMode.h> > > namespace android { > > -DrmDisplayComposition::~DrmDisplayComposition() { > - if (timeline_fd_ >= 0) { > - SignalCompositionDone(); > - close(timeline_fd_); > - } > -} > +DrmDisplayComposition::~DrmDisplayComposition() {} > > int DrmDisplayComposition::Init(DrmResources *drm, DrmCrtc *crtc, > Importer *importer, Planner *planner, > @@ -51,12 +45,6 @@ int DrmDisplayComposition::Init(DrmResources *drm, DrmCrtc *crtc, > planner_ = planner; > frame_no_ = frame_no; > > - int ret = sw_sync_timeline_create(); > - if (ret < 0) { > - ALOGE("Failed to create sw sync timeline %d", ret); > - return ret; > - } > - timeline_fd_ = ret; > return 0; > } > > @@ -64,26 +52,6 @@ bool DrmDisplayComposition::validate_composition_type(DrmCompositionType des) { > return type_ == DRM_COMPOSITION_TYPE_EMPTY || type_ == des; > } > > -int DrmDisplayComposition::CreateNextTimelineFence() { > - ++timeline_; > - return sw_sync_fence_create(timeline_fd_, "hwc drm display composition fence", > - timeline_); > -} > - > -int DrmDisplayComposition::IncreaseTimelineToPoint(int point) { > - int timeline_increase = point - timeline_current_; > - if (timeline_increase <= 0) > - return 0; > - > - int ret = sw_sync_timeline_inc(timeline_fd_, timeline_increase); > - if (ret) > - ALOGE("Failed to increment sync timeline %d", ret); > - else > - timeline_current_ = point; > - > - return ret; > -} > - > int DrmDisplayComposition::SetLayers(DrmHwcLayer *layers, size_t num_layers, > bool geometry_changed) { > if (!validate_composition_type(DRM_COMPOSITION_TYPE_FRAME)) > @@ -122,252 +90,38 @@ int DrmDisplayComposition::AddPlaneDisable(DrmPlane *plane) { > return 0; > } > > -static std::vector<size_t> SetBitsToVector( > - uint64_t in, const std::vector<size_t> &index_map) { > - std::vector<size_t> out; > - size_t msb = sizeof(in) * 8 - 1; > - uint64_t mask = (uint64_t)1 << msb; > - for (size_t i = msb; mask != (uint64_t)0; i--, mask >>= 1) > - if (in & mask) > - out.push_back(index_map[i]); > - return out; > -} > - > int DrmDisplayComposition::AddPlaneComposition(DrmCompositionPlane plane) { > composition_planes_.emplace_back(std::move(plane)); > return 0; > } > > -void DrmDisplayComposition::SeparateLayers(DrmHwcRect<int> *exclude_rects, > - size_t num_exclude_rects) { > - DrmCompositionPlane *comp = NULL; > +void DrmDisplayComposition::SeparateLayers(DrmHwcRect<int> *, > + size_t ) { > std::vector<size_t> dedicated_layers; > > - // Go through the composition and find the precomp layer as well as any > - // layers that have a dedicated plane located below the precomp layer. > + // Go through the composition and find the layers that have a dedicated plane. > for (auto &i : composition_planes_) { > if (i.type() == DrmCompositionPlane::Type::kLayer) { > dedicated_layers.insert(dedicated_layers.end(), i.source_layers().begin(), > i.source_layers().end()); > - } else if (i.type() == DrmCompositionPlane::Type::kPrecomp) { > - comp = &i; > - break; > - } > - } > - if (!comp) > - return; > - > - const std::vector<size_t> &comp_layers = comp->source_layers(); > - if (comp_layers.size() > 64) { > - ALOGE("Failed to separate layers because there are more than 64"); > - return; > - } > - > - // Index at which the actual layers begin > - size_t layer_offset = num_exclude_rects + dedicated_layers.size(); > - if (comp_layers.size() + layer_offset > 64) { > - ALOGW( > - "Exclusion rectangles are being truncated to make the rectangle count " > - "fit into 64"); > - num_exclude_rects = 64 - comp_layers.size() - dedicated_layers.size(); > - } > - > - // We inject all the exclude rects into the rects list. Any resulting rect > - // that includes ANY of the first num_exclude_rects is rejected. After the > - // exclude rects, we add the lower layers. The rects that intersect with > - // these layers will be inspected and only those which are to be composited > - // above the layer will be included in the composition regions. > - std::vector<DrmHwcRect<int>> layer_rects(comp_layers.size() + layer_offset); > - std::copy(exclude_rects, exclude_rects + num_exclude_rects, > - layer_rects.begin()); > - std::transform( > - dedicated_layers.begin(), dedicated_layers.end(), > - layer_rects.begin() + num_exclude_rects, > - [=](size_t layer_index) { return layers_[layer_index].display_frame; }); > - std::transform(comp_layers.begin(), comp_layers.end(), > - layer_rects.begin() + layer_offset, [=](size_t layer_index) { > - return layers_[layer_index].display_frame; > - }); > - > - std::vector<separate_rects::RectSet<uint64_t, int>> separate_regions; > - separate_rects::separate_rects_64(layer_rects, &separate_regions); > - uint64_t exclude_mask = ((uint64_t)1 << num_exclude_rects) - 1; > - uint64_t dedicated_mask = (((uint64_t)1 << dedicated_layers.size()) - 1) > - << num_exclude_rects; > - > - for (separate_rects::RectSet<uint64_t, int> ®ion : separate_regions) { > - if (region.id_set.getBits() & exclude_mask) > - continue; > - > - // If a rect intersects one of the dedicated layers, we need to remove the > - // layers from the composition region which appear *below* the dedicated > - // layer. This effectively punches a hole through the composition layer such > - // that the dedicated layer can be placed below the composition and not > - // be occluded. > - uint64_t dedicated_intersect = region.id_set.getBits() & dedicated_mask; > - for (size_t i = 0; dedicated_intersect && i < dedicated_layers.size(); > - ++i) { > - // Only exclude layers if they intersect this particular dedicated layer > - if (!(dedicated_intersect & (1 << (i + num_exclude_rects)))) > - continue; > - > - for (size_t j = 0; j < comp_layers.size(); ++j) { > - if (comp_layers[j] < dedicated_layers[i]) > - region.id_set.subtract(j + layer_offset); > - } > } > - if (!(region.id_set.getBits() >> layer_offset)) > - continue; > - > - pre_comp_regions_.emplace_back(DrmCompositionRegion{ > - region.rect, > - SetBitsToVector(region.id_set.getBits() >> layer_offset, comp_layers)}); > } > } > > -int DrmDisplayComposition::CreateAndAssignReleaseFences() { > - std::unordered_set<DrmHwcLayer *> squash_layers; > - std::unordered_set<DrmHwcLayer *> pre_comp_layers; > - std::unordered_set<DrmHwcLayer *> comp_layers; > - > - for (const DrmCompositionRegion ®ion : squash_regions_) { > - for (size_t source_layer_index : region.source_layers) { > - DrmHwcLayer *source_layer = &layers_[source_layer_index]; > - squash_layers.emplace(source_layer); > - } > - } > - > - for (const DrmCompositionRegion ®ion : pre_comp_regions_) { > - for (size_t source_layer_index : region.source_layers) { > - DrmHwcLayer *source_layer = &layers_[source_layer_index]; > - pre_comp_layers.emplace(source_layer); > - squash_layers.erase(source_layer); > - } > - } > - > - for (const DrmCompositionPlane &plane : composition_planes_) { > - if (plane.type() == DrmCompositionPlane::Type::kLayer) { > - for (auto i : plane.source_layers()) { > - DrmHwcLayer *source_layer = &layers_[i]; > - comp_layers.emplace(source_layer); > - pre_comp_layers.erase(source_layer); > - } > - } > - } > - > - for (DrmHwcLayer *layer : squash_layers) { > - if (!layer->release_fence) > - continue; > - int ret = layer->release_fence.Set(CreateNextTimelineFence()); > - if (ret < 0) { > - ALOGE("Failed to set the release fence (squash) %d", ret); > - return ret; > - } > - } > - timeline_squash_done_ = timeline_; > - > - for (DrmHwcLayer *layer : pre_comp_layers) { > - if (!layer->release_fence) > - continue; > - int ret = layer->release_fence.Set(CreateNextTimelineFence()); > - if (ret < 0) > - return ret; > - } > - timeline_pre_comp_done_ = timeline_; > - > - for (DrmHwcLayer *layer : comp_layers) { > - if (!layer->release_fence) > - continue; > - int ret = layer->release_fence.Set(CreateNextTimelineFence()); > - if (ret < 0) { > - ALOGE("Failed to set the release fence (comp) %d", ret); > - return ret; > - } > - } > - > - return 0; > -} > - > -int DrmDisplayComposition::Plan(SquashState *squash, > - std::vector<DrmPlane *> *primary_planes, > +int DrmDisplayComposition::Plan(std::vector<DrmPlane *> *primary_planes, > std::vector<DrmPlane *> *overlay_planes) { > if (type_ != DRM_COMPOSITION_TYPE_FRAME) > return 0; > > - // Used to track which layers should be sent to the planner. We exclude layers > - // that are entirely squashed so the planner can provision a precomposition > - // layer as appropriate (ex: if 5 layers are squashed and 1 is not, we don't > - // want to plan a precomposition layer that will be comprised of the already > - // squashed layers). > std::map<size_t, DrmHwcLayer *> to_composite; > > - bool use_squash_framebuffer = false; > - // Used to determine which layers were entirely squashed > - std::vector<int> layer_squash_area(layers_.size(), 0); > - // Used to avoid rerendering regions that were squashed > - std::vector<DrmHwcRect<int>> exclude_rects; > - if (squash != NULL) { > - if (geometry_changed_) { > - squash->Init(layers_.data(), layers_.size()); > - } else { > - std::vector<bool> changed_regions; > - squash->GenerateHistory(layers_.data(), layers_.size(), changed_regions); > - > - std::vector<bool> stable_regions; > - squash->StableRegionsWithMarginalHistory(changed_regions, stable_regions); > - > - // Only if SOME region is stable > - use_squash_framebuffer = > - std::find(stable_regions.begin(), stable_regions.end(), true) != > - stable_regions.end(); > - > - squash->RecordHistory(layers_.data(), layers_.size(), changed_regions); > - > - // Changes in which regions are squashed triggers a rerender via > - // squash_regions. > - bool render_squash = squash->RecordAndCompareSquashed(stable_regions); > - > - for (size_t region_index = 0; region_index < stable_regions.size(); > - region_index++) { > - const SquashState::Region ®ion = squash->regions()[region_index]; > - if (!stable_regions[region_index]) > - continue; > - > - exclude_rects.emplace_back(region.rect); > - > - if (render_squash) { > - squash_regions_.emplace_back(); > - squash_regions_.back().frame = region.rect; > - } > - > - int frame_area = region.rect.area(); > - // Source layers are sorted front to back i.e. top layer has lowest > - // index. > - for (size_t layer_index = layers_.size(); > - layer_index-- > 0; // Yes, I double checked this > - /* See condition */) { > - if (!region.layer_refs[layer_index]) > - continue; > - layer_squash_area[layer_index] += frame_area; > - if (render_squash) > - squash_regions_.back().source_layers.push_back(layer_index); > - } > - } > - } > - > - for (size_t i = 0; i < layers_.size(); ++i) { > - if (layer_squash_area[i] < layers_[i].display_frame.area()) > - to_composite.emplace(std::make_pair(i, &layers_[i])); > - } > - } else { > - for (size_t i = 0; i < layers_.size(); ++i) > - to_composite.emplace(std::make_pair(i, &layers_[i])); > - } > + for (size_t i = 0; i < layers_.size(); ++i) > + to_composite.emplace(std::make_pair(i, &layers_[i])); > > int ret; > std::vector<DrmCompositionPlane> plan; > std::tie(ret, composition_planes_) = > - planner_->ProvisionPlanes(to_composite, use_squash_framebuffer, crtc_, > + planner_->ProvisionPlanes(to_composite, crtc_, > primary_planes, overlay_planes); > if (ret) { > ALOGE("Planner failed provisioning planes ret=%d", ret); > @@ -396,17 +150,7 @@ int DrmDisplayComposition::Plan(SquashState *squash, > } > } > > - return FinalizeComposition(exclude_rects.data(), exclude_rects.size()); > -} > - > -int DrmDisplayComposition::FinalizeComposition() { > - return FinalizeComposition(NULL, 0); > -} > - > -int DrmDisplayComposition::FinalizeComposition(DrmHwcRect<int> *exclude_rects, > - size_t num_exclude_rects) { > - SeparateLayers(exclude_rects, num_exclude_rects); > - return CreateAndAssignReleaseFences(); > + return 0; > } > > static const char *DrmCompositionTypeToString(DrmCompositionType type) { > @@ -506,23 +250,6 @@ static const char *BlendingToString(DrmHwcBlending blending) { > } > } > > -static void DumpRegion(const DrmCompositionRegion ®ion, > - std::ostringstream *out) { > - *out << "frame"; > - region.frame.Dump(out); > - *out << " source_layers=("; > - > - const std::vector<size_t> &source_layers = region.source_layers; > - for (size_t i = 0; i < source_layers.size(); i++) { > - *out << source_layers[i]; > - if (i < source_layers.size() - 1) { > - *out << " "; > - } > - } > - > - *out << ")"; > -} > - > void DrmDisplayComposition::Dump(std::ostringstream *out) const { > *out << "----DrmDisplayComposition" > << " crtc=" << (crtc_ ? crtc_->id() : -1) > @@ -540,10 +267,6 @@ void DrmDisplayComposition::Dump(std::ostringstream *out) const { > break; > } > > - *out << " timeline[current/squash/pre-comp/done]=" << timeline_current_ << "/" > - << timeline_squash_done_ << "/" << timeline_pre_comp_done_ << "/" > - << timeline_ << "\n"; > - > *out << " Layers: count=" << layers_.size() << "\n"; > for (size_t i = 0; i < layers_.size(); i++) { > const DrmHwcLayer &layer = layers_[i]; > @@ -578,12 +301,6 @@ void DrmDisplayComposition::Dump(std::ostringstream *out) const { > case DrmCompositionPlane::Type::kLayer: > *out << "LAYER"; > break; > - case DrmCompositionPlane::Type::kPrecomp: > - *out << "PRECOMP"; > - break; > - case DrmCompositionPlane::Type::kSquash: > - *out << "SQUASH"; > - break; > default: > *out << "<invalid>"; > break; > @@ -595,19 +312,5 @@ void DrmDisplayComposition::Dump(std::ostringstream *out) const { > } > *out << "\n"; > } > - > - *out << " Squash Regions: count=" << squash_regions_.size() << "\n"; > - for (size_t i = 0; i < squash_regions_.size(); i++) { > - *out << " [" << i << "] "; > - DumpRegion(squash_regions_[i], out); > - *out << "\n"; > - } > - > - *out << " Pre-Comp Regions: count=" << pre_comp_regions_.size() << "\n"; > - for (size_t i = 0; i < pre_comp_regions_.size(); i++) { > - *out << " [" << i << "] "; > - DumpRegion(pre_comp_regions_[i], out); > - *out << "\n"; > - } > } > } > diff --git a/drmdisplaycomposition.h b/drmdisplaycomposition.h > index 918392578753..b7fccb9cd283 100644 > --- a/drmdisplaycomposition.h > +++ b/drmdisplaycomposition.h > @@ -20,7 +20,6 @@ > #include "drmcrtc.h" > #include "drmhwcomposer.h" > #include "drmplane.h" > -#include "glworker.h" > > #include <sstream> > #include <vector> > @@ -62,8 +61,6 @@ class DrmCompositionPlane { > enum class Type : int32_t { > kDisable, > kLayer, > - kPrecomp, > - kSquash, > }; > > DrmCompositionPlane() = default; > @@ -125,34 +122,15 @@ class DrmDisplayComposition { > int SetDpmsMode(uint32_t dpms_mode); > int SetDisplayMode(const DrmMode &display_mode); > > - int Plan(SquashState *squash, std::vector<DrmPlane *> *primary_planes, > + int Plan(std::vector<DrmPlane *> *primary_planes, > std::vector<DrmPlane *> *overlay_planes); > > int FinalizeComposition(); > > - int CreateNextTimelineFence(); > - int SignalSquashDone() { > - return IncreaseTimelineToPoint(timeline_squash_done_); > - } > - int SignalPreCompDone() { > - return IncreaseTimelineToPoint(timeline_pre_comp_done_); > - } > - int SignalCompositionDone() { > - return IncreaseTimelineToPoint(timeline_); > - } > - > std::vector<DrmHwcLayer> &layers() { > return layers_; > } > > - std::vector<DrmCompositionRegion> &squash_regions() { > - return squash_regions_; > - } > - > - std::vector<DrmCompositionRegion> &pre_comp_regions() { > - return pre_comp_regions_; > - } > - > std::vector<DrmCompositionPlane> &composition_planes() { > return composition_planes_; > } > @@ -202,12 +180,9 @@ class DrmDisplayComposition { > private: > bool validate_composition_type(DrmCompositionType desired); > > - int IncreaseTimelineToPoint(int point); > - > int FinalizeComposition(DrmHwcRect<int> *exclude_rects, > size_t num_exclude_rects); > void SeparateLayers(DrmHwcRect<int> *exclude_rects, size_t num_exclude_rects); > - int CreateAndAssignReleaseFences(); > > DrmResources *drm_ = NULL; > DrmCrtc *crtc_ = NULL; > @@ -218,17 +193,10 @@ class DrmDisplayComposition { > uint32_t dpms_mode_ = DRM_MODE_DPMS_ON; > DrmMode display_mode_; > > - int timeline_fd_ = -1; > - int timeline_ = 0; > - int timeline_current_ = 0; > - int timeline_squash_done_ = 0; > - int timeline_pre_comp_done_ = 0; > UniqueFd out_fence_ = -1; > > bool geometry_changed_; > std::vector<DrmHwcLayer> layers_; > - std::vector<DrmCompositionRegion> squash_regions_; > - std::vector<DrmCompositionRegion> pre_comp_regions_; > std::vector<DrmCompositionPlane> composition_planes_; > > uint64_t frame_no_ = 0; > diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp > index e570923de942..34a729924fc6 100644 > --- a/drmdisplaycompositor.cpp > +++ b/drmdisplaycompositor.cpp > @@ -35,153 +35,15 @@ > #include "drmcrtc.h" > #include "drmplane.h" > #include "drmresources.h" > -#include "glworker.h" > > namespace android { > > -void SquashState::Init(DrmHwcLayer *layers, size_t num_layers) { > - generation_number_++; > - valid_history_ = 0; > - regions_.clear(); > - last_handles_.clear(); > - > - std::vector<DrmHwcRect<int>> in_rects; > - for (size_t i = 0; i < num_layers; i++) { > - DrmHwcLayer *layer = &layers[i]; > - in_rects.emplace_back(layer->display_frame); > - last_handles_.push_back(layer->sf_handle); > - } > - > - std::vector<separate_rects::RectSet<uint64_t, int>> out_regions; > - separate_rects::separate_rects_64(in_rects, &out_regions); > - > - for (const separate_rects::RectSet<uint64_t, int> &out_region : out_regions) { > - regions_.emplace_back(); > - Region ®ion = regions_.back(); > - region.rect = out_region.rect; > - region.layer_refs = out_region.id_set.getBits(); > - } > -} > - > -void SquashState::GenerateHistory(DrmHwcLayer *layers, size_t num_layers, > - std::vector<bool> &changed_regions) const { > - changed_regions.resize(regions_.size()); > - if (num_layers != last_handles_.size()) { > - ALOGE("SquashState::GenerateHistory expected %zu layers but got %zu layers", > - last_handles_.size(), num_layers); > - return; > - } > - std::bitset<kMaxLayers> changed_layers; > - for (size_t i = 0; i < last_handles_.size(); i++) { > - DrmHwcLayer *layer = &layers[i]; > - // Protected layers can't be squashed so we treat them as constantly > - // changing. > - if (layer->protected_usage() || last_handles_[i] != layer->sf_handle) > - changed_layers.set(i); > - } > - > - for (size_t i = 0; i < regions_.size(); i++) { > - changed_regions[i] = (regions_[i].layer_refs & changed_layers).any(); > - } > -} > - > -void SquashState::StableRegionsWithMarginalHistory( > - const std::vector<bool> &changed_regions, > - std::vector<bool> &stable_regions) const { > - stable_regions.resize(regions_.size()); > - for (size_t i = 0; i < regions_.size(); i++) { > - stable_regions[i] = !changed_regions[i] && is_stable(i); > - } > -} > - > -void SquashState::RecordHistory(DrmHwcLayer *layers, size_t num_layers, > - const std::vector<bool> &changed_regions) { > - if (num_layers != last_handles_.size()) { > - ALOGE("SquashState::RecordHistory expected %zu layers but got %zu layers", > - last_handles_.size(), num_layers); > - return; > - } > - if (changed_regions.size() != regions_.size()) { > - ALOGE("SquashState::RecordHistory expected %zu regions but got %zu regions", > - regions_.size(), changed_regions.size()); > - return; > - } > - > - for (size_t i = 0; i < last_handles_.size(); i++) { > - DrmHwcLayer *layer = &layers[i]; > - last_handles_[i] = layer->sf_handle; > - } > - > - for (size_t i = 0; i < regions_.size(); i++) { > - regions_[i].change_history <<= 1; > - regions_[i].change_history.set(/* LSB */ 0, changed_regions[i]); > - } > - > - valid_history_++; > -} > - > -bool SquashState::RecordAndCompareSquashed( > - const std::vector<bool> &squashed_regions) { > - if (squashed_regions.size() != regions_.size()) { > - ALOGE( > - "SquashState::RecordAndCompareSquashed expected %zu regions but got " > - "%zu regions", > - regions_.size(), squashed_regions.size()); > - return false; > - } > - bool changed = false; > - for (size_t i = 0; i < regions_.size(); i++) { > - if (regions_[i].squashed != squashed_regions[i]) { > - regions_[i].squashed = squashed_regions[i]; > - changed = true; > - } > - } > - return changed; > -} > - > -void SquashState::Dump(std::ostringstream *out) const { > - *out << "----SquashState generation=" << generation_number_ > - << " history=" << valid_history_ << "\n" > - << " Regions: count=" << regions_.size() << "\n"; > - for (size_t i = 0; i < regions_.size(); i++) { > - const Region ®ion = regions_[i]; > - *out << " [" << i << "]" > - << " history=" << region.change_history << " rect"; > - region.rect.Dump(out); > - *out << " layers=("; > - bool first = true; > - for (size_t layer_index = 0; layer_index < kMaxLayers; layer_index++) { > - if ((region.layer_refs & > - std::bitset<kMaxLayers>((size_t)1 << layer_index)) > - .any()) { > - if (!first) > - *out << " "; > - first = false; > - *out << layer_index; > - } > - } > - *out << ")"; > - if (region.squashed) > - *out << " squashed"; > - *out << "\n"; > - } > -} > - > -static bool UsesSquash(const std::vector<DrmCompositionPlane> &comp_planes) { > - return std::any_of(comp_planes.begin(), comp_planes.end(), > - [](const DrmCompositionPlane &plane) { > - return plane.type() == DrmCompositionPlane::Type::kSquash; > - }); > -} > - > DrmDisplayCompositor::DrmDisplayCompositor() > : drm_(NULL), > display_(-1), > initialized_(false), > active_(false), > use_hw_overlays_(true), > - framebuffer_index_(0), > - squash_framebuffer_index_(0), > dump_frames_composited_(0), > dump_last_timestamp_ns_(0) { > struct timespec ts; > @@ -244,112 +106,6 @@ DrmDisplayCompositor::GetActiveModeResolution() { > return std::make_tuple(mode.h_display(), mode.v_display(), 0); > } > > -int DrmDisplayCompositor::PrepareFramebuffer( > - DrmFramebuffer &fb, DrmDisplayComposition *display_comp) { > - int ret = fb.WaitReleased(-1); > - if (ret) { > - ALOGE("Failed to wait for framebuffer release %d", ret); > - return ret; > - } > - uint32_t width, height; > - std::tie(width, height, ret) = GetActiveModeResolution(); > - if (ret) { > - ALOGE( > - "Failed to allocate framebuffer because the display resolution could " > - "not be determined %d", > - ret); > - return ret; > - } > - > - fb.set_release_fence_fd(-1); > - if (!fb.Allocate(width, height)) { > - ALOGE("Failed to allocate framebuffer with size %dx%d", width, height); > - return -ENOMEM; > - } > - > - display_comp->layers().emplace_back(); > - DrmHwcLayer &pre_comp_layer = display_comp->layers().back(); > - pre_comp_layer.sf_handle = fb.buffer()->handle; > - pre_comp_layer.blending = DrmHwcBlending::kPreMult; > - pre_comp_layer.source_crop = DrmHwcRect<float>(0, 0, width, height); > - pre_comp_layer.display_frame = DrmHwcRect<int>(0, 0, width, height); > - ret = pre_comp_layer.buffer.ImportBuffer(fb.buffer()->handle, > - display_comp->importer()); > - if (ret) { > - ALOGE("Failed to import framebuffer for display %d", ret); > - return ret; > - } > - > - return ret; > -} > - > -int DrmDisplayCompositor::ApplySquash(DrmDisplayComposition *display_comp) { > - int ret = 0; > - > - DrmFramebuffer &fb = squash_framebuffers_[squash_framebuffer_index_]; > - ret = PrepareFramebuffer(fb, display_comp); > - if (ret) { > - ALOGE("Failed to prepare framebuffer for squash %d", ret); > - return ret; > - } > - > - std::vector<DrmCompositionRegion> ®ions = display_comp->squash_regions(); > - ret = pre_compositor_->Composite(display_comp->layers().data(), > - regions.data(), regions.size(), fb.buffer(), > - display_comp->importer()); > - pre_compositor_->Finish(); > - > - if (ret) { > - ALOGE("Failed to squash layers"); > - return ret; > - } > - > - ret = display_comp->CreateNextTimelineFence(); > - if (ret <= 0) { > - ALOGE("Failed to create squash framebuffer release fence %d", ret); > - return ret; > - } > - > - fb.set_release_fence_fd(ret); > - display_comp->SignalSquashDone(); > - > - return 0; > -} > - > -int DrmDisplayCompositor::ApplyPreComposite( > - DrmDisplayComposition *display_comp) { > - int ret = 0; > - > - DrmFramebuffer &fb = framebuffers_[framebuffer_index_]; > - ret = PrepareFramebuffer(fb, display_comp); > - if (ret) { > - ALOGE("Failed to prepare framebuffer for pre-composite %d", ret); > - return ret; > - } > - > - std::vector<DrmCompositionRegion> ®ions = display_comp->pre_comp_regions(); > - ret = pre_compositor_->Composite(display_comp->layers().data(), > - regions.data(), regions.size(), fb.buffer(), > - display_comp->importer()); > - pre_compositor_->Finish(); > - > - if (ret) { > - ALOGE("Failed to pre-composite layers"); > - return ret; > - } > - > - ret = display_comp->CreateNextTimelineFence(); > - if (ret <= 0) { > - ALOGE("Failed to create pre-composite framebuffer release fence %d", ret); > - return ret; > - } > - > - fb.set_release_fence_fd(ret); > - display_comp->SignalPreCompDone(); > - > - return 0; > -} > - > int DrmDisplayCompositor::DisablePlanes(DrmDisplayComposition *display_comp) { > drmModeAtomicReqPtr pset = drmModeAtomicAlloc(); > if (!pset) { > @@ -384,103 +140,6 @@ int DrmDisplayCompositor::DisablePlanes(DrmDisplayComposition *display_comp) { > return 0; > } > > -int DrmDisplayCompositor::PrepareFrame(DrmDisplayComposition *display_comp) { > - int ret = 0; > - > - std::vector<DrmHwcLayer> &layers = display_comp->layers(); > - std::vector<DrmCompositionPlane> &comp_planes = > - display_comp->composition_planes(); > - std::vector<DrmCompositionRegion> &squash_regions = > - display_comp->squash_regions(); > - std::vector<DrmCompositionRegion> &pre_comp_regions = > - display_comp->pre_comp_regions(); > - > - if (!pre_compositor_) { > - pre_compositor_.reset(new GLWorkerCompositor()); > - int ret = pre_compositor_->Init(); > - if (ret) { > - ALOGE("Failed to initialize OpenGL compositor %d", ret); > - return ret; > - } > - } > - > - int squash_layer_index = -1; > - if (squash_regions.size() > 0) { > - squash_framebuffer_index_ = (squash_framebuffer_index_ + 1) % 2; > - ret = ApplySquash(display_comp); > - if (ret) > - return ret; > - > - squash_layer_index = layers.size() - 1; > - } else { > - if (UsesSquash(comp_planes)) { > - DrmFramebuffer &fb = squash_framebuffers_[squash_framebuffer_index_]; > - layers.emplace_back(); > - squash_layer_index = layers.size() - 1; > - DrmHwcLayer &squash_layer = layers.back(); > - ret = squash_layer.buffer.ImportBuffer(fb.buffer()->handle, > - display_comp->importer()); > - if (ret) { > - ALOGE("Failed to import old squashed framebuffer %d", ret); > - return ret; > - } > - squash_layer.sf_handle = fb.buffer()->handle; > - squash_layer.blending = DrmHwcBlending::kPreMult; > - squash_layer.source_crop = DrmHwcRect<float>( > - 0, 0, squash_layer.buffer->width, squash_layer.buffer->height); > - squash_layer.display_frame = DrmHwcRect<int>( > - 0, 0, squash_layer.buffer->width, squash_layer.buffer->height); > - ret = display_comp->CreateNextTimelineFence(); > - > - if (ret <= 0) { > - ALOGE("Failed to create squash framebuffer release fence %d", ret); > - return ret; > - } > - > - fb.set_release_fence_fd(ret); > - ret = 0; > - } > - } > - > - bool do_pre_comp = pre_comp_regions.size() > 0; > - int pre_comp_layer_index = -1; > - if (do_pre_comp) { > - ret = ApplyPreComposite(display_comp); > - if (ret) > - return ret; > - > - pre_comp_layer_index = layers.size() - 1; > - framebuffer_index_ = (framebuffer_index_ + 1) % DRM_DISPLAY_BUFFERS; > - } > - > - for (DrmCompositionPlane &comp_plane : comp_planes) { > - std::vector<size_t> &source_layers = comp_plane.source_layers(); > - switch (comp_plane.type()) { > - case DrmCompositionPlane::Type::kSquash: > - if (source_layers.size()) > - ALOGE("Squash source_layers is expected to be empty (%zu/%d)", > - source_layers[0], squash_layer_index); > - source_layers.push_back(squash_layer_index); > - break; > - case DrmCompositionPlane::Type::kPrecomp: > - if (!do_pre_comp) { > - ALOGE( > - "Can not use pre composite framebuffer with no pre composite " > - "regions"); > - return -EINVAL; > - } > - // Replace source_layers with the output of the precomposite > - source_layers.clear(); > - source_layers.push_back(pre_comp_layer_index); > - break; > - default: > - break; > - } > - } > - > - return ret; > -} > - > int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, > bool test_only) { > ATRACE_CALL(); > @@ -778,8 +437,6 @@ void DrmDisplayCompositor::ClearDisplay() { > if (DisablePlanes(active_composition_.get())) > return; > > - active_composition_->SignalCompositionDone(); > - > active_composition_.reset(NULL); > } > > @@ -799,9 +456,6 @@ void DrmDisplayCompositor::ApplyFrame( > } > ++dump_frames_composited_; > > - if (active_composition_) > - active_composition_->SignalCompositionDone(); > - > ret = pthread_mutex_lock(&lock_); > if (ret) > ALOGE("Failed to acquire lock for active_composition swap"); > @@ -819,38 +473,16 @@ int DrmDisplayCompositor::ApplyComposition( > int ret = 0; > switch (composition->type()) { > case DRM_COMPOSITION_TYPE_FRAME: > - ret = PrepareFrame(composition.get()); > - if (ret) { > - ALOGE("Failed to prepare frame for display %d", display_); > - return ret; > - } > if (composition->geometry_changed()) { > // Send the composition to the kernel to ensure we can commit it. This > - // is just a test, it won't actually commit the frame. If rejected, > - // squash the frame into one layer and use the squashed composition > + // is just a test, it won't actually commit the frame. > ret = CommitFrame(composition.get(), true); > - if (ret) > - ALOGI("Commit test failed, squashing frame for display %d", display_); > - use_hw_overlays_ = !ret; > - } > - > - // If use_hw_overlays_ is false, we can't use hardware to composite the > - // frame. So squash all layers into a single composition and apply that > - // instead. > - if (!use_hw_overlays_) { > - std::unique_ptr<DrmDisplayComposition> squashed = CreateComposition(); > - ret = SquashFrame(composition.get(), squashed.get()); > - if (!ret) { > - composition = std::move(squashed); > - } else { > - ALOGE("Failed to squash frame for display %d", display_); > - // Disable the hw used by the last active composition. This allows us > - // to signal the release fences from that composition to avoid > - // hanging. > - ClearDisplay(); > + if (ret) { > + ALOGE("Commit test failed for display %d, FIXME", display_); > return ret; > } > } > + > ApplyFrame(std::move(composition), ret); > break; > case DRM_COMPOSITION_TYPE_DPMS: > @@ -878,154 +510,6 @@ int DrmDisplayCompositor::ApplyComposition( > return ret; > } > > -int DrmDisplayCompositor::SquashAll() { > - AutoLock lock(&lock_, "compositor"); > - int ret = lock.Lock(); > - if (ret) > - return ret; > - > - if (!active_composition_) > - return 0; > - > - std::unique_ptr<DrmDisplayComposition> comp = CreateComposition(); > - ret = SquashFrame(active_composition_.get(), comp.get()); > - > - // ApplyFrame needs the lock > - lock.Unlock(); > - > - if (!ret) > - ApplyFrame(std::move(comp), 0); > - > - return ret; > -} > - > -// Returns: > -// - 0 if src is successfully squashed into dst > -// - -EALREADY if the src is already squashed > -// - Appropriate error if the squash fails > -int DrmDisplayCompositor::SquashFrame(DrmDisplayComposition *src, > - DrmDisplayComposition *dst) { > - if (src->type() != DRM_COMPOSITION_TYPE_FRAME) > - return -ENOTSUP; > - > - std::vector<DrmCompositionPlane> &src_planes = src->composition_planes(); > - std::vector<DrmHwcLayer> &src_layers = src->layers(); > - > - // Make sure there is more than one layer to squash. > - size_t src_planes_with_layer = std::count_if( > - src_planes.begin(), src_planes.end(), [](DrmCompositionPlane &p) { > - return p.type() != DrmCompositionPlane::Type::kDisable; > - }); > - if (src_planes_with_layer <= 1) > - return -EALREADY; > - > - int pre_comp_layer_index; > - > - int ret = dst->Init(drm_, src->crtc(), src->importer(), src->planner(), > - src->frame_no()); > - if (ret) { > - ALOGE("Failed to init squash all composition %d", ret); > - return ret; > - } > - > - DrmCompositionPlane squashed_comp(DrmCompositionPlane::Type::kPrecomp, NULL, > - src->crtc()); > - std::vector<DrmHwcLayer> dst_layers; > - for (DrmCompositionPlane &comp_plane : src_planes) { > - // Composition planes without DRM planes should never happen > - if (comp_plane.plane() == NULL) { > - ALOGE("Skipping squash all because of NULL plane"); > - ret = -EINVAL; > - goto move_layers_back; > - } > - > - if (comp_plane.plane()->type() == DRM_PLANE_TYPE_PRIMARY) > - squashed_comp.set_plane(comp_plane.plane()); > - else > - dst->AddPlaneDisable(comp_plane.plane()); > - > - if (comp_plane.type() == DrmCompositionPlane::Type::kDisable) > - continue; > - > - for (auto i : comp_plane.source_layers()) { > - DrmHwcLayer &layer = src_layers[i]; > - > - // Squashing protected layers is impossible. > - if (layer.protected_usage()) { > - ret = -ENOTSUP; > - goto move_layers_back; > - } > - > - // The OutputFds point to freed memory after hwc_set returns. They are > - // returned to the default to prevent DrmDisplayComposition::Plan from > - // filling the OutputFds. > - layer.release_fence = OutputFd(); > - dst_layers.emplace_back(std::move(layer)); > - squashed_comp.source_layers().push_back( > - squashed_comp.source_layers().size()); > - } > - } > - > - if (squashed_comp.plane() == NULL) { > - ALOGE("Primary plane not found for squash"); > - ret = -ENOTSUP; > - goto move_layers_back; > - } > - > - ret = dst->SetLayers(dst_layers.data(), dst_layers.size(), false); > - if (ret) { > - ALOGE("Failed to set layers for squash all composition %d", ret); > - goto move_layers_back; > - } > - > - ret = dst->AddPlaneComposition(std::move(squashed_comp)); > - if (ret) { > - ALOGE("Failed to add squashed plane composition %d", ret); > - goto move_layers_back; > - } > - > - ret = dst->FinalizeComposition(); > - if (ret) { > - ALOGE("Failed to plan for squash all composition %d", ret); > - goto move_layers_back; > - } > - > - ret = ApplyPreComposite(dst); > - if (ret) { > - ALOGE("Failed to pre-composite for squash all composition %d", ret); > - goto move_layers_back; > - } > - > - pre_comp_layer_index = dst->layers().size() - 1; > - framebuffer_index_ = (framebuffer_index_ + 1) % DRM_DISPLAY_BUFFERS; > - > - for (DrmCompositionPlane &plane : dst->composition_planes()) { > - if (plane.type() == DrmCompositionPlane::Type::kPrecomp) { > - // Replace source_layers with the output of the precomposite > - plane.source_layers().clear(); > - plane.source_layers().push_back(pre_comp_layer_index); > - break; > - } > - } > - > - return 0; > - > -// TODO(zachr): think of a better way to transfer ownership back to the active > -// composition. > -move_layers_back: > - for (size_t plane_index = 0; > - plane_index < src_planes.size() && plane_index < dst_layers.size();) { > - if (src_planes[plane_index].source_layers().empty()) { > - plane_index++; > - continue; > - } > - for (auto i : src_planes[plane_index].source_layers()) > - src_layers[i] = std::move(dst_layers[plane_index++]); > - } > - > - return ret; > -} > - > void DrmDisplayCompositor::Dump(std::ostringstream *out) const { > int ret = pthread_mutex_lock(&lock_); > if (ret) > @@ -1051,11 +535,6 @@ void DrmDisplayCompositor::Dump(std::ostringstream *out) const { > > dump_last_timestamp_ns_ = cur_ts; > > - if (active_composition_) > - active_composition_->Dump(out); > - > - squash_state_.Dump(out); > - > pthread_mutex_unlock(&lock_); > } > } > diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h > index f1965fb0ad7f..eaf82fca989d 100644 > --- a/drmdisplaycompositor.h > +++ b/drmdisplaycompositor.h > @@ -36,49 +36,6 @@ > > namespace android { > > -class GLWorkerCompositor; > - > -class SquashState { > - public: > - static const unsigned kHistoryLength = 6; // TODO: make this number not magic > - static const unsigned kMaxLayers = 64; > - > - struct Region { > - DrmHwcRect<int> rect; > - std::bitset<kMaxLayers> layer_refs; > - std::bitset<kHistoryLength> change_history; > - bool squashed = false; > - }; > - > - bool is_stable(int region_index) const { > - return valid_history_ >= kHistoryLength && > - regions_[region_index].change_history.none(); > - } > - > - const std::vector<Region> ®ions() const { > - return regions_; > - } > - > - void Init(DrmHwcLayer *layers, size_t num_layers); > - void GenerateHistory(DrmHwcLayer *layers, size_t num_layers, > - std::vector<bool> &changed_regions) const; > - void StableRegionsWithMarginalHistory( > - const std::vector<bool> &changed_regions, > - std::vector<bool> &stable_regions) const; > - void RecordHistory(DrmHwcLayer *layers, size_t num_layers, > - const std::vector<bool> &changed_regions); > - bool RecordAndCompareSquashed(const std::vector<bool> &squashed_regions); > - > - void Dump(std::ostringstream *out) const; > - > - private: > - size_t generation_number_ = 0; > - unsigned valid_history_ = 0; > - std::vector<buffer_handle_t> last_handles_; > - > - std::vector<Region> regions_; > -}; > - > class DrmDisplayCompositor { > public: > DrmDisplayCompositor(); > @@ -89,15 +46,10 @@ class DrmDisplayCompositor { > std::unique_ptr<DrmDisplayComposition> CreateComposition() const; > int ApplyComposition(std::unique_ptr<DrmDisplayComposition> composition); > int Composite(); > - int SquashAll(); > void Dump(std::ostringstream *out) const; > > std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution(); > > - SquashState *squash_state() { > - return &squash_state_; > - } > - > private: > struct ModeState { > bool needs_modeset = false; > @@ -115,11 +67,8 @@ class DrmDisplayCompositor { > > int PrepareFramebuffer(DrmFramebuffer &fb, > DrmDisplayComposition *display_comp); > - int ApplySquash(DrmDisplayComposition *display_comp); > - int ApplyPreComposite(DrmDisplayComposition *display_comp); > int PrepareFrame(DrmDisplayComposition *display_comp); > int CommitFrame(DrmDisplayComposition *display_comp, bool test_only); > - int SquashFrame(DrmDisplayComposition *src, DrmDisplayComposition *dst); > int ApplyDpms(DrmDisplayComposition *display_comp); > int DisablePlanes(DrmDisplayComposition *display_comp); > > @@ -142,11 +91,6 @@ class DrmDisplayCompositor { > > int framebuffer_index_; > DrmFramebuffer framebuffers_[DRM_DISPLAY_BUFFERS]; > - std::unique_ptr<GLWorkerCompositor> pre_compositor_; > - > - SquashState squash_state_; > - int squash_framebuffer_index_; > - DrmFramebuffer squash_framebuffers_[2]; > > // mutable since we need to acquire in Dump() > mutable pthread_mutex_t lock_; > diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp > index 8e00d7150217..60ff384e9a08 100644 > --- a/drmhwctwo.cpp > +++ b/drmhwctwo.cpp > @@ -539,7 +539,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { > > std::vector<DrmPlane *> primary_planes(primary_planes_); > std::vector<DrmPlane *> overlay_planes(overlay_planes_); > - ret = composition->Plan(compositor_.squash_state(), &primary_planes, > + ret = composition->Plan(&primary_planes, > &overlay_planes); > if (ret) { > ALOGE("Failed to plan the composition ret=%d", ret); > @@ -692,12 +692,10 @@ HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types, > case HWC2::Composition::SolidColor: > case HWC2::Composition::Cursor: > case HWC2::Composition::Sideband: > + default: > layer.set_validated_type(HWC2::Composition::Client); > ++*num_types; > break; > - default: > - layer.set_validated_type(layer.sf_type()); > - break; > } > } > return *num_types ? HWC2::Error::HasChanges : HWC2::Error::None; > diff --git a/glworker.cpp b/glworker.cpp > deleted file mode 100644 > index ca726bf573ba..000000000000 > --- a/glworker.cpp > +++ /dev/null > @@ -1,840 +0,0 @@ > -/* > - * 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. > - */ > - > -#define ATRACE_TAG ATRACE_TAG_GRAPHICS > -#define LOG_TAG "hwc-gl-worker" > - > -#include <algorithm> > -#include <string> > -#include <sstream> > -#include <unordered_set> > - > -#include <sys/resource.h> > - > -#include <cutils/properties.h> > - > -#include <hardware/hardware.h> > -#include <hardware/hwcomposer.h> > - > -#include <ui/GraphicBuffer.h> > -#include <ui/PixelFormat.h> > - > -#include <utils/Trace.h> > - > -#include "drmdisplaycomposition.h" > -#include "platform.h" > - > -#include "glworker.h" > - > -#define MAX_OVERLAPPING_LAYERS 64 > - > -namespace android { > - > -// clang-format off > -// Column-major order: > -// float mat[4] = { 1, 2, 3, 4 } === > -// [ 1 3 ] > -// [ 2 4 ] > -float kTextureTransformMatrices[] = { > - 1.0f, 0.0f, 0.0f, 1.0f, // identity matrix > - 0.0f, 1.0f, 1.0f, 0.0f, // swap x and y > -}; > -// clang-format on > - > -static const char *GetGLError(void) { > - switch (glGetError()) { > - case GL_NO_ERROR: > - return "GL_NO_ERROR"; > - case GL_INVALID_ENUM: > - return "GL_INVALID_ENUM"; > - case GL_INVALID_VALUE: > - return "GL_INVALID_VALUE"; > - case GL_INVALID_OPERATION: > - return "GL_INVALID_OPERATION"; > - case GL_INVALID_FRAMEBUFFER_OPERATION: > - return "GL_INVALID_FRAMEBUFFER_OPERATION"; > - case GL_OUT_OF_MEMORY: > - return "GL_OUT_OF_MEMORY"; > - default: > - return "Unknown error"; > - } > -} > - > -static const char *GetGLFramebufferError(void) { > - switch (glCheckFramebufferStatus(GL_FRAMEBUFFER)) { > - case GL_FRAMEBUFFER_COMPLETE: > - return "GL_FRAMEBUFFER_COMPLETE"; > - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: > - return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; > - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: > - return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; > - case GL_FRAMEBUFFER_UNSUPPORTED: > - return "GL_FRAMEBUFFER_UNSUPPORTED"; > - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: > - return "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; > - default: > - return "Unknown error"; > - } > -} > - > -static const char *GetEGLError(void) { > - switch (eglGetError()) { > - case EGL_SUCCESS: > - return "EGL_SUCCESS"; > - case EGL_NOT_INITIALIZED: > - return "EGL_NOT_INITIALIZED"; > - case EGL_BAD_ACCESS: > - return "EGL_BAD_ACCESS"; > - case EGL_BAD_ALLOC: > - return "EGL_BAD_ALLOC"; > - case EGL_BAD_ATTRIBUTE: > - return "EGL_BAD_ATTRIBUTE"; > - case EGL_BAD_CONTEXT: > - return "EGL_BAD_CONTEXT"; > - case EGL_BAD_CONFIG: > - return "EGL_BAD_CONFIG"; > - case EGL_BAD_CURRENT_SURFACE: > - return "EGL_BAD_CURRENT_SURFACE"; > - case EGL_BAD_DISPLAY: > - return "EGL_BAD_DISPLAY"; > - case EGL_BAD_SURFACE: > - return "EGL_BAD_SURFACE"; > - case EGL_BAD_MATCH: > - return "EGL_BAD_MATCH"; > - case EGL_BAD_PARAMETER: > - return "EGL_BAD_PARAMETER"; > - case EGL_BAD_NATIVE_PIXMAP: > - return "EGL_BAD_NATIVE_PIXMAP"; > - case EGL_BAD_NATIVE_WINDOW: > - return "EGL_BAD_NATIVE_WINDOW"; > - case EGL_CONTEXT_LOST: > - return "EGL_CONTEXT_LOST"; > - default: > - return "Unknown error"; > - } > -} > - > -static bool HasExtension(const char *extension, const char *extensions) { > - const char *start, *where, *terminator; > - start = extensions; > - for (;;) { > - where = (char *)strstr((const char *)start, extension); > - if (!where) > - break; > - terminator = where + strlen(extension); > - if (where == start || *(where - 1) == ' ') > - if (*terminator == ' ' || *terminator == '\0') > - return true; > - start = terminator; > - } > - return false; > -} > - > -int GLWorkerCompositor::BeginContext() { > - private_.saved_egl_display = eglGetCurrentDisplay(); > - private_.saved_egl_ctx = eglGetCurrentContext(); > - > - if (private_.saved_egl_display != egl_display_ || > - private_.saved_egl_ctx != egl_ctx_) { > - private_.saved_egl_read = eglGetCurrentSurface(EGL_READ); > - private_.saved_egl_draw = eglGetCurrentSurface(EGL_DRAW); > - } else { > - return 0; > - } > - > - if (!eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_ctx_)) { > - ALOGE("BeginContext failed: %s", GetEGLError()); > - return 1; > - } > - return 0; > -} > - > -int GLWorkerCompositor::EndContext() { > - if (private_.saved_egl_display != eglGetCurrentDisplay() || > - private_.saved_egl_ctx != eglGetCurrentContext()) { > - if (!eglMakeCurrent(private_.saved_egl_display, private_.saved_egl_read, > - private_.saved_egl_draw, private_.saved_egl_ctx)) { > - ALOGE("EndContext failed: %s", GetEGLError()); > - return 1; > - } > - } > - > - return 0; > -} > - > -static AutoGLShader CompileAndCheckShader(GLenum type, unsigned source_count, > - const GLchar **sources, > - std::ostringstream *shader_log) { > - GLint status; > - AutoGLShader shader(glCreateShader(type)); > - if (shader.get() == 0) { > - if (shader_log) > - *shader_log << "Failed glCreateShader call"; > - return 0; > - } > - > - glShaderSource(shader.get(), source_count, sources, NULL); > - glCompileShader(shader.get()); > - glGetShaderiv(shader.get(), GL_COMPILE_STATUS, &status); > - if (!status) { > - if (shader_log) { > - GLint log_length; > - glGetShaderiv(shader.get(), GL_INFO_LOG_LENGTH, &log_length); > - std::string info_log(log_length, ' '); > - glGetShaderInfoLog(shader.get(), log_length, NULL, &info_log.front()); > - *shader_log << "Failed to compile shader:\n" << info_log.c_str() > - << "\nShader Source:\n"; > - for (unsigned i = 0; i < source_count; i++) { > - *shader_log << sources[i]; > - } > - *shader_log << "\n"; > - } > - return 0; > - } > - > - return shader; > -} > - > -static std::string GenerateVertexShader(int layer_count) { > - std::ostringstream vertex_shader_stream; > - vertex_shader_stream > - << "#version 300 es\n" > - << "#define LAYER_COUNT " << layer_count << "\n" > - << "precision mediump int;\n" > - << "uniform vec4 uViewport;\n" > - << "uniform vec4 uLayerCrop[LAYER_COUNT];\n" > - << "uniform mat2 uTexMatrix[LAYER_COUNT];\n" > - << "in vec2 vPosition;\n" > - << "in vec2 vTexCoords;\n" > - << "out vec2 fTexCoords[LAYER_COUNT];\n" > - << "void main() {\n" > - << " for (int i = 0; i < LAYER_COUNT; i++) {\n" > - << " vec2 tempCoords = vTexCoords * uTexMatrix[i];\n" > - << " fTexCoords[i] =\n" > - << " uLayerCrop[i].xy + tempCoords * uLayerCrop[i].zw;\n" > - << " }\n" > - << " vec2 scaledPosition = uViewport.xy + vPosition * uViewport.zw;\n" > - << " gl_Position =\n" > - << " vec4(scaledPosition * vec2(2.0) - vec2(1.0), 0.0, 1.0);\n" > - << "}\n"; > - return vertex_shader_stream.str(); > -} > - > -static std::string GenerateFragmentShader(int layer_count) { > - std::ostringstream fragment_shader_stream; > - fragment_shader_stream << "#version 300 es\n" > - << "#define LAYER_COUNT " << layer_count << "\n" > - << "#extension GL_OES_EGL_image_external : require\n" > - << "precision mediump float;\n"; > - for (int i = 0; i < layer_count; ++i) { > - fragment_shader_stream << "uniform samplerExternalOES uLayerTexture" << i > - << ";\n"; > - } > - fragment_shader_stream << "uniform float uLayerAlpha[LAYER_COUNT];\n" > - << "uniform float uLayerPremult[LAYER_COUNT];\n" > - << "in vec2 fTexCoords[LAYER_COUNT];\n" > - << "out vec4 oFragColor;\n" > - << "void main() {\n" > - << " vec3 color = vec3(0.0, 0.0, 0.0);\n" > - << " float alphaCover = 1.0;\n" > - << " vec4 texSample;\n" > - << " vec3 multRgb;\n"; > - for (int i = 0; i < layer_count; ++i) { > - if (i > 0) > - fragment_shader_stream << " if (alphaCover > 0.5/255.0) {\n"; > - // clang-format off > - fragment_shader_stream > - << " texSample = texture2D(uLayerTexture" << i << ",\n" > - << " fTexCoords[" << i << "]);\n" > - << " multRgb = texSample.rgb *\n" > - << " max(texSample.a, uLayerPremult[" << i << "]);\n" > - << " color += multRgb * uLayerAlpha[" << i << "] * alphaCover;\n" > - << " alphaCover *= 1.0 - texSample.a * uLayerAlpha[" << i << "];\n"; > - // clang-format on > - } > - for (int i = 0; i < layer_count - 1; ++i) > - fragment_shader_stream << " }\n"; > - fragment_shader_stream << " oFragColor = vec4(color, 1.0 - alphaCover);\n" > - << "}\n"; > - return fragment_shader_stream.str(); > -} > - > -static AutoGLProgram GenerateProgram(unsigned num_textures, > - std::ostringstream *shader_log) { > - std::string vertex_shader_string = GenerateVertexShader(num_textures); > - const GLchar *vertex_shader_source = vertex_shader_string.c_str(); > - AutoGLShader vertex_shader = CompileAndCheckShader( > - GL_VERTEX_SHADER, 1, &vertex_shader_source, shader_log); > - if (!vertex_shader.get()) > - return 0; > - > - std::string fragment_shader_string = GenerateFragmentShader(num_textures); > - const GLchar *fragment_shader_source = fragment_shader_string.c_str(); > - AutoGLShader fragment_shader = CompileAndCheckShader( > - GL_FRAGMENT_SHADER, 1, &fragment_shader_source, shader_log); > - if (!fragment_shader.get()) > - return 0; > - > - AutoGLProgram program(glCreateProgram()); > - if (!program.get()) { > - if (shader_log) > - *shader_log << "Failed to create program: " << GetGLError() << "\n"; > - return 0; > - } > - > - glAttachShader(program.get(), vertex_shader.get()); > - glAttachShader(program.get(), fragment_shader.get()); > - glBindAttribLocation(program.get(), 0, "vPosition"); > - glBindAttribLocation(program.get(), 1, "vTexCoords"); > - glLinkProgram(program.get()); > - glDetachShader(program.get(), vertex_shader.get()); > - glDetachShader(program.get(), fragment_shader.get()); > - > - GLint status; > - glGetProgramiv(program.get(), GL_LINK_STATUS, &status); > - if (!status) { > - if (shader_log) { > - GLint log_length; > - glGetProgramiv(program.get(), GL_INFO_LOG_LENGTH, &log_length); > - std::string program_log(log_length, ' '); > - glGetProgramInfoLog(program.get(), log_length, NULL, > - &program_log.front()); > - *shader_log << "Failed to link program:\n" << program_log.c_str() << "\n"; > - } > - return 0; > - } > - > - return program; > -} > - > -struct RenderingCommand { > - struct TextureSource { > - unsigned texture_index; > - float crop_bounds[4]; > - float alpha; > - float premult; > - float texture_matrix[4]; > - }; > - > - float bounds[4]; > - unsigned texture_count = 0; > - TextureSource textures[MAX_OVERLAPPING_LAYERS]; > -}; > - > -static void ConstructCommand(const DrmHwcLayer *layers, > - const DrmCompositionRegion ®ion, > - RenderingCommand &cmd) { > - std::copy_n(region.frame.bounds, 4, cmd.bounds); > - > - for (size_t texture_index : region.source_layers) { > - const DrmHwcLayer &layer = layers[texture_index]; > - > - DrmHwcRect<float> display_rect(layer.display_frame); > - float display_size[2] = {display_rect.bounds[2] - display_rect.bounds[0], > - display_rect.bounds[3] - display_rect.bounds[1]}; > - > - float tex_width = layer.buffer->width; > - float tex_height = layer.buffer->height; > - DrmHwcRect<float> crop_rect(layer.source_crop.left / tex_width, > - layer.source_crop.top / tex_height, > - layer.source_crop.right / tex_width, > - layer.source_crop.bottom / tex_height); > - > - float crop_size[2] = {crop_rect.bounds[2] - crop_rect.bounds[0], > - crop_rect.bounds[3] - crop_rect.bounds[1]}; > - > - RenderingCommand::TextureSource &src = cmd.textures[cmd.texture_count]; > - cmd.texture_count++; > - src.texture_index = texture_index; > - > - 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; > - } else if (layer.transform & DrmHwcTransform::kFlipV) { > - flip_xy[0] = false; > - flip_xy[1] = false; > - } 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) > - std::copy_n(&kTextureTransformMatrices[4], 4, src.texture_matrix); > - else > - std::copy_n(&kTextureTransformMatrices[0], 4, src.texture_matrix); > - > - for (int j = 0; j < 4; j++) { > - int b = j ^ (swap_xy ? 1 : 0); > - float bound_percent = > - (cmd.bounds[b] - display_rect.bounds[b % 2]) / display_size[b % 2]; > - if (flip_xy[j % 2]) { > - src.crop_bounds[j] = > - crop_rect.bounds[j % 2 + 2] - bound_percent * crop_size[j % 2]; > - } else { > - src.crop_bounds[j] = > - crop_rect.bounds[j % 2] + bound_percent * crop_size[j % 2]; > - } > - } > - > - if (layer.blending == DrmHwcBlending::kNone) { > - src.alpha = src.premult = 1.0f; > - // This layer is opaque. There is no point in using layers below this one. > - break; > - } > - > - src.alpha = layer.alpha / 255.0f; > - src.premult = (layer.blending == DrmHwcBlending::kPreMult) ? 1.0f : 0.0f; > - } > -} > - > -static int EGLFenceWait(EGLDisplay egl_display, int acquireFenceFd) { > - int ret = 0; > - > - EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, acquireFenceFd, > - EGL_NONE}; > - EGLSyncKHR egl_sync = > - eglCreateSyncKHR(egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); > - if (egl_sync == EGL_NO_SYNC_KHR) { > - ALOGE("Failed to make EGLSyncKHR from acquireFenceFd: %s", GetEGLError()); > - close(acquireFenceFd); > - return 1; > - } > - > - EGLint success = eglWaitSyncKHR(egl_display, egl_sync, 0); > - if (success == EGL_FALSE) { > - ALOGE("Failed to wait for acquire: %s", GetEGLError()); > - ret = 1; > - } > - eglDestroySyncKHR(egl_display, egl_sync); > - > - return ret; > -} > - > -static int CreateTextureFromHandle(EGLDisplay egl_display, > - buffer_handle_t handle, > - Importer *importer, > - AutoEGLImageAndGLTexture *out) { > - EGLImageKHR image = importer->ImportImage(egl_display, handle); > - > - if (image == EGL_NO_IMAGE_KHR) { > - ALOGE("Failed to make image %s %p", GetEGLError(), handle); > - return -EINVAL; > - } > - > - GLuint texture; > - glGenTextures(1, &texture); > - glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture); > - glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)image); > - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); > - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); > - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_REPEAT); > - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_REPEAT); > - glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); > - > - out->image.reset(egl_display, image); > - out->texture.reset(texture); > - > - return 0; > -} > - > -GLWorkerCompositor::GLWorkerCompositor() > - : egl_display_(EGL_NO_DISPLAY), egl_ctx_(EGL_NO_CONTEXT) { > -} > - > -int GLWorkerCompositor::Init() { > - int ret = 0; > - const char *egl_extensions; > - const char *gl_extensions; > - EGLint num_configs; > - EGLConfig egl_config; > - > - // clang-format off > - const GLfloat verts[] = { > - 0.0f, 0.0f, 0.0f, 0.0f, > - 0.0f, 2.0f, 0.0f, 2.0f, > - 2.0f, 0.0f, 2.0f, 0.0f > - }; > - // clang-format on > - > - const EGLint config_attribs[] = {EGL_RENDERABLE_TYPE, > - EGL_OPENGL_ES2_BIT, > - EGL_RED_SIZE, > - 8, > - EGL_GREEN_SIZE, > - 8, > - EGL_BLUE_SIZE, > - 8, > - EGL_NONE}; > - > - const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE}; > - > - egl_display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); > - if (egl_display_ == EGL_NO_DISPLAY) { > - ALOGE("Failed to get egl display"); > - return 1; > - } > - > - if (!eglInitialize(egl_display_, NULL, NULL)) { > - ALOGE("Failed to initialize egl: %s", GetEGLError()); > - return 1; > - } > - > - egl_extensions = eglQueryString(egl_display_, EGL_EXTENSIONS); > - > - // These extensions are all technically required but not always reported due > - // to meta EGL filtering them out. > - if (!HasExtension("EGL_KHR_image_base", egl_extensions)) > - ALOGW("EGL_KHR_image_base extension not supported"); > - > - if (!HasExtension("EGL_ANDROID_image_native_buffer", egl_extensions)) > - ALOGW("EGL_ANDROID_image_native_buffer extension not supported"); > - > - if (!HasExtension("EGL_ANDROID_native_fence_sync", egl_extensions)) > - ALOGW("EGL_ANDROID_native_fence_sync extension not supported"); > - > - if (!eglChooseConfig(egl_display_, config_attribs, &egl_config, 1, > - &num_configs)) { > - ALOGE("eglChooseConfig() failed with error: %s", GetEGLError()); > - return 1; > - } > - > - egl_ctx_ = > - eglCreateContext(egl_display_, egl_config, > - EGL_NO_CONTEXT /* No shared context */, context_attribs); > - > - if (egl_ctx_ == EGL_NO_CONTEXT) { > - ALOGE("Failed to create OpenGL ES Context: %s", GetEGLError()); > - return 1; > - } > - > - ret = BeginContext(); > - if (ret) > - return ret; > - > - gl_extensions = (const char *)glGetString(GL_EXTENSIONS); > - > - if (!HasExtension("GL_OES_EGL_image", gl_extensions)) > - ALOGW("GL_OES_EGL_image extension not supported"); > - > - if (!HasExtension("GL_OES_EGL_image_external", gl_extensions)) > - ALOGW("GL_OES_EGL_image_external extension not supported"); > - > - GLuint vertex_buffer; > - glGenBuffers(1, &vertex_buffer); > - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); > - glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); > - glBindBuffer(GL_ARRAY_BUFFER, 0); > - vertex_buffer_.reset(vertex_buffer); > - > - std::ostringstream shader_log; > - blend_programs_.emplace_back(GenerateProgram(1, &shader_log)); > - > - EndContext(); > - > - if (blend_programs_.back().get() == 0) { > - ALOGE("%s", shader_log.str().c_str()); > - return 1; > - } > - > - return 0; > -} > - > -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 GLWorkerCompositor::Composite(DrmHwcLayer *layers, > - DrmCompositionRegion *regions, > - size_t num_regions, > - const sp<GraphicBuffer> &framebuffer, > - Importer *importer) { > - ATRACE_CALL(); > - int ret = 0; > - std::vector<AutoEGLImageAndGLTexture> layer_textures; > - std::vector<RenderingCommand> commands; > - > - if (num_regions == 0) { > - return -EALREADY; > - } > - > - ret = BeginContext(); > - if (ret) > - return -1; > - > - GLint frame_width = framebuffer->getWidth(); > - GLint frame_height = framebuffer->getHeight(); > - CachedFramebuffer *cached_framebuffer = > - PrepareAndCacheFramebuffer(framebuffer); > - if (cached_framebuffer == NULL) { > - ALOGE("Composite failed because of failed framebuffer"); > - EndContext(); > - return -EINVAL; > - } > - > - std::unordered_set<size_t> layers_used_indices; > - for (size_t region_index = 0; region_index < num_regions; region_index++) { > - DrmCompositionRegion ®ion = regions[region_index]; > - layers_used_indices.insert(region.source_layers.begin(), > - region.source_layers.end()); > - commands.emplace_back(); > - ConstructCommand(layers, region, commands.back()); > - } > - > - for (size_t layer_index = 0; layer_index < MAX_OVERLAPPING_LAYERS; > - layer_index++) { > - DrmHwcLayer *layer = &layers[layer_index]; > - > - layer_textures.emplace_back(); > - > - if (layers_used_indices.count(layer_index) == 0) > - continue; > - > - ret = CreateTextureFromHandle(egl_display_, layer->get_usable_handle(), > - importer, &layer_textures.back()); > - > - if (!ret) { > - ret = EGLFenceWait(egl_display_, layer->acquire_fence.Release()); > - } > - if (ret) { > - layer_textures.pop_back(); > - ret = -EINVAL; > - } > - } > - > - if (ret) { > - EndContext(); > - return ret; > - } > - > - glViewport(0, 0, frame_width, frame_height); > - > - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); > - glClear(GL_COLOR_BUFFER_BIT); > - > - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_.get()); > - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, NULL); > - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, > - (void *)(sizeof(float) * 2)); > - glEnableVertexAttribArray(0); > - glEnableVertexAttribArray(1); > - glEnable(GL_SCISSOR_TEST); > - > - for (const RenderingCommand &cmd : commands) { > - if (cmd.texture_count == 0) > - continue; > - > - // TODO(zachr): handle the case of too many overlapping textures for one > - // area by falling back to rendering as many layers as possible using > - // multiple blending passes. > - GLint program = PrepareAndCacheProgram(cmd.texture_count); > - if (program == 0) { > - ALOGE("Too many layers to render in one area"); > - continue; > - } > - > - glUseProgram(program); > - GLint gl_viewport_loc = glGetUniformLocation(program, "uViewport"); > - GLint gl_crop_loc = glGetUniformLocation(program, "uLayerCrop"); > - GLint gl_alpha_loc = glGetUniformLocation(program, "uLayerAlpha"); > - GLint gl_premult_loc = glGetUniformLocation(program, "uLayerPremult"); > - GLint gl_tex_matrix_loc = glGetUniformLocation(program, "uTexMatrix"); > - glUniform4f(gl_viewport_loc, cmd.bounds[0] / (float)frame_width, > - cmd.bounds[1] / (float)frame_height, > - (cmd.bounds[2] - cmd.bounds[0]) / (float)frame_width, > - (cmd.bounds[3] - cmd.bounds[1]) / (float)frame_height); > - > - for (unsigned src_index = 0; src_index < cmd.texture_count; src_index++) { > - std::ostringstream texture_name_formatter; > - texture_name_formatter << "uLayerTexture" << src_index; > - GLint gl_tex_loc = > - glGetUniformLocation(program, texture_name_formatter.str().c_str()); > - > - const RenderingCommand::TextureSource &src = cmd.textures[src_index]; > - glUniform1f(gl_alpha_loc + src_index, src.alpha); > - glUniform1f(gl_premult_loc + src_index, src.premult); > - glUniform4f(gl_crop_loc + src_index, src.crop_bounds[0], > - src.crop_bounds[1], src.crop_bounds[2] - src.crop_bounds[0], > - src.crop_bounds[3] - src.crop_bounds[1]); > - glUniform1i(gl_tex_loc, src_index); > - glUniformMatrix2fv(gl_tex_matrix_loc + src_index, 1, GL_FALSE, > - src.texture_matrix); > - glActiveTexture(GL_TEXTURE0 + src_index); > - glBindTexture(GL_TEXTURE_EXTERNAL_OES, > - layer_textures[src.texture_index].texture.get()); > - } > - > - glScissor(cmd.bounds[0], cmd.bounds[1], cmd.bounds[2] - cmd.bounds[0], > - cmd.bounds[3] - cmd.bounds[1]); > - glDrawArrays(GL_TRIANGLES, 0, 3); > - > - for (unsigned src_index = 0; src_index < cmd.texture_count; src_index++) { > - glActiveTexture(GL_TEXTURE0 + src_index); > - glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); > - } > - } > - > - glDisable(GL_SCISSOR_TEST); > - glActiveTexture(GL_TEXTURE0); > - glDisableVertexAttribArray(0); > - glDisableVertexAttribArray(1); > - glBindBuffer(GL_ARRAY_BUFFER, 0); > - glUseProgram(0); > - > - glBindFramebuffer(GL_FRAMEBUFFER, 0); > - > - EndContext(); > - return ret; > -} > - > -void GLWorkerCompositor::Finish() { > - ATRACE_CALL(); > - glFinish(); > - > - char use_framebuffer_cache_opt[PROPERTY_VALUE_MAX]; > - property_get("hwc.drm.use_framebuffer_cache", use_framebuffer_cache_opt, "1"); > - bool use_framebuffer_cache = atoi(use_framebuffer_cache_opt); > - > - if (use_framebuffer_cache) { > - for (auto &fb : cached_framebuffers_) > - fb.strong_framebuffer.clear(); > - } else { > - cached_framebuffers_.clear(); > - } > -} > - > -GLWorkerCompositor::CachedFramebuffer::CachedFramebuffer( > - const sp<GraphicBuffer> &gb, AutoEGLDisplayImage &&image, > - AutoGLTexture &&tex, AutoGLFramebuffer &&fb) > - : strong_framebuffer(gb), > - weak_framebuffer(gb), > - egl_fb_image(std::move(image)), > - gl_fb_tex(std::move(tex)), > - gl_fb(std::move(fb)) { > -} > - > -bool GLWorkerCompositor::CachedFramebuffer::Promote() { > - if (strong_framebuffer.get() != NULL) > - return true; > - strong_framebuffer = weak_framebuffer.promote(); > - return strong_framebuffer.get() != NULL; > -} > - > -GLWorkerCompositor::CachedFramebuffer * > -GLWorkerCompositor::FindCachedFramebuffer( > - const sp<GraphicBuffer> &framebuffer) { > - for (auto &fb : cached_framebuffers_) > - if (fb.weak_framebuffer == framebuffer) > - return &fb; > - return NULL; > -} > - > -GLWorkerCompositor::CachedFramebuffer * > -GLWorkerCompositor::PrepareAndCacheFramebuffer( > - const sp<GraphicBuffer> &framebuffer) { > - CachedFramebuffer *cached_framebuffer = FindCachedFramebuffer(framebuffer); > - if (cached_framebuffer != NULL) { > - if (cached_framebuffer->Promote()) { > - glBindFramebuffer(GL_FRAMEBUFFER, cached_framebuffer->gl_fb.get()); > - return cached_framebuffer; > - } > - > - for (auto it = cached_framebuffers_.begin(); > - it != cached_framebuffers_.end(); ++it) { > - if (it->weak_framebuffer == framebuffer) { > - cached_framebuffers_.erase(it); > - break; > - } > - } > - } > - > - AutoEGLDisplayImage egl_fb_image( > - egl_display_, > - eglCreateImageKHR(egl_display_, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, > - (EGLClientBuffer)framebuffer->getNativeBuffer(), > - NULL /* no attribs */)); > - > - if (egl_fb_image.image() == EGL_NO_IMAGE_KHR) { > - ALOGE("Failed to make image from target buffer: %s", GetEGLError()); > - return NULL; > - } > - > - GLuint gl_fb_tex; > - glGenTextures(1, &gl_fb_tex); > - AutoGLTexture gl_fb_tex_auto(gl_fb_tex); > - glBindTexture(GL_TEXTURE_2D, gl_fb_tex); > - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, > - (GLeglImageOES)egl_fb_image.image()); > - glBindTexture(GL_TEXTURE_2D, 0); > - > - GLuint gl_fb; > - glGenFramebuffers(1, &gl_fb); > - AutoGLFramebuffer gl_fb_auto(gl_fb); > - glBindFramebuffer(GL_FRAMEBUFFER, gl_fb); > - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, > - gl_fb_tex, 0); > - > - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { > - ALOGE("Failed framebuffer check for created target buffer: %s", > - GetGLFramebufferError()); > - return NULL; > - } > - > - cached_framebuffers_.emplace_back(framebuffer, std::move(egl_fb_image), > - std::move(gl_fb_tex_auto), > - std::move(gl_fb_auto)); > - return &cached_framebuffers_.back(); > -} > - > -GLint GLWorkerCompositor::PrepareAndCacheProgram(unsigned texture_count) { > - if (blend_programs_.size() >= texture_count) { > - GLint program = blend_programs_[texture_count - 1].get(); > - if (program != 0) > - return program; > - } > - > - AutoGLProgram program = GenerateProgram(texture_count, NULL); > - if (program.get() != 0) { > - if (blend_programs_.size() < texture_count) > - blend_programs_.resize(texture_count); > - blend_programs_[texture_count - 1] = std::move(program); > - return blend_programs_[texture_count - 1].get(); > - } > - > - return 0; > -} > - > -} // namespace android > diff --git a/glworker.h b/glworker.h > deleted file mode 100644 > index 26de55d725cd..000000000000 > --- a/glworker.h > +++ /dev/null > @@ -1,94 +0,0 @@ > -/* > - * 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_GL_WORKER_H_ > -#define ANDROID_GL_WORKER_H_ > - > -#include <vector> > - > -#define EGL_EGLEXT_PROTOTYPES > -#define GL_GLEXT_PROTOTYPES > - > -#include <EGL/egl.h> > -#include <EGL/eglext.h> > -#include <GLES2/gl2.h> > -#include <GLES2/gl2ext.h> > - > -#include <ui/GraphicBuffer.h> > - > -#include "autogl.h" > - > -namespace android { > - > -struct DrmHwcLayer; > -struct DrmCompositionRegion; > - > -class GLWorkerCompositor { > - public: > - GLWorkerCompositor(); > - ~GLWorkerCompositor(); > - > - int Init(); > - int Composite(DrmHwcLayer *layers, DrmCompositionRegion *regions, > - size_t num_regions, const sp<GraphicBuffer> &framebuffer, > - Importer *importer); > - void Finish(); > - > - private: > - struct CachedFramebuffer { > - // If the strong_framebuffer is non-NULL, we are holding a strong reference > - // until we are sure rendering is done. The weak reference will be equal in > - // that case. > - sp<GraphicBuffer> strong_framebuffer; > - wp<GraphicBuffer> weak_framebuffer; > - AutoEGLDisplayImage egl_fb_image; > - AutoGLTexture gl_fb_tex; > - AutoGLFramebuffer gl_fb; > - > - CachedFramebuffer(const sp<GraphicBuffer> &gb, AutoEGLDisplayImage &&image, > - AutoGLTexture &&tex, AutoGLFramebuffer &&fb); > - > - bool Promote(); > - }; > - > - struct { > - EGLDisplay saved_egl_display = EGL_NO_DISPLAY; > - EGLContext saved_egl_ctx = EGL_NO_CONTEXT; > - EGLSurface saved_egl_read = EGL_NO_SURFACE; > - EGLSurface saved_egl_draw = EGL_NO_SURFACE; > - } private_; > - > - int BeginContext(); > - int EndContext(); > - > - CachedFramebuffer *FindCachedFramebuffer( > - const sp<GraphicBuffer> &framebuffer); > - CachedFramebuffer *PrepareAndCacheFramebuffer( > - const sp<GraphicBuffer> &framebuffer); > - > - GLint PrepareAndCacheProgram(unsigned texture_count); > - > - EGLDisplay egl_display_; > - EGLContext egl_ctx_; > - > - std::vector<AutoGLProgram> blend_programs_; > - AutoGLBuffer vertex_buffer_; > - > - std::vector<CachedFramebuffer> cached_framebuffers_; > -}; > -} > - > -#endif > diff --git a/hwcomposer.cpp b/hwcomposer.cpp > deleted file mode 100644 > index 338e042895a9..000000000000 > --- a/hwcomposer.cpp > +++ /dev/null > @@ -1,841 +0,0 @@ > -/* > - * 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. > - */ > - > -#define ATRACE_TAG ATRACE_TAG_GRAPHICS > -#define LOG_TAG "hwcomposer-drm" > - > -#include "drmhwcomposer.h" > -#include "drmeventlistener.h" > -#include "drmresources.h" > -#include "platform.h" > -#include "virtualcompositorworker.h" > -#include "vsyncworker.h" > - > -#include <stdlib.h> > - > -#include <cinttypes> > -#include <map> > -#include <vector> > -#include <sstream> > - > -#include <errno.h> > -#include <fcntl.h> > -#include <pthread.h> > -#include <sys/param.h> > -#include <sys/resource.h> > -#include <xf86drm.h> > -#include <xf86drmMode.h> > - > -#include <log/log.h> > -#include <cutils/properties.h> > -#include <hardware/hardware.h> > -#include <hardware/hwcomposer.h> > -#include <sw_sync.h> > -#include <sync/sync.h> > -#include <utils/Trace.h> > - > -#define UM_PER_INCH 25400 > - > -namespace android { > - > -class DummySwSyncTimeline { > - public: > - int Init() { > - int ret = timeline_fd_.Set(sw_sync_timeline_create()); > - if (ret < 0) > - return ret; > - return 0; > - } > - > - UniqueFd CreateDummyFence() { > - int ret = sw_sync_fence_create(timeline_fd_.get(), "dummy fence", > - timeline_pt_ + 1); > - if (ret < 0) { > - ALOGE("Failed to create dummy fence %d", ret); > - return ret; > - } > - > - UniqueFd ret_fd(ret); > - > - ret = sw_sync_timeline_inc(timeline_fd_.get(), 1); > - if (ret) { > - ALOGE("Failed to increment dummy sync timeline %d", ret); > - return ret; > - } > - > - ++timeline_pt_; > - return ret_fd; > - } > - > - private: > - UniqueFd timeline_fd_; > - int timeline_pt_ = 0; > -}; > - > -struct CheckedOutputFd { > - CheckedOutputFd(int *fd, const char *description, > - DummySwSyncTimeline &timeline) > - : fd_(fd), description_(description), timeline_(timeline) { > - } > - CheckedOutputFd(CheckedOutputFd &&rhs) > - : description_(rhs.description_), timeline_(rhs.timeline_) { > - std::swap(fd_, rhs.fd_); > - } > - > - CheckedOutputFd &operator=(const CheckedOutputFd &rhs) = delete; > - > - ~CheckedOutputFd() { > - if (fd_ == NULL) > - return; > - > - if (*fd_ >= 0) > - return; > - > - *fd_ = timeline_.CreateDummyFence().Release(); > - > - if (*fd_ < 0) > - ALOGE("Failed to fill %s (%p == %d) before destruction", > - description_.c_str(), fd_, *fd_); > - } > - > - private: > - int *fd_ = NULL; > - std::string description_; > - DummySwSyncTimeline &timeline_; > -}; > - > -typedef struct hwc_drm_display { > - struct hwc_context_t *ctx; > - int display; > - > - std::vector<uint32_t> config_ids; > - > - VSyncWorker vsync_worker; > -} hwc_drm_display_t; > - > -class DrmHotplugHandler : public DrmEventHandler { > - public: > - void Init(DrmResources *drm, const struct hwc_procs *procs) { > - drm_ = drm; > - procs_ = procs; > - } > - > - void HandleEvent(uint64_t timestamp_us) { > - for (auto &conn : drm_->connectors()) { > - drmModeConnection old_state = conn->state(); > - > - conn->UpdateModes(); > - > - drmModeConnection cur_state = conn->state(); > - > - if (cur_state == old_state) > - continue; > - > - ALOGI("%s event @%" PRIu64 " for connector %u\n", > - cur_state == DRM_MODE_CONNECTED ? "Plug" : "Unplug", timestamp_us, > - conn->id()); > - > - if (cur_state == DRM_MODE_CONNECTED) { > - // Take the first one, then look for the preferred > - DrmMode mode = *(conn->modes().begin()); > - for (auto &m : conn->modes()) { > - if (m.type() & DRM_MODE_TYPE_PREFERRED) { > - mode = m; > - break; > - } > - } > - ALOGI("Setting mode %dx%d for connector %d\n", mode.h_display(), > - mode.v_display(), conn->id()); > - int ret = drm_->SetDisplayActiveMode(conn->display(), mode); > - if (ret) { > - ALOGE("Failed to set active config %d", ret); > - return; > - } > - } else { > - int ret = drm_->SetDpmsMode(conn->display(), DRM_MODE_DPMS_OFF); > - if (ret) { > - ALOGE("Failed to set dpms mode off %d", ret); > - return; > - } > - } > - > - procs_->hotplug(procs_, conn->display(), > - cur_state == DRM_MODE_CONNECTED ? 1 : 0); > - } > - } > - > - private: > - DrmResources *drm_ = NULL; > - const struct hwc_procs *procs_ = NULL; > -}; > - > -struct hwc_context_t { > - // map of display:hwc_drm_display_t > - typedef std::map<int, hwc_drm_display_t> DisplayMap; > - > - ~hwc_context_t() { > - virtual_compositor_worker.Exit(); > - } > - > - hwc_composer_device_1_t device; > - hwc_procs_t const *procs = NULL; > - > - DisplayMap displays; > - DrmResources drm; > - std::unique_ptr<Importer> importer; > - const gralloc_module_t *gralloc; > - DummySwSyncTimeline dummy_timeline; > - VirtualCompositorWorker virtual_compositor_worker; > - DrmHotplugHandler hotplug_handler; > -}; > - > -class DrmVsyncCallback : public VsyncCallback { > - public: > - DrmVsyncCallback(hwc_procs_t const *procs) : procs_(procs) { > - } > - > - void Callback(int display, int64_t timestamp) { > - procs_->vsync(procs_, display, timestamp); > - } > - private: > - hwc_procs_t const *procs_; > -}; > - > -static void hwc_dump(struct hwc_composer_device_1 *dev, char *buff, > - int buff_len) { > - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; > - std::ostringstream out; > - > - ctx->drm.compositor()->Dump(&out); > - std::string out_str = out.str(); > - strncpy(buff, out_str.c_str(), > - std::min((size_t)buff_len, out_str.length() + 1)); > - buff[buff_len - 1] = '\0'; > -} > - > -static bool hwc_skip_layer(const std::pair<int, int> &indices, int i) { > - return indices.first >= 0 && i >= indices.first && i <= indices.second; > -} > - > -static int hwc_prepare(hwc_composer_device_1_t *dev, size_t num_displays, > - hwc_display_contents_1_t **display_contents) { > - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; > - > - for (int i = 0; i < (int)num_displays; ++i) { > - if (!display_contents[i]) > - continue; > - > - bool use_framebuffer_target = false; > - DrmMode mode; > - if (i == HWC_DISPLAY_VIRTUAL) { > - use_framebuffer_target = true; > - } else { > - DrmConnector *c = ctx->drm.GetConnectorForDisplay(i); > - if (!c) { > - ALOGE("Failed to get DrmConnector for display %d", i); > - return -ENODEV; > - } > - mode = c->active_mode(); > - } > - > - // Since we can't composite HWC_SKIP_LAYERs by ourselves, we'll let SF > - // handle all layers in between the first and last skip layers. So find the > - // outer indices and mark everything in between as HWC_FRAMEBUFFER > - std::pair<int, int> skip_layer_indices(-1, -1); > - int num_layers = display_contents[i]->numHwLayers; > - for (int j = 0; !use_framebuffer_target && j < num_layers; ++j) { > - hwc_layer_1_t *layer = &display_contents[i]->hwLayers[j]; > - > - if (!(layer->flags & HWC_SKIP_LAYER)) > - continue; > - > - if (skip_layer_indices.first == -1) > - skip_layer_indices.first = j; > - skip_layer_indices.second = j; > - } > - > - for (int j = 0; j < num_layers; ++j) { > - hwc_layer_1_t *layer = &display_contents[i]->hwLayers[j]; > - > - if (!use_framebuffer_target && !hwc_skip_layer(skip_layer_indices, j)) { > - // If the layer is off the screen, don't earmark it for an overlay. > - // We'll leave it as-is, which effectively just drops it from the frame > - const hwc_rect_t *frame = &layer->displayFrame; > - if ((frame->right - frame->left) <= 0 || > - (frame->bottom - frame->top) <= 0 || > - frame->right <= 0 || frame->bottom <= 0 || > - frame->left >= (int)mode.h_display() || > - frame->top >= (int)mode.v_display()) > - continue; > - > - if (layer->compositionType == HWC_FRAMEBUFFER) > - layer->compositionType = HWC_OVERLAY; > - } else { > - switch (layer->compositionType) { > - case HWC_OVERLAY: > - case HWC_BACKGROUND: > - case HWC_SIDEBAND: > - case HWC_CURSOR_OVERLAY: > - layer->compositionType = HWC_FRAMEBUFFER; > - break; > - } > - } > - } > - } > - > - return 0; > -} > - > -static void hwc_add_layer_to_retire_fence( > - hwc_layer_1_t *layer, hwc_display_contents_1_t *display_contents) { > - if (layer->releaseFenceFd < 0) > - return; > - > - if (display_contents->retireFenceFd >= 0) { > - int old_retire_fence = display_contents->retireFenceFd; > - display_contents->retireFenceFd = > - sync_merge("dc_retire", old_retire_fence, layer->releaseFenceFd); > - close(old_retire_fence); > - } else { > - display_contents->retireFenceFd = dup(layer->releaseFenceFd); > - } > -} > - > -static int hwc_set(hwc_composer_device_1_t *dev, size_t num_displays, > - hwc_display_contents_1_t **sf_display_contents) { > - ATRACE_CALL(); > - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; > - int ret = 0; > - > - std::vector<CheckedOutputFd> checked_output_fences; > - std::vector<DrmHwcDisplayContents> displays_contents; > - std::vector<DrmCompositionDisplayLayersMap> layers_map; > - std::vector<std::vector<size_t>> layers_indices; > - displays_contents.reserve(num_displays); > - // layers_map.reserve(num_displays); > - layers_indices.reserve(num_displays); > - > - // Phase one does nothing that would cause errors. Only take ownership of FDs. > - for (size_t i = 0; i < num_displays; ++i) { > - hwc_display_contents_1_t *dc = sf_display_contents[i]; > - displays_contents.emplace_back(); > - DrmHwcDisplayContents &display_contents = displays_contents.back(); > - layers_indices.emplace_back(); > - std::vector<size_t> &indices_to_composite = layers_indices.back(); > - > - if (!sf_display_contents[i]) > - continue; > - > - if (i == HWC_DISPLAY_VIRTUAL) { > - ctx->virtual_compositor_worker.QueueComposite(dc); > - continue; > - } > - > - std::ostringstream display_index_formatter; > - display_index_formatter << "retire fence for display " << i; > - std::string display_fence_description(display_index_formatter.str()); > - checked_output_fences.emplace_back(&dc->retireFenceFd, > - display_fence_description.c_str(), > - ctx->dummy_timeline); > - display_contents.retire_fence = OutputFd(&dc->retireFenceFd); > - > - size_t num_dc_layers = dc->numHwLayers; > - int framebuffer_target_index = -1; > - for (size_t j = 0; j < num_dc_layers; ++j) { > - hwc_layer_1_t *sf_layer = &dc->hwLayers[j]; > - if (sf_layer->compositionType == HWC_FRAMEBUFFER_TARGET) { > - framebuffer_target_index = j; > - break; > - } > - } > - > - for (size_t j = 0; j < num_dc_layers; ++j) { > - hwc_layer_1_t *sf_layer = &dc->hwLayers[j]; > - > - display_contents.layers.emplace_back(); > - DrmHwcLayer &layer = display_contents.layers.back(); > - > - // In prepare() we marked all layers FRAMEBUFFER between SKIP_LAYER's. > - // This means we should insert the FB_TARGET layer in the composition > - // stack at the location of the first skip layer, and ignore the rest. > - if (sf_layer->flags & HWC_SKIP_LAYER) { > - if (framebuffer_target_index < 0) > - continue; > - int idx = framebuffer_target_index; > - framebuffer_target_index = -1; > - hwc_layer_1_t *fbt_layer = &dc->hwLayers[idx]; > - if (!fbt_layer->handle || (fbt_layer->flags & HWC_SKIP_LAYER)) { > - ALOGE("Invalid HWC_FRAMEBUFFER_TARGET with HWC_SKIP_LAYER present"); > - continue; > - } > - indices_to_composite.push_back(idx); > - continue; > - } > - > - if (sf_layer->compositionType == HWC_OVERLAY) > - indices_to_composite.push_back(j); > - > - layer.acquire_fence.Set(sf_layer->acquireFenceFd); > - sf_layer->acquireFenceFd = -1; > - > - std::ostringstream layer_fence_formatter; > - layer_fence_formatter << "release fence for layer " << j << " of display " > - << i; > - std::string layer_fence_description(layer_fence_formatter.str()); > - checked_output_fences.emplace_back(&sf_layer->releaseFenceFd, > - layer_fence_description.c_str(), > - ctx->dummy_timeline); > - layer.release_fence = OutputFd(&sf_layer->releaseFenceFd); > - } > - > - // This is a catch-all in case we get a frame without any overlay layers, or > - // skip layers, but with a value fb_target layer. This _shouldn't_ happen, > - // but it's not ruled out by the hwc specification > - if (indices_to_composite.empty() && framebuffer_target_index >= 0) { > - hwc_layer_1_t *sf_layer = &dc->hwLayers[framebuffer_target_index]; > - if (!sf_layer->handle || (sf_layer->flags & HWC_SKIP_LAYER)) { > - ALOGE( > - "Expected valid layer with HWC_FRAMEBUFFER_TARGET when all " > - "HWC_OVERLAY layers are skipped."); > - ret = -EINVAL; > - } > - indices_to_composite.push_back(framebuffer_target_index); > - } > - } > - > - if (ret) > - return ret; > - > - for (size_t i = 0; i < num_displays; ++i) { > - hwc_display_contents_1_t *dc = sf_display_contents[i]; > - DrmHwcDisplayContents &display_contents = displays_contents[i]; > - if (!sf_display_contents[i] || i == HWC_DISPLAY_VIRTUAL) > - continue; > - > - layers_map.emplace_back(); > - DrmCompositionDisplayLayersMap &map = layers_map.back(); > - map.display = i; > - map.geometry_changed = > - (dc->flags & HWC_GEOMETRY_CHANGED) == HWC_GEOMETRY_CHANGED; > - std::vector<size_t> &indices_to_composite = layers_indices[i]; > - for (size_t j : indices_to_composite) { > - hwc_layer_1_t *sf_layer = &dc->hwLayers[j]; > - > - DrmHwcLayer &layer = display_contents.layers[j]; > - > - ret = layer.InitFromHwcLayer(sf_layer, ctx->importer.get(), ctx->gralloc); > - if (ret) { > - ALOGE("Failed to init composition from layer %d", ret); > - return ret; > - } > - map.layers.emplace_back(std::move(layer)); > - } > - } > - > - std::unique_ptr<DrmComposition> composition( > - ctx->drm.compositor()->CreateComposition(ctx->importer.get())); > - if (!composition) { > - ALOGE("Drm composition init failed"); > - return -EINVAL; > - } > - > - ret = composition->SetLayers(layers_map.size(), layers_map.data()); > - if (ret) { > - return -EINVAL; > - } > - > - ret = ctx->drm.compositor()->QueueComposition(std::move(composition)); > - if (ret) { > - return -EINVAL; > - } > - > - for (size_t i = 0; i < num_displays; ++i) { > - hwc_display_contents_1_t *dc = sf_display_contents[i]; > - if (!dc) > - continue; > - > - size_t num_dc_layers = dc->numHwLayers; > - for (size_t j = 0; j < num_dc_layers; ++j) { > - hwc_layer_1_t *layer = &dc->hwLayers[j]; > - if (layer->flags & HWC_SKIP_LAYER) > - continue; > - hwc_add_layer_to_retire_fence(layer, dc); > - } > - } > - > - composition.reset(NULL); > - > - return ret; > -} > - > -static int hwc_event_control(struct hwc_composer_device_1 *dev, int display, > - int event, int enabled) { > - if (event != HWC_EVENT_VSYNC || (enabled != 0 && enabled != 1)) > - return -EINVAL; > - > - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; > - hwc_drm_display_t *hd = &ctx->displays[display]; > - hd->vsync_worker.VSyncControl(enabled); > - return 0; > -} > - > -static int hwc_set_power_mode(struct hwc_composer_device_1 *dev, int display, > - int mode) { > - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; > - > - uint64_t dpmsValue = 0; > - switch (mode) { > - case HWC_POWER_MODE_OFF: > - dpmsValue = DRM_MODE_DPMS_OFF; > - break; > - > - /* We can't support dozing right now, so go full on */ > - case HWC_POWER_MODE_DOZE: > - case HWC_POWER_MODE_DOZE_SUSPEND: > - case HWC_POWER_MODE_NORMAL: > - dpmsValue = DRM_MODE_DPMS_ON; > - break; > - }; > - return ctx->drm.SetDpmsMode(display, dpmsValue); > -} > - > -static int hwc_query(struct hwc_composer_device_1 * /* dev */, int what, > - int *value) { > - switch (what) { > - case HWC_BACKGROUND_LAYER_SUPPORTED: > - *value = 0; /* TODO: We should do this */ > - break; > - case HWC_VSYNC_PERIOD: > - ALOGW("Query for deprecated vsync value, returning 60Hz"); > - *value = 1000 * 1000 * 1000 / 60; > - break; > - case HWC_DISPLAY_TYPES_SUPPORTED: > - *value = HWC_DISPLAY_PRIMARY_BIT | HWC_DISPLAY_EXTERNAL_BIT | > - HWC_DISPLAY_VIRTUAL_BIT; > - break; > - } > - return 0; > -} > - > -static void hwc_register_procs(struct hwc_composer_device_1 *dev, > - hwc_procs_t const *procs) { > - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; > - > - ctx->procs = procs; > - > - for (std::pair<const int, hwc_drm_display> &display_entry : ctx->displays) { > - auto callback = std::make_shared<DrmVsyncCallback>(procs); > - display_entry.second.vsync_worker.RegisterCallback(std::move(callback)); > - } > - > - ctx->hotplug_handler.Init(&ctx->drm, procs); > - ctx->drm.event_listener()->RegisterHotplugHandler(&ctx->hotplug_handler); > -} > - > -static int hwc_get_display_configs(struct hwc_composer_device_1 *dev, > - int display, uint32_t *configs, > - size_t *num_configs) { > - if (!*num_configs) > - return 0; > - > - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; > - hwc_drm_display_t *hd = &ctx->displays[display]; > - hd->config_ids.clear(); > - > - DrmConnector *connector = ctx->drm.GetConnectorForDisplay(display); > - if (!connector) { > - ALOGE("Failed to get connector for display %d", display); > - return -ENODEV; > - } > - > - int ret = connector->UpdateModes(); > - if (ret) { > - ALOGE("Failed to update display modes %d", ret); > - return ret; > - } > - > - for (const DrmMode &mode : connector->modes()) { > - size_t idx = hd->config_ids.size(); > - if (idx == *num_configs) > - break; > - hd->config_ids.push_back(mode.id()); > - configs[idx] = mode.id(); > - } > - *num_configs = hd->config_ids.size(); > - return *num_configs == 0 ? -1 : 0; > -} > - > -static int hwc_get_display_attributes(struct hwc_composer_device_1 *dev, > - int display, uint32_t config, > - const uint32_t *attributes, > - int32_t *values) { > - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; > - DrmConnector *c = ctx->drm.GetConnectorForDisplay(display); > - if (!c) { > - ALOGE("Failed to get DrmConnector for display %d", display); > - return -ENODEV; > - } > - DrmMode mode; > - for (const DrmMode &conn_mode : c->modes()) { > - if (conn_mode.id() == config) { > - mode = conn_mode; > - break; > - } > - } > - if (mode.id() == 0) { > - ALOGE("Failed to find active mode for display %d", display); > - return -ENOENT; > - } > - > - uint32_t mm_width = c->mm_width(); > - uint32_t mm_height = c->mm_height(); > - for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; ++i) { > - switch (attributes[i]) { > - case HWC_DISPLAY_VSYNC_PERIOD: > - values[i] = 1000 * 1000 * 1000 / mode.v_refresh(); > - break; > - case HWC_DISPLAY_WIDTH: > - values[i] = mode.h_display(); > - break; > - case HWC_DISPLAY_HEIGHT: > - values[i] = mode.v_display(); > - break; > - case HWC_DISPLAY_DPI_X: > - /* Dots per 1000 inches */ > - values[i] = mm_width ? (mode.h_display() * UM_PER_INCH) / mm_width : 0; > - break; > - case HWC_DISPLAY_DPI_Y: > - /* Dots per 1000 inches */ > - values[i] = > - mm_height ? (mode.v_display() * UM_PER_INCH) / mm_height : 0; > - break; > - } > - } > - return 0; > -} > - > -static int hwc_get_active_config(struct hwc_composer_device_1 *dev, > - int display) { > - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; > - DrmConnector *c = ctx->drm.GetConnectorForDisplay(display); > - if (!c) { > - ALOGE("Failed to get DrmConnector for display %d", display); > - return -ENODEV; > - } > - > - DrmMode mode = c->active_mode(); > - hwc_drm_display_t *hd = &ctx->displays[display]; > - for (size_t i = 0; i < hd->config_ids.size(); ++i) { > - if (hd->config_ids[i] == mode.id()) > - return i; > - } > - return -1; > -} > - > -static int hwc_set_active_config(struct hwc_composer_device_1 *dev, int display, > - int index) { > - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; > - hwc_drm_display_t *hd = &ctx->displays[display]; > - if (index >= (int)hd->config_ids.size()) { > - ALOGE("Invalid config index %d passed in", index); > - return -EINVAL; > - } > - > - DrmConnector *c = ctx->drm.GetConnectorForDisplay(display); > - if (!c) { > - ALOGE("Failed to get connector for display %d", display); > - return -ENODEV; > - } > - > - if (c->state() != DRM_MODE_CONNECTED) > - return -ENODEV; > - > - DrmMode mode; > - for (const DrmMode &conn_mode : c->modes()) { > - if (conn_mode.id() == hd->config_ids[index]) { > - mode = conn_mode; > - break; > - } > - } > - if (mode.id() != hd->config_ids[index]) { > - ALOGE("Could not find active mode for %d/%d", index, hd->config_ids[index]); > - return -ENOENT; > - } > - int ret = ctx->drm.SetDisplayActiveMode(display, mode); > - if (ret) { > - ALOGE("Failed to set active config %d", ret); > - return ret; > - } > - ret = ctx->drm.SetDpmsMode(display, DRM_MODE_DPMS_ON); > - if (ret) { > - ALOGE("Failed to set dpms mode on %d", ret); > - return ret; > - } > - return ret; > -} > - > -static int hwc_device_close(struct hw_device_t *dev) { > - struct hwc_context_t *ctx = (struct hwc_context_t *)dev; > - delete ctx; > - return 0; > -} > - > -/* > - * TODO: This function sets the active config to the first one in the list. This > - * should be fixed such that it selects the preferred mode for the display, or > - * some other, saner, method of choosing the config. > - */ > -static int hwc_set_initial_config(hwc_drm_display_t *hd) { > - uint32_t config; > - size_t num_configs = 1; > - int ret = hwc_get_display_configs(&hd->ctx->device, hd->display, &config, > - &num_configs); > - if (ret || !num_configs) > - return 0; > - > - ret = hwc_set_active_config(&hd->ctx->device, hd->display, 0); > - if (ret) { > - ALOGE("Failed to set active config d=%d ret=%d", hd->display, ret); > - return ret; > - } > - > - return ret; > -} > - > -static int hwc_initialize_display(struct hwc_context_t *ctx, int display) { > - hwc_drm_display_t *hd = &ctx->displays[display]; > - hd->ctx = ctx; > - hd->display = display; > - > - int ret = hwc_set_initial_config(hd); > - if (ret) { > - ALOGE("Failed to set initial config for d=%d ret=%d", display, ret); > - return ret; > - } > - > - ret = hd->vsync_worker.Init(&ctx->drm, display); > - if (ret) { > - ALOGE("Failed to create event worker for display %d %d\n", display, ret); > - return ret; > - } > - > - return 0; > -} > - > -static int hwc_enumerate_displays(struct hwc_context_t *ctx) { > - int ret; > - for (auto &conn : ctx->drm.connectors()) { > - ret = hwc_initialize_display(ctx, conn->display()); > - if (ret) { > - ALOGE("Failed to initialize display %d", conn->display()); > - return ret; > - } > - } > - > - ret = ctx->virtual_compositor_worker.Init(); > - if (ret) { > - ALOGE("Failed to initialize virtual compositor worker"); > - return ret; > - } > - return 0; > -} > - > -static int hwc_device_open(const struct hw_module_t *module, const char *name, > - struct hw_device_t **dev) { > - if (strcmp(name, HWC_HARDWARE_COMPOSER)) { > - ALOGE("Invalid module name- %s", name); > - return -EINVAL; > - } > - > - std::unique_ptr<hwc_context_t> ctx(new hwc_context_t()); > - if (!ctx) { > - ALOGE("Failed to allocate hwc context"); > - return -ENOMEM; > - } > - > - int ret = ctx->drm.Init(); > - if (ret) { > - ALOGE("Can't initialize Drm object %d", ret); > - return ret; > - } > - > - ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, > - (const hw_module_t **)&ctx->gralloc); > - if (ret) { > - ALOGE("Failed to open gralloc module %d", ret); > - return ret; > - } > - > - ret = ctx->dummy_timeline.Init(); > - if (ret) { > - ALOGE("Failed to create dummy sw sync timeline %d", ret); > - return ret; > - } > - > - ctx->importer.reset(Importer::CreateInstance(&ctx->drm)); > - if (!ctx->importer) { > - ALOGE("Failed to create importer instance"); > - return ret; > - } > - > - ret = hwc_enumerate_displays(ctx.get()); > - if (ret) { > - ALOGE("Failed to enumerate displays: %s", strerror(ret)); > - return ret; > - } > - > - ctx->device.common.tag = HARDWARE_DEVICE_TAG; > - ctx->device.common.version = HWC_DEVICE_API_VERSION_1_4; > - ctx->device.common.module = const_cast<hw_module_t *>(module); > - ctx->device.common.close = hwc_device_close; > - > - ctx->device.dump = hwc_dump; > - ctx->device.prepare = hwc_prepare; > - ctx->device.set = hwc_set; > - ctx->device.eventControl = hwc_event_control; > - ctx->device.setPowerMode = hwc_set_power_mode; > - ctx->device.query = hwc_query; > - ctx->device.registerProcs = hwc_register_procs; > - ctx->device.getDisplayConfigs = hwc_get_display_configs; > - ctx->device.getDisplayAttributes = hwc_get_display_attributes; > - ctx->device.getActiveConfig = hwc_get_active_config; > - ctx->device.setActiveConfig = hwc_set_active_config; > - ctx->device.setCursorPositionAsync = NULL; /* TODO: Add cursor */ > - > - *dev = &ctx->device.common; > - ctx.release(); > - > - return 0; > -} > -} > - > -static struct hw_module_methods_t hwc_module_methods = { > - .open = android::hwc_device_open > -}; > - > -hwc_module_t HAL_MODULE_INFO_SYM = { > - .common = { > - .tag = HARDWARE_MODULE_TAG, > - .version_major = 1, > - .version_minor = 0, > - .id = HWC_HARDWARE_MODULE_ID, > - .name = "DRM hwcomposer module", > - .author = "The Android Open Source Project", > - .methods = &hwc_module_methods, > - .dso = NULL, > - .reserved = {0}, > - } > -}; > diff --git a/platform.cpp b/platform.cpp > index 62b03a881dca..b6c39d05a3a1 100644 > --- a/platform.cpp > +++ b/platform.cpp > @@ -37,7 +37,7 @@ std::vector<DrmPlane *> Planner::GetUsablePlanes( > } > > std::tuple<int, std::vector<DrmCompositionPlane>> Planner::ProvisionPlanes( > - std::map<size_t, DrmHwcLayer *> &layers, bool use_squash_fb, DrmCrtc *crtc, > + std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc, > std::vector<DrmPlane *> *primary_planes, > std::vector<DrmPlane *> *overlay_planes) { > std::vector<DrmCompositionPlane> composition; > @@ -48,30 +48,6 @@ std::tuple<int, std::vector<DrmCompositionPlane>> Planner::ProvisionPlanes( > return std::make_tuple(-ENODEV, std::vector<DrmCompositionPlane>()); > } > > - // If needed, reserve the squash plane at the highest z-order > - DrmPlane *squash_plane = NULL; > - if (use_squash_fb) { > - if (!planes.empty()) { > - squash_plane = planes.back(); > - planes.pop_back(); > - } else { > - ALOGI("Not enough planes to reserve for squash fb"); > - } > - } > - > - // If needed, reserve the precomp plane at the next highest z-order > - DrmPlane *precomp_plane = NULL; > - if (layers.size() > planes.size()) { > - if (!planes.empty()) { > - precomp_plane = planes.back(); > - planes.pop_back(); > - composition.emplace_back(DrmCompositionPlane::Type::kPrecomp, > - precomp_plane, crtc); > - } else { > - ALOGE("Not enough planes to reserve for precomp fb"); > - } > - } > - > // Go through the provisioning stages and provision planes > for (auto &i : stages_) { > int ret = i->ProvisionPlanes(&composition, layers, crtc, &planes); > @@ -81,10 +57,6 @@ std::tuple<int, std::vector<DrmCompositionPlane>> Planner::ProvisionPlanes( > } > } > > - if (squash_plane) > - composition.emplace_back(DrmCompositionPlane::Type::kSquash, squash_plane, > - crtc); > - > return std::make_tuple(0, std::move(composition)); > } > > @@ -109,62 +81,6 @@ int PlanStageProtected::ProvisionPlanes( > i = layers.erase(i); > } > > - if (protected_zorder == -1) > - return 0; > - > - // Add any layers below the protected content to the precomposition since we > - // need to punch a hole through them. > - for (auto i = layers.begin(); i != layers.end();) { > - // Skip layers above the z-order of the protected content > - if (i->first > static_cast<size_t>(protected_zorder)) { > - ++i; > - continue; > - } > - > - // If there's no precomp layer already queued, queue one now. > - DrmCompositionPlane *precomp = GetPrecomp(composition); > - if (precomp) { > - precomp->source_layers().emplace_back(i->first); > - } else { > - if (!planes->empty()) { > - DrmPlane *precomp_plane = planes->back(); > - planes->pop_back(); > - composition->emplace_back(DrmCompositionPlane::Type::kPrecomp, > - precomp_plane, crtc, i->first); > - } else { > - ALOGE("Not enough planes to reserve for precomp fb"); > - } > - } > - i = layers.erase(i); > - } > - return 0; > -} > - > -int PlanStagePrecomp::ProvisionPlanes( > - std::vector<DrmCompositionPlane> *composition, > - std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc * /*crtc*/, > - std::vector<DrmPlane *> * /*planes*/) { > - DrmCompositionPlane *precomp = GetPrecomp(composition); > - if (!precomp || precomp->source_layers().empty()) > - return 0; > - > - // Find lowest zorder out of precomp layers > - size_t precomp_zorder = *std::min_element( > - precomp->source_layers().begin(), precomp->source_layers().end(), > - [](size_t a, size_t b) { return a < b; }); > - > - // if there are any remaining layers on top of any of the precomp layers, > - // add them to precomp to avoid blending issues since precomp is always at > - // highest zorder > - for (auto i = layers.begin(); i != layers.end();) { > - if (i->first < precomp_zorder) { > - i++; > - continue; > - } > - precomp->source_layers().emplace_back(i->first); > - i = layers.erase(i); > - } > - > return 0; > } > > @@ -183,13 +99,6 @@ int PlanStageGreedy::ProvisionPlanes( > ALOGE("Failed to emplace layer %zu, dropping it", i->first); > } > > - // Put the rest of the layers in the precomp plane > - DrmCompositionPlane *precomp = GetPrecomp(composition); > - if (precomp) { > - for (auto i = layers.begin(); i != layers.end(); i = layers.erase(i)) > - precomp->source_layers().emplace_back(i->first); > - } > - > return 0; > } > } > diff --git a/platform.h b/platform.h > index e417bf785a2c..639ac884ba3f 100644 > --- a/platform.h > +++ b/platform.h > @@ -38,10 +38,6 @@ class Importer { > // Creates a platform-specific importer instance > static Importer *CreateInstance(DrmResources *drm); > > - // Imports EGLImage for glcompositor, since NV handles this in non-standard > - // way, and fishing out the details is specific to the gralloc used. > - virtual EGLImageKHR ImportImage(EGLDisplay egl_display, buffer_handle_t handle) = 0; > - > // Imports the buffer referred to by handle into bo. > // > // Note: This can be called from a different thread than ReleaseBuffer. The > @@ -77,17 +73,7 @@ class Planner { > return plane; > } > > - // Finds and returns the squash layer from the composition > - static DrmCompositionPlane *GetPrecomp( > - std::vector<DrmCompositionPlane> *composition) { > - auto l = GetPrecompIter(composition); > - if (l == composition->end()) > - return NULL; > - return &(*l); > - } > - > - // Inserts the given layer:plane in the composition right before the precomp > - // layer > + // Inserts the given layer:plane in the composition at the back > static int Emplace(std::vector<DrmCompositionPlane> *composition, > std::vector<DrmPlane *> *planes, > DrmCompositionPlane::Type type, DrmCrtc *crtc, > @@ -96,40 +82,25 @@ class Planner { > if (!plane) > return -ENOENT; > > - auto precomp = GetPrecompIter(composition); > - composition->emplace(precomp, type, plane, crtc, source_layer); > + composition->emplace_back(type, plane, crtc, source_layer); > return 0; > } > - > - private: > - static std::vector<DrmCompositionPlane>::iterator GetPrecompIter( > - std::vector<DrmCompositionPlane> *composition) { > - return std::find_if(composition->begin(), composition->end(), > - [](const DrmCompositionPlane &p) { > - return p.type() == DrmCompositionPlane::Type::kPrecomp; > - }); > - } > }; > > // Creates a planner instance with platform-specific planning stages > static std::unique_ptr<Planner> CreateInstance(DrmResources *drm); > > // Takes a stack of layers and provisions hardware planes for them. If the > - // entire stack can't fit in hardware, the Planner may place the remaining > - // layers in a PRECOMP plane. Layers in the PRECOMP plane will be composited > - // using GL. PRECOMP planes should be placed above any 1:1 layer:plane > - // compositions. If use_squash_fb is true, the Planner should try to reserve a > - // plane at the highest z-order with type SQUASH. > + // entire stack can't fit in hardware, FIXME > // > // @layers: a map of index:layer of layers to composite > - // @use_squash_fb: reserve a squash framebuffer > // @primary_planes: a vector of primary planes available for this frame > // @overlay_planes: a vector of overlay planes available for this frame > // > // Returns: A tuple with the status of the operation (0 for success) and > // a vector of the resulting plan (ie: layer->plane mapping). > std::tuple<int, std::vector<DrmCompositionPlane>> ProvisionPlanes( > - std::map<size_t, DrmHwcLayer *> &layers, bool use_squash_fb, > + std::map<size_t, DrmHwcLayer *> &layers, > DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes, > std::vector<DrmPlane *> *overlay_planes); > > @@ -156,18 +127,6 @@ class PlanStageProtected : public Planner::PlanStage { > std::vector<DrmPlane *> *planes); > }; > > -// This plan stage provisions the precomp plane with any remaining layers that > -// are on top of the current precomp layers. This stage should be included in > -// all platforms before loosely allocating layers (i.e. PlanStageGreedy) if > -// any previous plan could have modified the precomp plane layers > -// (ex. PlanStageProtected). > -class PlanStagePrecomp : public Planner::PlanStage { > - public: > - int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition, > - std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc, > - std::vector<DrmPlane *> *planes); > -}; > - > // This plan stage places as many layers on dedicated planes as possible (first > // come first serve), and then sticks the rest in a precomposition plane (if > // needed). > diff --git a/platformdrmgeneric.cpp b/platformdrmgeneric.cpp > index 82539676b229..5b42c4aed5a4 100644 > --- a/platformdrmgeneric.cpp > +++ b/platformdrmgeneric.cpp > @@ -27,7 +27,6 @@ > #include <log/log.h> > #include <gralloc_handle.h> > #include <hardware/gralloc.h> > -#include <EGL/eglext.h> > > namespace android { > > @@ -84,22 +83,6 @@ uint32_t DrmGenericImporter::ConvertHalFormatToDrm(uint32_t hal_format) { > } > } > > -EGLImageKHR DrmGenericImporter::ImportImage(EGLDisplay egl_display, buffer_handle_t handle) { > - gralloc_handle_t *gr_handle = gralloc_handle(handle); > - if (!gr_handle) > - return NULL; > - EGLint attr[] = { > - EGL_WIDTH, (EGLint)gr_handle->width, > - EGL_HEIGHT, (EGLint)gr_handle->height, > - EGL_LINUX_DRM_FOURCC_EXT, (EGLint)ConvertHalFormatToDrm(gr_handle->format), > - EGL_DMA_BUF_PLANE0_FD_EXT, gr_handle->prime_fd, > - EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, > - EGL_DMA_BUF_PLANE0_PITCH_EXT, (EGLint)gr_handle->stride, > - EGL_NONE, > - }; > - return eglCreateImageKHR(egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attr); > -} > - > int DrmGenericImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) { > gralloc_handle_t *gr_handle = gralloc_handle(handle); > if (!gr_handle) > diff --git a/platformdrmgeneric.h b/platformdrmgeneric.h > index fbe059b49a92..0339e1e3957e 100644 > --- a/platformdrmgeneric.h > +++ b/platformdrmgeneric.h > @@ -31,7 +31,6 @@ class DrmGenericImporter : public Importer { > > int Init(); > > - EGLImageKHR ImportImage(EGLDisplay egl_display, buffer_handle_t handle) override; > int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override; > int ReleaseBuffer(hwc_drm_bo_t *bo) override; > > diff --git a/platformhisi.cpp b/platformhisi.cpp > index 3f5c31995c57..1ea1d0776648 100644 > --- a/platformhisi.cpp > +++ b/platformhisi.cpp > @@ -69,27 +69,6 @@ int HisiImporter::Init() { > return 0; > } > > -EGLImageKHR HisiImporter::ImportImage(EGLDisplay egl_display, buffer_handle_t handle) { > - private_handle_t const *hnd = reinterpret_cast < private_handle_t const *>(handle); > - if (!hnd) > - return NULL; > - > - EGLint fmt = ConvertHalFormatToDrm(hnd->req_format); > - if (fmt < 0) > - return NULL; > - > - EGLint attr[] = { > - EGL_WIDTH, hnd->width, > - EGL_HEIGHT, hnd->height, > - EGL_LINUX_DRM_FOURCC_EXT, fmt, > - EGL_DMA_BUF_PLANE0_FD_EXT, hnd->share_fd, > - EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, > - EGL_DMA_BUF_PLANE0_PITCH_EXT, hnd->byte_stride, > - EGL_NONE, > - }; > - return eglCreateImageKHR(egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attr); > -} > - > int HisiImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) { > private_handle_t const *hnd = reinterpret_cast < private_handle_t const *>(handle); > if (!hnd) > @@ -131,5 +110,3 @@ std::unique_ptr<Planner> Planner::CreateInstance(DrmResources *) { > return planner; > } > } > - > - > diff --git a/platformhisi.h b/platformhisi.h > index 46f459513dff..a0986923d4d3 100644 > --- a/platformhisi.h > +++ b/platformhisi.h > @@ -34,7 +34,6 @@ class HisiImporter : public DrmGenericImporter { > > int Init(); > > - EGLImageKHR ImportImage(EGLDisplay egl_display, buffer_handle_t handle) override; > int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override; > > private: > diff --git a/platformminigbm.cpp b/platformminigbm.cpp > index 80e2c0f9f5fd..8e3cc65f0c4c 100644 > --- a/platformminigbm.cpp > +++ b/platformminigbm.cpp > @@ -66,22 +66,6 @@ int DrmMinigbmImporter::Init() { > return 0; > } > > -EGLImageKHR DrmMinigbmImporter::ImportImage(EGLDisplay egl_display, buffer_handle_t handle) { > - cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)handle; > - if (!gr_handle) > - return NULL; > - EGLint attr[] = { > - EGL_WIDTH, (EGLint)gr_handle->width, > - EGL_HEIGHT, (EGLint)gr_handle->height, > - EGL_LINUX_DRM_FOURCC_EXT, (EGLint)gr_handle->format, > - EGL_DMA_BUF_PLANE0_FD_EXT, gr_handle->fds[0], > - EGL_DMA_BUF_PLANE0_PITCH_EXT, (EGLint)gr_handle->strides[0], > - EGL_DMA_BUF_PLANE0_OFFSET_EXT, (EGLint)gr_handle->offsets[0], > - EGL_NONE, > - }; > - return eglCreateImageKHR(egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attr); > -} > - > int DrmMinigbmImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) { > cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)handle; > if (!gr_handle) > diff --git a/platformminigbm.h b/platformminigbm.h > index ded4c077e178..f25bf7bc2d19 100644 > --- a/platformminigbm.h > +++ b/platformminigbm.h > @@ -32,7 +32,6 @@ class DrmMinigbmImporter : public DrmGenericImporter { > > int Init(); > > - EGLImageKHR ImportImage(EGLDisplay egl_display, buffer_handle_t handle) override; > int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override; > > private: > diff --git a/virtualcompositorworker.cpp b/virtualcompositorworker.cpp > deleted file mode 100644 > index b64b4148ee50..000000000000 > --- a/virtualcompositorworker.cpp > +++ /dev/null > @@ -1,168 +0,0 @@ > -/* > - * 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. > - */ > - > -#define LOG_TAG "hwc-virtual-compositor-worker" > - > -#include "virtualcompositorworker.h" > -#include "worker.h" > - > -#include <errno.h> > -#include <stdlib.h> > - > -#include <log/log.h> > -#include <hardware/hardware.h> > -#include <hardware/hwcomposer.h> > -#include <sched.h> > -#include <sw_sync.h> > -#include <sync/sync.h> > - > -namespace android { > - > -static const int kMaxQueueDepth = 3; > -static const int kAcquireWaitTimeoutMs = 3000; > - > -VirtualCompositorWorker::VirtualCompositorWorker() > - : Worker("virtual-compositor", HAL_PRIORITY_URGENT_DISPLAY), > - timeline_fd_(-1), > - timeline_(0), > - timeline_current_(0) { > -} > - > -VirtualCompositorWorker::~VirtualCompositorWorker() { > - if (timeline_fd_ >= 0) { > - FinishComposition(timeline_); > - close(timeline_fd_); > - timeline_fd_ = -1; > - } > -} > - > -int VirtualCompositorWorker::Init() { > - int ret = sw_sync_timeline_create(); > - if (ret < 0) { > - ALOGE("Failed to create sw sync timeline %d", ret); > - return ret; > - } > - timeline_fd_ = ret; > - return InitWorker(); > -} > - > -void VirtualCompositorWorker::QueueComposite(hwc_display_contents_1_t *dc) { > - std::unique_ptr<VirtualComposition> composition(new VirtualComposition); > - > - composition->outbuf_acquire_fence.Set(dc->outbufAcquireFenceFd); > - dc->outbufAcquireFenceFd = -1; > - if (dc->retireFenceFd >= 0) > - close(dc->retireFenceFd); > - dc->retireFenceFd = CreateNextTimelineFence(); > - > - for (size_t i = 0; i < dc->numHwLayers; ++i) { > - hwc_layer_1_t *layer = &dc->hwLayers[i]; > - if (layer->flags & HWC_SKIP_LAYER) > - continue; > - composition->layer_acquire_fences.emplace_back(layer->acquireFenceFd); > - layer->acquireFenceFd = -1; > - if (layer->releaseFenceFd >= 0) > - close(layer->releaseFenceFd); > - layer->releaseFenceFd = CreateNextTimelineFence(); > - } > - > - composition->release_timeline = timeline_; > - > - Lock(); > - while (composite_queue_.size() >= kMaxQueueDepth) { > - Unlock(); > - sched_yield(); > - Lock(); > - } > - > - composite_queue_.push(std::move(composition)); > - Unlock(); > - Signal(); > -} > - > -void VirtualCompositorWorker::Routine() { > - int wait_ret = 0; > - > - Lock(); > - if (composite_queue_.empty()) { > - wait_ret = WaitForSignalOrExitLocked(); > - } > - > - std::unique_ptr<VirtualComposition> composition; > - if (!composite_queue_.empty()) { > - composition = std::move(composite_queue_.front()); > - composite_queue_.pop(); > - } > - Unlock(); > - > - if (wait_ret == -EINTR) { > - return; > - } else if (wait_ret) { > - ALOGE("Failed to wait for signal, %d", wait_ret); > - return; > - } > - > - Compose(std::move(composition)); > -} > - > -int VirtualCompositorWorker::CreateNextTimelineFence() { > - ++timeline_; > - return sw_sync_fence_create(timeline_fd_, "drm_fence", timeline_); > -} > - > -int VirtualCompositorWorker::FinishComposition(int point) { > - int timeline_increase = point - timeline_current_; > - if (timeline_increase <= 0) > - return 0; > - int ret = sw_sync_timeline_inc(timeline_fd_, timeline_increase); > - if (ret) > - ALOGE("Failed to increment sync timeline %d", ret); > - else > - timeline_current_ = point; > - return ret; > -} > - > -void VirtualCompositorWorker::Compose( > - std::unique_ptr<VirtualComposition> composition) { > - if (!composition.get()) > - return; > - > - int ret; > - int outbuf_acquire_fence = composition->outbuf_acquire_fence.get(); > - if (outbuf_acquire_fence >= 0) { > - ret = sync_wait(outbuf_acquire_fence, kAcquireWaitTimeoutMs); > - if (ret) { > - ALOGE("Failed to wait for outbuf acquire %d/%d", outbuf_acquire_fence, > - ret); > - return; > - } > - composition->outbuf_acquire_fence.Close(); > - } > - for (size_t i = 0; i < composition->layer_acquire_fences.size(); ++i) { > - int layer_acquire_fence = composition->layer_acquire_fences[i].get(); > - if (layer_acquire_fence >= 0) { > - ret = sync_wait(layer_acquire_fence, kAcquireWaitTimeoutMs); > - if (ret) { > - ALOGE("Failed to wait for layer acquire %d/%d", layer_acquire_fence, > - ret); > - return; > - } > - composition->layer_acquire_fences[i].Close(); > - } > - } > - FinishComposition(composition->release_timeline); > -} > -} > diff --git a/virtualcompositorworker.h b/virtualcompositorworker.h > deleted file mode 100644 > index 1fc5e435eaac..000000000000 > --- a/virtualcompositorworker.h > +++ /dev/null > @@ -1,56 +0,0 @@ > -/* > - * 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_VIRTUAL_COMPOSITOR_WORKER_H_ > -#define ANDROID_VIRTUAL_COMPOSITOR_WORKER_H_ > - > -#include "drmhwcomposer.h" > -#include "worker.h" > - > -#include <queue> > - > -namespace android { > - > -class VirtualCompositorWorker : public Worker { > - public: > - VirtualCompositorWorker(); > - ~VirtualCompositorWorker() override; > - > - int Init(); > - void QueueComposite(hwc_display_contents_1_t *dc); > - > - protected: > - void Routine() override; > - > - private: > - struct VirtualComposition { > - UniqueFd outbuf_acquire_fence; > - std::vector<UniqueFd> layer_acquire_fences; > - int release_timeline; > - }; > - > - int CreateNextTimelineFence(); > - int FinishComposition(int timeline); > - void Compose(std::unique_ptr<VirtualComposition> composition); > - > - std::queue<std::unique_ptr<VirtualComposition>> composite_queue_; > - int timeline_fd_; > - int timeline_; > - int timeline_current_; > -}; > -} > - > -#endif > -- > 2.17.0 > -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel