X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=drmdisplaycompositor.cpp;h=60adbacbdfe0fde422115ca17ee3e8d3bddb6023;hb=c1281eaa0b40f257ce3f99c06129f9251edeb2ec;hp=3675af4b959d5c746201bf7005c3a368ded5cb04;hpb=d4a0a3d2aee4bbfe38395f4c2e11128461d13317;p=android-x86%2Fexternal-drm_hwcomposer.git diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp index 3675af4..60adbac 100644 --- a/drmdisplaycompositor.cpp +++ b/drmdisplaycompositor.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include @@ -195,18 +195,14 @@ void DrmDisplayCompositor::FrameWorker::QueueFrame( frame.composition = std::move(composition); frame.status = status; frame_queue_.push(std::move(frame)); - SignalLocked(); Unlock(); + Signal(); } void DrmDisplayCompositor::FrameWorker::Routine() { - int ret = Lock(); - if (ret) { - ALOGE("Failed to lock worker, %d", ret); - return; - } - int wait_ret = 0; + + Lock(); if (frame_queue_.empty()) { wait_ret = WaitForSignalOrExitLocked(); } @@ -216,12 +212,7 @@ void DrmDisplayCompositor::FrameWorker::Routine() { frame = std::move(frame_queue_.front()); frame_queue_.pop(); } - - ret = Unlock(); - if (ret) { - ALOGE("Failed to unlock worker, %d", ret); - return; - } + Unlock(); if (wait_ret == -EINTR) { return; @@ -301,6 +292,13 @@ int DrmDisplayCompositor::Init(DrmResources *drm, int display) { return ret; } + pre_compositor_.reset(new GLWorkerCompositor()); + ret = pre_compositor_->Init(); + if (ret) { + ALOGE("Failed to initialize OpenGL compositor %d", ret); + pre_compositor_.reset(); + } + initialized_ = true; return 0; } @@ -422,13 +420,16 @@ int DrmDisplayCompositor::ApplySquash(DrmDisplayComposition *display_comp) { } std::vector ®ions = display_comp->squash_regions(); - ret = pre_compositor_->Composite(display_comp->layers().data(), - regions.data(), regions.size(), fb.buffer()); - pre_compositor_->Finish(); + if (pre_compositor_) { + 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; + if (ret) { + ALOGE("Failed to squash layers"); + return ret; + } } ret = display_comp->CreateNextTimelineFence(); @@ -455,13 +456,16 @@ int DrmDisplayCompositor::ApplyPreComposite( } std::vector ®ions = display_comp->pre_comp_regions(); - ret = pre_compositor_->Composite(display_comp->layers().data(), - regions.data(), regions.size(), fb.buffer()); - pre_compositor_->Finish(); + if (pre_compositor_) { + 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; + if (ret) { + ALOGE("Failed to pre-composite layers"); + return ret; + } } ret = display_comp->CreateNextTimelineFence(); @@ -607,8 +611,7 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, std::vector &layers = display_comp->layers(); std::vector &comp_planes = display_comp->composition_planes(); - std::vector &pre_comp_regions = - display_comp->pre_comp_regions(); + uint64_t out_fences[drm_->crtcs().size()]; DrmConnector *connector = drm_->GetConnectorForDisplay(display_); if (!connector) { @@ -627,7 +630,24 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, return -ENOMEM; } + if (crtc->out_fence_ptr_property().id() != 0) { + ret = drmModeAtomicAddProperty(pset, crtc->id(), crtc->out_fence_ptr_property().id(), + (uint64_t) &out_fences[crtc->pipe()]); + if (ret < 0) { + ALOGE("Failed to add OUT_FENCE_PTR property to pset: %d", ret); + drmModeAtomicFree(pset); + return ret; + } + } + if (mode_.needs_modeset) { + ret = drmModeAtomicAddProperty(pset, crtc->id(), crtc->active_property().id(), 1); + if (ret < 0) { + ALOGE("Failed to add crtc active to pset\n"); + drmModeAtomicFree(pset); + return ret; + } + ret = drmModeAtomicAddProperty(pset, crtc->id(), crtc->mode_property().id(), mode_.blob_id) < 0 || drmModeAtomicAddProperty(pset, connector->id(), @@ -646,6 +666,7 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, std::vector &source_layers = comp_plane.source_layers(); int fb_id = -1; + int fence_fd = -1; DrmHwcRect display_frame; DrmHwcRect source_crop; uint64_t rotation = 0; @@ -664,30 +685,12 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, break; } DrmHwcLayer &layer = layers[source_layers.front()]; - if (!test_only && layer.acquire_fence.get() >= 0) { - int acquire_fence = layer.acquire_fence.get(); - int total_fence_timeout = 0; - for (int i = 0; i < kAcquireWaitTries; ++i) { - int fence_timeout = kAcquireWaitTimeoutMs * (1 << i); - total_fence_timeout += fence_timeout; - ret = sync_wait(acquire_fence, fence_timeout); - if (ret) - ALOGW("Acquire fence %d wait %d failed (%d). Total time %d", - acquire_fence, i, ret, total_fence_timeout); - else - break; - } - if (ret) { - ALOGE("Failed to wait for acquire %d/%d", acquire_fence, ret); - break; - } - layer.acquire_fence.Close(); - } if (!layer.buffer) { ALOGE("Expected a valid framebuffer for pset"); break; } fb_id = layer.buffer->fb_id; + fence_fd = layer.acquire_fence.get(); display_frame = layer.display_frame; source_crop = layer.source_crop; if (layer.blending == DrmHwcBlending::kPreMult) @@ -695,16 +698,32 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, rotation = 0; if (layer.transform & DrmHwcTransform::kFlipH) - rotation |= 1 << DRM_REFLECT_X; + rotation |= DRM_MODE_REFLECT_X; if (layer.transform & DrmHwcTransform::kFlipV) - rotation |= 1 << DRM_REFLECT_Y; + rotation |= DRM_MODE_REFLECT_Y; if (layer.transform & DrmHwcTransform::kRotate90) - rotation |= 1 << DRM_ROTATE_90; + rotation |= DRM_MODE_ROTATE_90; else if (layer.transform & DrmHwcTransform::kRotate180) - rotation |= 1 << DRM_ROTATE_180; + rotation |= DRM_MODE_ROTATE_180; else if (layer.transform & DrmHwcTransform::kRotate270) - rotation |= 1 << DRM_ROTATE_270; + rotation |= DRM_MODE_ROTATE_270; + else + rotation |= DRM_MODE_ROTATE_0; + + if (fence_fd >= 0) { + int prop_id = plane->in_fence_fd_property().id(); + if (prop_id == 0) { + ALOGE("Failed to get IN_FENCE_FD property id"); + break; + } + ret = drmModeAtomicAddProperty(pset, plane->id(), prop_id, fence_fd); + if (ret < 0) { + ALOGE("Failed to add IN_FENCE_FD property to pset: %d", ret); + break; + } + } } + // Disable the plane if there's no framebuffer if (fb_id < 0) { ret = drmModeAtomicAddProperty(pset, plane->id(), @@ -719,7 +738,7 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, } // TODO: Once we have atomic test, this should fall back to GL - if (rotation && plane->rotation_property().id() == 0) { + if (rotation != DRM_MODE_ROTATE_0 && plane->rotation_property().id() == 0) { ALOGE("Rotation is not supported on plane %d", plane->id()); ret = -EINVAL; break; @@ -788,7 +807,6 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, } } -out: if (!ret) { uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; if (test_only) @@ -828,6 +846,10 @@ out: mode_.needs_modeset = false; } + if (crtc->out_fence_ptr_property().id()) { + display_comp->set_out_fence((int) out_fences[crtc->pipe()]); + } + return ret; } @@ -1087,10 +1109,13 @@ int DrmDisplayCompositor::SquashFrame(DrmDisplayComposition *src, goto move_layers_back; } - if (comp_plane.type() == DrmCompositionPlane::Type::kDisable) { + 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]; @@ -1109,11 +1134,12 @@ int DrmDisplayCompositor::SquashFrame(DrmDisplayComposition *src, squashed_comp.source_layers().push_back( squashed_comp.source_layers().size()); } + } - if (comp_plane.plane()->type() == DRM_PLANE_TYPE_PRIMARY) - squashed_comp.set_plane(comp_plane.plane()); - else - dst->AddPlaneDisable(comp_plane.plane()); + 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);