blob: c1a6d2f032a64e03f27ac95b235b6898ca4847a3 [file] [log] [blame]
Haixia Shid21f5282015-10-05 14:35:09 -07001/*
Adrian Salido0e892682017-03-01 14:57:39 -08002 * Copyright (C) 2015-2016 The Android Open Source Project
Haixia Shid21f5282015-10-05 14:35:09 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "hwc-virtual-compositor-worker"
18
19#include "virtualcompositorworker.h"
Haixia Shid21f5282015-10-05 14:35:09 -070020
21#include <cutils/log.h>
Haixia Shid21f5282015-10-05 14:35:09 -070022#include <sw_sync.h>
23#include <sync/sync.h>
24
25namespace android {
26
27static const int kMaxQueueDepth = 3;
Sean Paulfaca2092015-11-16 13:47:19 -050028static const int kAcquireWaitTimeoutMs = 3000;
Haixia Shid21f5282015-10-05 14:35:09 -070029
30VirtualCompositorWorker::VirtualCompositorWorker()
Adrian Salido0e892682017-03-01 14:57:39 -080031 : QueueWorker("virtual-compositor", HAL_PRIORITY_URGENT_DISPLAY),
Haixia Shi479412c2015-10-27 10:40:48 -070032 timeline_fd_(-1),
33 timeline_(0),
34 timeline_current_(0) {
Haixia Shid21f5282015-10-05 14:35:09 -070035}
36
37VirtualCompositorWorker::~VirtualCompositorWorker() {
38 if (timeline_fd_ >= 0) {
39 FinishComposition(timeline_);
40 close(timeline_fd_);
41 timeline_fd_ = -1;
42 }
43}
44
45int VirtualCompositorWorker::Init() {
46 int ret = sw_sync_timeline_create();
47 if (ret < 0) {
48 ALOGE("Failed to create sw sync timeline %d", ret);
49 return ret;
50 }
51 timeline_fd_ = ret;
Adrian Salido0e892682017-03-01 14:57:39 -080052
53 set_max_queue_size(kMaxQueueDepth);
Haixia Shid21f5282015-10-05 14:35:09 -070054 return InitWorker();
55}
56
57void VirtualCompositorWorker::QueueComposite(hwc_display_contents_1_t *dc) {
58 std::unique_ptr<VirtualComposition> composition(new VirtualComposition);
59
60 composition->outbuf_acquire_fence.Set(dc->outbufAcquireFenceFd);
61 dc->outbufAcquireFenceFd = -1;
62 if (dc->retireFenceFd >= 0)
63 close(dc->retireFenceFd);
64 dc->retireFenceFd = CreateNextTimelineFence();
65
66 for (size_t i = 0; i < dc->numHwLayers; ++i) {
67 hwc_layer_1_t *layer = &dc->hwLayers[i];
68 if (layer->flags & HWC_SKIP_LAYER)
69 continue;
70 composition->layer_acquire_fences.emplace_back(layer->acquireFenceFd);
71 layer->acquireFenceFd = -1;
72 if (layer->releaseFenceFd >= 0)
73 close(layer->releaseFenceFd);
74 layer->releaseFenceFd = CreateNextTimelineFence();
75 }
76
77 composition->release_timeline = timeline_;
78
Adrian Salido0e892682017-03-01 14:57:39 -080079 QueueWork(std::move(composition));
Haixia Shid21f5282015-10-05 14:35:09 -070080}
81
82int VirtualCompositorWorker::CreateNextTimelineFence() {
83 ++timeline_;
84 return sw_sync_fence_create(timeline_fd_, "drm_fence", timeline_);
85}
86
87int VirtualCompositorWorker::FinishComposition(int point) {
88 int timeline_increase = point - timeline_current_;
89 if (timeline_increase <= 0)
90 return 0;
91 int ret = sw_sync_timeline_inc(timeline_fd_, timeline_increase);
92 if (ret)
93 ALOGE("Failed to increment sync timeline %d", ret);
94 else
95 timeline_current_ = point;
96 return ret;
97}
98
Adrian Salido0e892682017-03-01 14:57:39 -080099void VirtualCompositorWorker::ProcessWork(
Haixia Shid21f5282015-10-05 14:35:09 -0700100 std::unique_ptr<VirtualComposition> composition) {
101 if (!composition.get())
102 return;
103
104 int ret;
105 int outbuf_acquire_fence = composition->outbuf_acquire_fence.get();
106 if (outbuf_acquire_fence >= 0) {
107 ret = sync_wait(outbuf_acquire_fence, kAcquireWaitTimeoutMs);
108 if (ret) {
Sean Paulfaca2092015-11-16 13:47:19 -0500109 ALOGE("Failed to wait for outbuf acquire %d/%d", outbuf_acquire_fence,
110 ret);
Haixia Shid21f5282015-10-05 14:35:09 -0700111 return;
112 }
113 composition->outbuf_acquire_fence.Close();
114 }
115 for (size_t i = 0; i < composition->layer_acquire_fences.size(); ++i) {
116 int layer_acquire_fence = composition->layer_acquire_fences[i].get();
117 if (layer_acquire_fence >= 0) {
118 ret = sync_wait(layer_acquire_fence, kAcquireWaitTimeoutMs);
119 if (ret) {
Sean Paulfaca2092015-11-16 13:47:19 -0500120 ALOGE("Failed to wait for layer acquire %d/%d", layer_acquire_fence,
121 ret);
Haixia Shid21f5282015-10-05 14:35:09 -0700122 return;
123 }
124 composition->layer_acquire_fences[i].Close();
125 }
126 }
127 FinishComposition(composition->release_timeline);
128}
129}