external/drm_hwcomposer
Revision | f6d14a6ebf08d75ec8a7bbbd927c41319d358f8d (tree) |
---|---|
Time | 2017-11-02 16:16:31 |
Author | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Revert "drm_hwcomposer: Remove threading"
This reverts commit ed45a8eb01d5927e36e34acd7bac46abbbecb304.
@@ -53,6 +53,9 @@ LOCAL_C_INCLUDES := \ | ||
53 | 53 | LOCAL_SRC_FILES := \ |
54 | 54 | autolock.cpp \ |
55 | 55 | drmresources.cpp \ |
56 | + drmcomposition.cpp \ | |
57 | + drmcompositor.cpp \ | |
58 | + drmcompositorworker.cpp \ | |
56 | 59 | drmconnector.cpp \ |
57 | 60 | drmcrtc.cpp \ |
58 | 61 | drmdisplaycomposition.cpp \ |
@@ -0,0 +1,166 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2015 The Android Open Source Project | |
3 | + * | |
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-drm-composition" | |
18 | + | |
19 | +#include "drmcomposition.h" | |
20 | +#include "drmcrtc.h" | |
21 | +#include "drmplane.h" | |
22 | +#include "drmresources.h" | |
23 | +#include "platform.h" | |
24 | + | |
25 | +#include <stdlib.h> | |
26 | + | |
27 | +#include <cutils/log.h> | |
28 | +#include <cutils/properties.h> | |
29 | +#include <sw_sync.h> | |
30 | +#include <sync/sync.h> | |
31 | + | |
32 | +namespace android { | |
33 | + | |
34 | +DrmComposition::DrmComposition(DrmResources *drm, Importer *importer, | |
35 | + Planner *planner) | |
36 | + : drm_(drm), importer_(importer), planner_(planner) { | |
37 | + char use_overlay_planes_prop[PROPERTY_VALUE_MAX]; | |
38 | + property_get("hwc.drm.use_overlay_planes", use_overlay_planes_prop, "1"); | |
39 | + bool use_overlay_planes = atoi(use_overlay_planes_prop); | |
40 | + | |
41 | + for (auto &plane : drm->planes()) { | |
42 | + if (plane->type() == DRM_PLANE_TYPE_PRIMARY) | |
43 | + primary_planes_.push_back(plane.get()); | |
44 | + else if (use_overlay_planes && plane->type() == DRM_PLANE_TYPE_OVERLAY) | |
45 | + overlay_planes_.push_back(plane.get()); | |
46 | + } | |
47 | +} | |
48 | + | |
49 | +int DrmComposition::Init(uint64_t frame_no) { | |
50 | + for (auto &conn : drm_->connectors()) { | |
51 | + int display = conn->display(); | |
52 | + composition_map_[display].reset(new DrmDisplayComposition()); | |
53 | + if (!composition_map_[display]) { | |
54 | + ALOGE("Failed to allocate new display composition\n"); | |
55 | + return -ENOMEM; | |
56 | + } | |
57 | + | |
58 | + // If the display hasn't been modeset yet, this will be NULL | |
59 | + DrmCrtc *crtc = drm_->GetCrtcForDisplay(display); | |
60 | + | |
61 | + int ret = composition_map_[display]->Init(drm_, crtc, importer_, planner_, | |
62 | + frame_no); | |
63 | + if (ret) { | |
64 | + ALOGE("Failed to init display composition for %d", display); | |
65 | + return ret; | |
66 | + } | |
67 | + } | |
68 | + return 0; | |
69 | +} | |
70 | + | |
71 | +int DrmComposition::SetLayers(size_t num_displays, | |
72 | + DrmCompositionDisplayLayersMap *maps) { | |
73 | + int ret = 0; | |
74 | + for (size_t display_index = 0; display_index < num_displays; | |
75 | + display_index++) { | |
76 | + DrmCompositionDisplayLayersMap &map = maps[display_index]; | |
77 | + int display = map.display; | |
78 | + | |
79 | + if (!drm_->GetConnectorForDisplay(display)) { | |
80 | + ALOGE("Invalid display given to SetLayers %d", display); | |
81 | + continue; | |
82 | + } | |
83 | + | |
84 | + ret = composition_map_[display]->SetLayers( | |
85 | + map.layers.data(), map.layers.size(), map.geometry_changed); | |
86 | + if (ret) | |
87 | + return ret; | |
88 | + } | |
89 | + | |
90 | + return 0; | |
91 | +} | |
92 | + | |
93 | +int DrmComposition::SetDpmsMode(int display, uint32_t dpms_mode) { | |
94 | + return composition_map_[display]->SetDpmsMode(dpms_mode); | |
95 | +} | |
96 | + | |
97 | +int DrmComposition::SetDisplayMode(int display, const DrmMode &display_mode) { | |
98 | + return composition_map_[display]->SetDisplayMode(display_mode); | |
99 | +} | |
100 | + | |
101 | +std::unique_ptr<DrmDisplayComposition> DrmComposition::TakeDisplayComposition( | |
102 | + int display) { | |
103 | + return std::move(composition_map_[display]); | |
104 | +} | |
105 | + | |
106 | +int DrmComposition::Plan(std::map<int, DrmDisplayCompositor> &compositor_map) { | |
107 | + int ret = 0; | |
108 | + for (auto &conn : drm_->connectors()) { | |
109 | + int display = conn->display(); | |
110 | + DrmDisplayComposition *comp = GetDisplayComposition(display); | |
111 | + ret = comp->Plan(compositor_map[display].squash_state(), &primary_planes_, | |
112 | + &overlay_planes_); | |
113 | + if (ret) { | |
114 | + ALOGE("Failed to plan composition for dislay %d", display); | |
115 | + return ret; | |
116 | + } | |
117 | + } | |
118 | + | |
119 | + return 0; | |
120 | +} | |
121 | + | |
122 | +int DrmComposition::DisableUnusedPlanes() { | |
123 | + for (auto &conn : drm_->connectors()) { | |
124 | + int display = conn->display(); | |
125 | + DrmDisplayComposition *comp = GetDisplayComposition(display); | |
126 | + | |
127 | + /* | |
128 | + * Leave empty compositions alone | |
129 | + * TODO: re-visit this and potentially disable leftover planes after the | |
130 | + * active compositions have gobbled up all they can | |
131 | + */ | |
132 | + if (comp->type() == DRM_COMPOSITION_TYPE_EMPTY || | |
133 | + comp->type() == DRM_COMPOSITION_TYPE_MODESET) | |
134 | + continue; | |
135 | + | |
136 | + DrmCrtc *crtc = drm_->GetCrtcForDisplay(display); | |
137 | + if (!crtc) { | |
138 | + ALOGE("Failed to find crtc for display %d", display); | |
139 | + continue; | |
140 | + } | |
141 | + | |
142 | + for (std::vector<DrmPlane *>::iterator iter = primary_planes_.begin(); | |
143 | + iter != primary_planes_.end(); ++iter) { | |
144 | + if ((*iter)->GetCrtcSupported(*crtc)) { | |
145 | + comp->AddPlaneDisable(*iter); | |
146 | + primary_planes_.erase(iter); | |
147 | + break; | |
148 | + } | |
149 | + } | |
150 | + for (std::vector<DrmPlane *>::iterator iter = overlay_planes_.begin(); | |
151 | + iter != overlay_planes_.end();) { | |
152 | + if ((*iter)->GetCrtcSupported(*crtc)) { | |
153 | + comp->AddPlaneDisable(*iter); | |
154 | + iter = overlay_planes_.erase(iter); | |
155 | + } else { | |
156 | + iter++; | |
157 | + } | |
158 | + } | |
159 | + } | |
160 | + return 0; | |
161 | +} | |
162 | + | |
163 | +DrmDisplayComposition *DrmComposition::GetDisplayComposition(int display) { | |
164 | + return composition_map_[display].get(); | |
165 | +} | |
166 | +} |
@@ -0,0 +1,79 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2015 The Android Open Source Project | |
3 | + * | |
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 | +#ifndef ANDROID_DRM_COMPOSITION_H_ | |
18 | +#define ANDROID_DRM_COMPOSITION_H_ | |
19 | + | |
20 | +#include "drmhwcomposer.h" | |
21 | +#include "drmdisplaycomposition.h" | |
22 | +#include "drmplane.h" | |
23 | +#include "platform.h" | |
24 | + | |
25 | +#include <map> | |
26 | +#include <vector> | |
27 | + | |
28 | +#include <hardware/hardware.h> | |
29 | +#include <hardware/hwcomposer.h> | |
30 | + | |
31 | +namespace android { | |
32 | + | |
33 | +class DrmDisplayCompositor; | |
34 | + | |
35 | +struct DrmCompositionDisplayLayersMap { | |
36 | + int display; | |
37 | + bool geometry_changed = true; | |
38 | + std::vector<DrmHwcLayer> layers; | |
39 | + | |
40 | + DrmCompositionDisplayLayersMap() = default; | |
41 | + DrmCompositionDisplayLayersMap(DrmCompositionDisplayLayersMap &&rhs) = | |
42 | + default; | |
43 | +}; | |
44 | + | |
45 | +class DrmComposition { | |
46 | + public: | |
47 | + DrmComposition(DrmResources *drm, Importer *importer, Planner *planner); | |
48 | + | |
49 | + int Init(uint64_t frame_no); | |
50 | + | |
51 | + int SetLayers(size_t num_displays, DrmCompositionDisplayLayersMap *maps); | |
52 | + int SetDpmsMode(int display, uint32_t dpms_mode); | |
53 | + int SetDisplayMode(int display, const DrmMode &display_mode); | |
54 | + | |
55 | + std::unique_ptr<DrmDisplayComposition> TakeDisplayComposition(int display); | |
56 | + DrmDisplayComposition *GetDisplayComposition(int display); | |
57 | + | |
58 | + int Plan(std::map<int, DrmDisplayCompositor> &compositor_map); | |
59 | + int DisableUnusedPlanes(); | |
60 | + | |
61 | + private: | |
62 | + DrmComposition(const DrmComposition &) = delete; | |
63 | + | |
64 | + DrmResources *drm_; | |
65 | + Importer *importer_; | |
66 | + Planner *planner_; | |
67 | + | |
68 | + std::vector<DrmPlane *> primary_planes_; | |
69 | + std::vector<DrmPlane *> overlay_planes_; | |
70 | + | |
71 | + /* | |
72 | + * This _must_ be read-only after it's passed to QueueComposition. Otherwise | |
73 | + * locking is required to maintain consistency across the compositor threads. | |
74 | + */ | |
75 | + std::map<int, std::unique_ptr<DrmDisplayComposition>> composition_map_; | |
76 | +}; | |
77 | +} | |
78 | + | |
79 | +#endif // ANDROID_DRM_COMPOSITION_H_ |
@@ -0,0 +1,106 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2015 The Android Open Source Project | |
3 | + * | |
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-drm-compositor" | |
18 | + | |
19 | +#include "drmcompositor.h" | |
20 | +#include "drmdisplaycompositor.h" | |
21 | +#include "drmresources.h" | |
22 | +#include "platform.h" | |
23 | + | |
24 | +#include <sstream> | |
25 | +#include <stdlib.h> | |
26 | + | |
27 | +#include <cutils/log.h> | |
28 | + | |
29 | +namespace android { | |
30 | + | |
31 | +DrmCompositor::DrmCompositor(DrmResources *drm) : drm_(drm), frame_no_(0) { | |
32 | +} | |
33 | + | |
34 | +DrmCompositor::~DrmCompositor() { | |
35 | +} | |
36 | + | |
37 | +int DrmCompositor::Init() { | |
38 | + for (auto &conn : drm_->connectors()) { | |
39 | + int display = conn->display(); | |
40 | + int ret = compositor_map_[display].Init(drm_, display); | |
41 | + if (ret) { | |
42 | + ALOGE("Failed to initialize display compositor for %d", display); | |
43 | + return ret; | |
44 | + } | |
45 | + } | |
46 | + planner_ = Planner::CreateInstance(drm_); | |
47 | + if (!planner_) { | |
48 | + ALOGE("Failed to create planner instance for composition"); | |
49 | + return -ENOMEM; | |
50 | + } | |
51 | + | |
52 | + return 0; | |
53 | +} | |
54 | + | |
55 | +std::unique_ptr<DrmComposition> DrmCompositor::CreateComposition( | |
56 | + Importer *importer) { | |
57 | + std::unique_ptr<DrmComposition> composition( | |
58 | + new DrmComposition(drm_, importer, planner_.get())); | |
59 | + int ret = composition->Init(++frame_no_); | |
60 | + if (ret) { | |
61 | + ALOGE("Failed to initialize drm composition %d", ret); | |
62 | + return nullptr; | |
63 | + } | |
64 | + return composition; | |
65 | +} | |
66 | + | |
67 | +int DrmCompositor::QueueComposition( | |
68 | + std::unique_ptr<DrmComposition> composition) { | |
69 | + int ret; | |
70 | + | |
71 | + ret = composition->Plan(compositor_map_); | |
72 | + if (ret) | |
73 | + return ret; | |
74 | + | |
75 | + ret = composition->DisableUnusedPlanes(); | |
76 | + if (ret) | |
77 | + return ret; | |
78 | + | |
79 | + for (auto &conn : drm_->connectors()) { | |
80 | + int display = conn->display(); | |
81 | + int ret = compositor_map_[display].QueueComposition( | |
82 | + composition->TakeDisplayComposition(display)); | |
83 | + if (ret) { | |
84 | + ALOGE("Failed to queue composition for display %d (%d)", display, ret); | |
85 | + return ret; | |
86 | + } | |
87 | + } | |
88 | + | |
89 | + return 0; | |
90 | +} | |
91 | + | |
92 | +int DrmCompositor::Composite() { | |
93 | + /* | |
94 | + * This shouldn't be called, we should be calling Composite() on the display | |
95 | + * compositors directly. | |
96 | + */ | |
97 | + ALOGE("Calling base drm compositor Composite() function"); | |
98 | + return -EINVAL; | |
99 | +} | |
100 | + | |
101 | +void DrmCompositor::Dump(std::ostringstream *out) const { | |
102 | + *out << "DrmCompositor stats:\n"; | |
103 | + for (auto &conn : drm_->connectors()) | |
104 | + compositor_map_[conn->display()].Dump(out); | |
105 | +} | |
106 | +} |
@@ -0,0 +1,56 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2015 The Android Open Source Project | |
3 | + * | |
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 | +#ifndef ANDROID_DRM_COMPOSITOR_H_ | |
18 | +#define ANDROID_DRM_COMPOSITOR_H_ | |
19 | + | |
20 | +#include "drmcomposition.h" | |
21 | +#include "drmdisplaycompositor.h" | |
22 | +#include "platform.h" | |
23 | + | |
24 | +#include <map> | |
25 | +#include <memory> | |
26 | +#include <sstream> | |
27 | + | |
28 | +namespace android { | |
29 | + | |
30 | +class DrmCompositor { | |
31 | + public: | |
32 | + DrmCompositor(DrmResources *drm); | |
33 | + ~DrmCompositor(); | |
34 | + | |
35 | + int Init(); | |
36 | + | |
37 | + std::unique_ptr<DrmComposition> CreateComposition(Importer *importer); | |
38 | + | |
39 | + int QueueComposition(std::unique_ptr<DrmComposition> composition); | |
40 | + int Composite(); | |
41 | + void Dump(std::ostringstream *out) const; | |
42 | + | |
43 | + private: | |
44 | + DrmCompositor(const DrmCompositor &) = delete; | |
45 | + | |
46 | + DrmResources *drm_; | |
47 | + std::unique_ptr<Planner> planner_; | |
48 | + | |
49 | + uint64_t frame_no_; | |
50 | + | |
51 | + // mutable for Dump() propagation | |
52 | + mutable std::map<int, DrmDisplayCompositor> compositor_map_; | |
53 | +}; | |
54 | +} | |
55 | + | |
56 | +#endif // ANDROID_DRM_COMPOSITOR_H_ |
@@ -0,0 +1,41 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2015 The Android Open Source Project | |
3 | + * | |
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 | +#ifndef ANDROID_DRM_COMPOSITOR_WORKER_H_ | |
18 | +#define ANDROID_DRM_COMPOSITOR_WORKER_H_ | |
19 | + | |
20 | +#include "worker.h" | |
21 | + | |
22 | +namespace android { | |
23 | + | |
24 | +class DrmDisplayCompositor; | |
25 | + | |
26 | +class DrmCompositorWorker : public Worker { | |
27 | + public: | |
28 | + DrmCompositorWorker(DrmDisplayCompositor *compositor); | |
29 | + ~DrmCompositorWorker() override; | |
30 | + | |
31 | + int Init(); | |
32 | + | |
33 | + protected: | |
34 | + void Routine() override; | |
35 | + | |
36 | + DrmDisplayCompositor *compositor_; | |
37 | + bool did_squash_all_ = false; | |
38 | +}; | |
39 | +} | |
40 | + | |
41 | +#endif |
@@ -17,7 +17,6 @@ | ||
17 | 17 | #define LOG_TAG "hwc-drm-display-composition" |
18 | 18 | |
19 | 19 | #include "drmdisplaycomposition.h" |
20 | -#include "drmdisplaycompositor.h" | |
21 | 20 | #include "drmcrtc.h" |
22 | 21 | #include "drmplane.h" |
23 | 22 | #include "drmresources.h" |
@@ -42,16 +42,6 @@ enum DrmCompositionType { | ||
42 | 42 | DRM_COMPOSITION_TYPE_MODESET, |
43 | 43 | }; |
44 | 44 | |
45 | -struct DrmCompositionDisplayLayersMap { | |
46 | - int display; | |
47 | - bool geometry_changed = true; | |
48 | - std::vector<DrmHwcLayer> layers; | |
49 | - | |
50 | - DrmCompositionDisplayLayersMap() = default; | |
51 | - DrmCompositionDisplayLayersMap(DrmCompositionDisplayLayersMap &&rhs) = | |
52 | - default; | |
53 | -}; | |
54 | - | |
55 | 45 | struct DrmCompositionRegion { |
56 | 46 | DrmHwcRect<int> frame; |
57 | 47 | std::vector<size_t> source_layers; |
@@ -37,6 +37,8 @@ | ||
37 | 37 | #include "drmresources.h" |
38 | 38 | #include "glworker.h" |
39 | 39 | |
40 | +#define DRM_DISPLAY_COMPOSITOR_MAX_QUEUE_DEPTH 2 | |
41 | + | |
40 | 42 | namespace android { |
41 | 43 | |
42 | 44 | void SquashState::Init(DrmHwcLayer *layers, size_t num_layers) { |
@@ -174,9 +176,58 @@ static bool UsesSquash(const std::vector<DrmCompositionPlane> &comp_planes) { | ||
174 | 176 | }); |
175 | 177 | } |
176 | 178 | |
179 | +DrmDisplayCompositor::FrameWorker::FrameWorker(DrmDisplayCompositor *compositor) | |
180 | + : Worker("frame-worker", HAL_PRIORITY_URGENT_DISPLAY), | |
181 | + compositor_(compositor) { | |
182 | +} | |
183 | + | |
184 | +DrmDisplayCompositor::FrameWorker::~FrameWorker() { | |
185 | +} | |
186 | + | |
187 | +int DrmDisplayCompositor::FrameWorker::Init() { | |
188 | + return InitWorker(); | |
189 | +} | |
190 | + | |
191 | +void DrmDisplayCompositor::FrameWorker::QueueFrame( | |
192 | + std::unique_ptr<DrmDisplayComposition> composition, int status) { | |
193 | + Lock(); | |
194 | + FrameState frame; | |
195 | + frame.composition = std::move(composition); | |
196 | + frame.status = status; | |
197 | + frame_queue_.push(std::move(frame)); | |
198 | + Unlock(); | |
199 | + Signal(); | |
200 | +} | |
201 | + | |
202 | +void DrmDisplayCompositor::FrameWorker::Routine() { | |
203 | + int wait_ret = 0; | |
204 | + | |
205 | + Lock(); | |
206 | + if (frame_queue_.empty()) { | |
207 | + wait_ret = WaitForSignalOrExitLocked(); | |
208 | + } | |
209 | + | |
210 | + FrameState frame; | |
211 | + if (!frame_queue_.empty()) { | |
212 | + frame = std::move(frame_queue_.front()); | |
213 | + frame_queue_.pop(); | |
214 | + } | |
215 | + Unlock(); | |
216 | + | |
217 | + if (wait_ret == -EINTR) { | |
218 | + return; | |
219 | + } else if (wait_ret) { | |
220 | + ALOGE("Failed to wait for signal, %d", wait_ret); | |
221 | + return; | |
222 | + } | |
223 | + compositor_->ApplyFrame(std::move(frame.composition), frame.status); | |
224 | +} | |
225 | + | |
177 | 226 | DrmDisplayCompositor::DrmDisplayCompositor() |
178 | 227 | : drm_(NULL), |
179 | 228 | display_(-1), |
229 | + worker_(this), | |
230 | + frame_worker_(this), | |
180 | 231 | initialized_(false), |
181 | 232 | active_(false), |
182 | 233 | use_hw_overlays_(true), |
@@ -194,6 +245,9 @@ DrmDisplayCompositor::~DrmDisplayCompositor() { | ||
194 | 245 | if (!initialized_) |
195 | 246 | return; |
196 | 247 | |
248 | + worker_.Exit(); | |
249 | + frame_worker_.Exit(); | |
250 | + | |
197 | 251 | int ret = pthread_mutex_lock(&lock_); |
198 | 252 | if (ret) |
199 | 253 | ALOGE("Failed to acquire compositor lock %d", ret); |
@@ -203,6 +257,10 @@ DrmDisplayCompositor::~DrmDisplayCompositor() { | ||
203 | 257 | if (mode_.old_blob_id) |
204 | 258 | drm_->DestroyPropertyBlob(mode_.old_blob_id); |
205 | 259 | |
260 | + while (!composite_queue_.empty()) { | |
261 | + composite_queue_.front().reset(); | |
262 | + composite_queue_.pop(); | |
263 | + } | |
206 | 264 | active_composition_.reset(); |
207 | 265 | |
208 | 266 | ret = pthread_mutex_unlock(&lock_); |
@@ -221,6 +279,18 @@ int DrmDisplayCompositor::Init(DrmResources *drm, int display) { | ||
221 | 279 | ALOGE("Failed to initialize drm compositor lock %d\n", ret); |
222 | 280 | return ret; |
223 | 281 | } |
282 | + ret = worker_.Init(); | |
283 | + if (ret) { | |
284 | + pthread_mutex_destroy(&lock_); | |
285 | + ALOGE("Failed to initialize compositor worker %d\n", ret); | |
286 | + return ret; | |
287 | + } | |
288 | + ret = frame_worker_.Init(); | |
289 | + if (ret) { | |
290 | + pthread_mutex_destroy(&lock_); | |
291 | + ALOGE("Failed to initialize frame worker %d\n", ret); | |
292 | + return ret; | |
293 | + } | |
224 | 294 | |
225 | 295 | initialized_ = true; |
226 | 296 | return 0; |
@@ -231,6 +301,55 @@ std::unique_ptr<DrmDisplayComposition> DrmDisplayCompositor::CreateComposition() | ||
231 | 301 | return std::unique_ptr<DrmDisplayComposition>(new DrmDisplayComposition()); |
232 | 302 | } |
233 | 303 | |
304 | +int DrmDisplayCompositor::QueueComposition( | |
305 | + std::unique_ptr<DrmDisplayComposition> composition) { | |
306 | + switch (composition->type()) { | |
307 | + case DRM_COMPOSITION_TYPE_FRAME: | |
308 | + if (!active_) | |
309 | + return -ENODEV; | |
310 | + break; | |
311 | + case DRM_COMPOSITION_TYPE_DPMS: | |
312 | + /* | |
313 | + * Update the state as soon as we get it so we can start/stop queuing | |
314 | + * frames asap. | |
315 | + */ | |
316 | + active_ = (composition->dpms_mode() == DRM_MODE_DPMS_ON); | |
317 | + break; | |
318 | + case DRM_COMPOSITION_TYPE_MODESET: | |
319 | + break; | |
320 | + case DRM_COMPOSITION_TYPE_EMPTY: | |
321 | + return 0; | |
322 | + default: | |
323 | + ALOGE("Unknown composition type %d/%d", composition->type(), display_); | |
324 | + return -ENOENT; | |
325 | + } | |
326 | + | |
327 | + int ret = pthread_mutex_lock(&lock_); | |
328 | + if (ret) { | |
329 | + ALOGE("Failed to acquire compositor lock %d", ret); | |
330 | + return ret; | |
331 | + } | |
332 | + | |
333 | + // Block the queue if it gets too large. Otherwise, SurfaceFlinger will start | |
334 | + // to eat our buffer handles when we get about 1 second behind. | |
335 | + while (composite_queue_.size() >= DRM_DISPLAY_COMPOSITOR_MAX_QUEUE_DEPTH) { | |
336 | + pthread_mutex_unlock(&lock_); | |
337 | + sched_yield(); | |
338 | + pthread_mutex_lock(&lock_); | |
339 | + } | |
340 | + | |
341 | + composite_queue_.push(std::move(composition)); | |
342 | + | |
343 | + ret = pthread_mutex_unlock(&lock_); | |
344 | + if (ret) { | |
345 | + ALOGE("Failed to release compositor lock %d", ret); | |
346 | + return ret; | |
347 | + } | |
348 | + | |
349 | + worker_.Signal(); | |
350 | + return 0; | |
351 | +} | |
352 | + | |
234 | 353 | std::tuple<uint32_t, uint32_t, int> |
235 | 354 | DrmDisplayCompositor::GetActiveModeResolution() { |
236 | 355 | DrmConnector *connector = drm_->GetConnectorForDisplay(display_); |
@@ -395,15 +514,6 @@ int DrmDisplayCompositor::PrepareFrame(DrmDisplayComposition *display_comp) { | ||
395 | 514 | std::vector<DrmCompositionRegion> &pre_comp_regions = |
396 | 515 | display_comp->pre_comp_regions(); |
397 | 516 | |
398 | - if (!pre_compositor_) { | |
399 | - pre_compositor_.reset(new GLWorkerCompositor()); | |
400 | - int ret = pre_compositor_->Init(); | |
401 | - if (ret) { | |
402 | - ALOGE("Failed to initialize OpenGL compositor %d", ret); | |
403 | - return ret; | |
404 | - } | |
405 | - } | |
406 | - | |
407 | 517 | int squash_layer_index = -1; |
408 | 518 | if (squash_regions.size() > 0) { |
409 | 519 | squash_framebuffer_index_ = (squash_framebuffer_index_ + 1) % 2; |
@@ -810,9 +920,41 @@ void DrmDisplayCompositor::ApplyFrame( | ||
810 | 920 | ALOGE("Failed to release lock for active_composition swap"); |
811 | 921 | } |
812 | 922 | |
813 | -int DrmDisplayCompositor::ApplyComposition( | |
814 | - std::unique_ptr<DrmDisplayComposition> composition) { | |
815 | - int ret = 0; | |
923 | +int DrmDisplayCompositor::Composite() { | |
924 | + ATRACE_CALL(); | |
925 | + | |
926 | + if (!pre_compositor_) { | |
927 | + pre_compositor_.reset(new GLWorkerCompositor()); | |
928 | + int ret = pre_compositor_->Init(); | |
929 | + if (ret) { | |
930 | + ALOGE("Failed to initialize OpenGL compositor %d", ret); | |
931 | + return ret; | |
932 | + } | |
933 | + } | |
934 | + | |
935 | + int ret = pthread_mutex_lock(&lock_); | |
936 | + if (ret) { | |
937 | + ALOGE("Failed to acquire compositor lock %d", ret); | |
938 | + return ret; | |
939 | + } | |
940 | + if (composite_queue_.empty()) { | |
941 | + ret = pthread_mutex_unlock(&lock_); | |
942 | + if (ret) | |
943 | + ALOGE("Failed to release compositor lock %d", ret); | |
944 | + return ret; | |
945 | + } | |
946 | + | |
947 | + std::unique_ptr<DrmDisplayComposition> composition( | |
948 | + std::move(composite_queue_.front())); | |
949 | + | |
950 | + composite_queue_.pop(); | |
951 | + | |
952 | + ret = pthread_mutex_unlock(&lock_); | |
953 | + if (ret) { | |
954 | + ALOGE("Failed to release compositor lock %d", ret); | |
955 | + return ret; | |
956 | + } | |
957 | + | |
816 | 958 | switch (composition->type()) { |
817 | 959 | case DRM_COMPOSITION_TYPE_FRAME: |
818 | 960 | ret = PrepareFrame(composition.get()); |
@@ -831,7 +973,7 @@ int DrmDisplayCompositor::ApplyComposition( | ||
831 | 973 | } |
832 | 974 | |
833 | 975 | // If use_hw_overlays_ is false, we can't use hardware to composite the |
834 | - // frame. So squash all layers into a single composition and apply that | |
976 | + // frame. So squash all layers into a single composition and queue that | |
835 | 977 | // instead. |
836 | 978 | if (!use_hw_overlays_) { |
837 | 979 | std::unique_ptr<DrmDisplayComposition> squashed = CreateComposition(); |
@@ -847,10 +989,9 @@ int DrmDisplayCompositor::ApplyComposition( | ||
847 | 989 | return ret; |
848 | 990 | } |
849 | 991 | } |
850 | - ApplyFrame(std::move(composition), ret); | |
992 | + frame_worker_.QueueFrame(std::move(composition), ret); | |
851 | 993 | break; |
852 | 994 | case DRM_COMPOSITION_TYPE_DPMS: |
853 | - active_ = (composition->dpms_mode() == DRM_MODE_DPMS_ON); | |
854 | 995 | ret = ApplyDpms(composition.get()); |
855 | 996 | if (ret) |
856 | 997 | ALOGE("Failed to apply dpms for display %d", display_); |
@@ -874,6 +1015,24 @@ int DrmDisplayCompositor::ApplyComposition( | ||
874 | 1015 | return ret; |
875 | 1016 | } |
876 | 1017 | |
1018 | +bool DrmDisplayCompositor::HaveQueuedComposites() const { | |
1019 | + int ret = pthread_mutex_lock(&lock_); | |
1020 | + if (ret) { | |
1021 | + ALOGE("Failed to acquire compositor lock %d", ret); | |
1022 | + return false; | |
1023 | + } | |
1024 | + | |
1025 | + bool empty_ret = !composite_queue_.empty(); | |
1026 | + | |
1027 | + ret = pthread_mutex_unlock(&lock_); | |
1028 | + if (ret) { | |
1029 | + ALOGE("Failed to release compositor lock %d", ret); | |
1030 | + return false; | |
1031 | + } | |
1032 | + | |
1033 | + return empty_ret; | |
1034 | +} | |
1035 | + | |
877 | 1036 | int DrmDisplayCompositor::SquashAll() { |
878 | 1037 | AutoLock lock(&lock_, "compositor"); |
879 | 1038 | int ret = lock.Lock(); |
@@ -18,12 +18,14 @@ | ||
18 | 18 | #define ANDROID_DRM_DISPLAY_COMPOSITOR_H_ |
19 | 19 | |
20 | 20 | #include "drmhwcomposer.h" |
21 | -#include "drmdisplaycomposition.h" | |
21 | +#include "drmcomposition.h" | |
22 | +#include "drmcompositorworker.h" | |
22 | 23 | #include "drmframebuffer.h" |
23 | 24 | #include "separate_rects.h" |
24 | 25 | |
25 | 26 | #include <pthread.h> |
26 | 27 | #include <memory> |
28 | +#include <queue> | |
27 | 29 | #include <sstream> |
28 | 30 | #include <tuple> |
29 | 31 |
@@ -87,18 +89,42 @@ class DrmDisplayCompositor { | ||
87 | 89 | int Init(DrmResources *drm, int display); |
88 | 90 | |
89 | 91 | std::unique_ptr<DrmDisplayComposition> CreateComposition() const; |
90 | - int ApplyComposition(std::unique_ptr<DrmDisplayComposition> composition); | |
92 | + int QueueComposition(std::unique_ptr<DrmDisplayComposition> composition); | |
91 | 93 | int Composite(); |
92 | 94 | int SquashAll(); |
93 | 95 | void Dump(std::ostringstream *out) const; |
94 | 96 | |
95 | 97 | std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution(); |
96 | 98 | |
99 | + bool HaveQueuedComposites() const; | |
100 | + | |
97 | 101 | SquashState *squash_state() { |
98 | 102 | return &squash_state_; |
99 | 103 | } |
100 | 104 | |
101 | 105 | private: |
106 | + struct FrameState { | |
107 | + std::unique_ptr<DrmDisplayComposition> composition; | |
108 | + int status = 0; | |
109 | + }; | |
110 | + | |
111 | + class FrameWorker : public Worker { | |
112 | + public: | |
113 | + FrameWorker(DrmDisplayCompositor *compositor); | |
114 | + ~FrameWorker() override; | |
115 | + | |
116 | + int Init(); | |
117 | + void QueueFrame(std::unique_ptr<DrmDisplayComposition> composition, | |
118 | + int status); | |
119 | + | |
120 | + protected: | |
121 | + void Routine() override; | |
122 | + | |
123 | + private: | |
124 | + DrmDisplayCompositor *compositor_; | |
125 | + std::queue<FrameState> frame_queue_; | |
126 | + }; | |
127 | + | |
102 | 128 | struct ModeState { |
103 | 129 | bool needs_modeset = false; |
104 | 130 | DrmMode mode; |
@@ -132,6 +158,10 @@ class DrmDisplayCompositor { | ||
132 | 158 | DrmResources *drm_; |
133 | 159 | int display_; |
134 | 160 | |
161 | + DrmCompositorWorker worker_; | |
162 | + FrameWorker frame_worker_; | |
163 | + | |
164 | + std::queue<std::unique_ptr<DrmDisplayComposition>> composite_queue_; | |
135 | 165 | std::unique_ptr<DrmDisplayComposition> active_composition_; |
136 | 166 | |
137 | 167 | bool initialized_; |
@@ -148,7 +178,7 @@ class DrmDisplayCompositor { | ||
148 | 178 | int squash_framebuffer_index_; |
149 | 179 | DrmFramebuffer squash_framebuffers_[2]; |
150 | 180 | |
151 | - // mutable since we need to acquire in Dump() | |
181 | + // mutable since we need to acquire in HaveQueuedComposites | |
152 | 182 | mutable pthread_mutex_t lock_; |
153 | 183 | |
154 | 184 | // State tracking progress since our last Dump(). These are mutable since |
@@ -20,13 +20,10 @@ | ||
20 | 20 | #include "drmresources.h" |
21 | 21 | |
22 | 22 | #include <assert.h> |
23 | -#include <errno.h> | |
24 | 23 | #include <linux/netlink.h> |
25 | 24 | #include <sys/socket.h> |
26 | 25 | |
27 | 26 | #include <cutils/log.h> |
28 | -#include <hardware/hardware.h> | |
29 | -#include <hardware/hwcomposer.h> | |
30 | 27 | #include <xf86drm.h> |
31 | 28 | #include <assert.h> |
32 | 29 |
@@ -559,7 +559,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { | ||
559 | 559 | |
560 | 560 | AddFenceToRetireFence(composition->take_out_fence()); |
561 | 561 | |
562 | - ret = compositor_.ApplyComposition(std::move(composition)); | |
562 | + ret = compositor_.QueueComposition(std::move(composition)); | |
563 | 563 | if (ret) { |
564 | 564 | ALOGE("Failed to apply the frame composition ret=%d", ret); |
565 | 565 | return HWC2::Error::BadParameter; |
@@ -588,7 +588,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) { | ||
588 | 588 | compositor_.CreateComposition(); |
589 | 589 | composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_); |
590 | 590 | int ret = composition->SetDisplayMode(*mode); |
591 | - ret = compositor_.ApplyComposition(std::move(composition)); | |
591 | + ret = compositor_.QueueComposition(std::move(composition)); | |
592 | 592 | if (ret) { |
593 | 593 | ALOGE("Failed to queue dpms composition on %d", ret); |
594 | 594 | return HWC2::Error::BadConfig; |
@@ -668,7 +668,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) { | ||
668 | 668 | compositor_.CreateComposition(); |
669 | 669 | composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_); |
670 | 670 | composition->SetDpmsMode(dpms_value); |
671 | - int ret = compositor_.ApplyComposition(std::move(composition)); | |
671 | + int ret = compositor_.QueueComposition(std::move(composition)); | |
672 | 672 | if (ret) { |
673 | 673 | ALOGE("Failed to apply the dpms composition ret=%d", ret); |
674 | 674 | return HWC2::Error::BadParameter; |
@@ -35,7 +35,7 @@ | ||
35 | 35 | |
36 | 36 | namespace android { |
37 | 37 | |
38 | -DrmResources::DrmResources() : event_listener_(this) { | |
38 | +DrmResources::DrmResources() : compositor_(this), event_listener_(this) { | |
39 | 39 | } |
40 | 40 | |
41 | 41 | DrmResources::~DrmResources() { |
@@ -213,6 +213,10 @@ int DrmResources::Init() { | ||
213 | 213 | if (ret) |
214 | 214 | return ret; |
215 | 215 | |
216 | + ret = compositor_.Init(); | |
217 | + if (ret) | |
218 | + return ret; | |
219 | + | |
216 | 220 | ret = event_listener_.Init(); |
217 | 221 | if (ret) { |
218 | 222 | ALOGE("Can't initialize event listener %d", ret); |
@@ -345,6 +349,54 @@ int DrmResources::DestroyPropertyBlob(uint32_t blob_id) { | ||
345 | 349 | return 0; |
346 | 350 | } |
347 | 351 | |
352 | +int DrmResources::SetDisplayActiveMode(int display, const DrmMode &mode) { | |
353 | + std::unique_ptr<DrmComposition> comp(compositor_.CreateComposition(NULL)); | |
354 | + if (!comp) { | |
355 | + ALOGE("Failed to create composition for dpms on %d", display); | |
356 | + return -ENOMEM; | |
357 | + } | |
358 | + int ret = comp->SetDisplayMode(display, mode); | |
359 | + if (ret) { | |
360 | + ALOGE("Failed to add mode to composition on %d %d", display, ret); | |
361 | + return ret; | |
362 | + } | |
363 | + ret = compositor_.QueueComposition(std::move(comp)); | |
364 | + if (ret) { | |
365 | + ALOGE("Failed to queue dpms composition on %d %d", display, ret); | |
366 | + return ret; | |
367 | + } | |
368 | + return 0; | |
369 | +} | |
370 | + | |
371 | +int DrmResources::SetDpmsMode(int display, uint64_t mode) { | |
372 | + if (mode != DRM_MODE_DPMS_ON && mode != DRM_MODE_DPMS_OFF) { | |
373 | + ALOGE("Invalid dpms mode %" PRIu64, mode); | |
374 | + return -EINVAL; | |
375 | + } | |
376 | + | |
377 | + std::unique_ptr<DrmComposition> comp(compositor_.CreateComposition(NULL)); | |
378 | + if (!comp) { | |
379 | + ALOGE("Failed to create composition for dpms on %d", display); | |
380 | + return -ENOMEM; | |
381 | + } | |
382 | + int ret = comp->SetDpmsMode(display, mode); | |
383 | + if (ret) { | |
384 | + ALOGE("Failed to add dpms %" PRIu64 " to composition on %d %d", mode, | |
385 | + display, ret); | |
386 | + return ret; | |
387 | + } | |
388 | + ret = compositor_.QueueComposition(std::move(comp)); | |
389 | + if (ret) { | |
390 | + ALOGE("Failed to queue dpms composition on %d %d", display, ret); | |
391 | + return ret; | |
392 | + } | |
393 | + return 0; | |
394 | +} | |
395 | + | |
396 | +DrmCompositor *DrmResources::compositor() { | |
397 | + return &compositor_; | |
398 | +} | |
399 | + | |
348 | 400 | DrmEventListener *DrmResources::event_listener() { |
349 | 401 | return &event_listener_; |
350 | 402 | } |
@@ -17,6 +17,7 @@ | ||
17 | 17 | #ifndef ANDROID_DRM_H_ |
18 | 18 | #define ANDROID_DRM_H_ |
19 | 19 | |
20 | +#include "drmcompositor.h" | |
20 | 21 | #include "drmconnector.h" |
21 | 22 | #include "drmcrtc.h" |
22 | 23 | #include "drmencoder.h" |
@@ -57,6 +58,7 @@ class DrmResources { | ||
57 | 58 | DrmConnector *GetConnectorForDisplay(int display) const; |
58 | 59 | DrmCrtc *GetCrtcForDisplay(int display) const; |
59 | 60 | DrmPlane *GetPlane(uint32_t id) const; |
61 | + DrmCompositor *compositor(); | |
60 | 62 | DrmEventListener *event_listener(); |
61 | 63 | |
62 | 64 | int GetPlaneProperty(const DrmPlane &plane, const char *prop_name, |
@@ -68,6 +70,8 @@ class DrmResources { | ||
68 | 70 | |
69 | 71 | const std::vector<std::unique_ptr<DrmCrtc>> &crtcs() const; |
70 | 72 | uint32_t next_mode_id(); |
73 | + int SetDisplayActiveMode(int display, const DrmMode &mode); | |
74 | + int SetDpmsMode(int display, uint64_t mode); | |
71 | 75 | |
72 | 76 | int CreatePropertyBlob(void *data, size_t length, uint32_t *blob_id); |
73 | 77 | int DestroyPropertyBlob(uint32_t blob_id); |
@@ -86,6 +90,7 @@ class DrmResources { | ||
86 | 90 | std::vector<std::unique_ptr<DrmEncoder>> encoders_; |
87 | 91 | std::vector<std::unique_ptr<DrmCrtc>> crtcs_; |
88 | 92 | std::vector<std::unique_ptr<DrmPlane>> planes_; |
93 | + DrmCompositor compositor_; | |
89 | 94 | DrmEventListener event_listener_; |
90 | 95 | |
91 | 96 | std::pair<uint32_t, uint32_t> min_resolution_; |
@@ -143,38 +143,6 @@ static bool HasExtension(const char *extension, const char *extensions) { | ||
143 | 143 | return false; |
144 | 144 | } |
145 | 145 | |
146 | -int GLWorkerCompositor::BeginContext() { | |
147 | - private_.saved_egl_display = eglGetCurrentDisplay(); | |
148 | - private_.saved_egl_ctx = eglGetCurrentContext(); | |
149 | - | |
150 | - if (private_.saved_egl_display != egl_display_ || | |
151 | - private_.saved_egl_ctx != egl_ctx_) { | |
152 | - private_.saved_egl_read = eglGetCurrentSurface(EGL_READ); | |
153 | - private_.saved_egl_draw = eglGetCurrentSurface(EGL_DRAW); | |
154 | - } else { | |
155 | - return 0; | |
156 | - } | |
157 | - | |
158 | - if (!eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_ctx_)) { | |
159 | - ALOGE("BeginContext failed: %s", GetEGLError()); | |
160 | - return 1; | |
161 | - } | |
162 | - return 0; | |
163 | -} | |
164 | - | |
165 | -int GLWorkerCompositor::EndContext() { | |
166 | - if (private_.saved_egl_display != eglGetCurrentDisplay() || | |
167 | - private_.saved_egl_ctx != eglGetCurrentContext()) { | |
168 | - if (!eglMakeCurrent(private_.saved_egl_display, private_.saved_egl_read, | |
169 | - private_.saved_egl_draw, private_.saved_egl_ctx)) { | |
170 | - ALOGE("EndContext failed: %s", GetEGLError()); | |
171 | - return 1; | |
172 | - } | |
173 | - } | |
174 | - | |
175 | - return 0; | |
176 | -} | |
177 | - | |
178 | 146 | static AutoGLShader CompileAndCheckShader(GLenum type, unsigned source_count, |
179 | 147 | const GLchar **sources, |
180 | 148 | std::ostringstream *shader_log) { |
@@ -540,9 +508,10 @@ int GLWorkerCompositor::Init() { | ||
540 | 508 | return 1; |
541 | 509 | } |
542 | 510 | |
543 | - ret = BeginContext(); | |
544 | - if (ret) | |
545 | - return ret; | |
511 | + if (!eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_ctx_)) { | |
512 | + ALOGE("Failed to make the OpenGL ES Context current: %s", GetEGLError()); | |
513 | + return 1; | |
514 | + } | |
546 | 515 | |
547 | 516 | gl_extensions = (const char *)glGetString(GL_EXTENSIONS); |
548 | 517 |
@@ -561,9 +530,6 @@ int GLWorkerCompositor::Init() { | ||
561 | 530 | |
562 | 531 | std::ostringstream shader_log; |
563 | 532 | blend_programs_.emplace_back(GenerateProgram(1, &shader_log)); |
564 | - | |
565 | - EndContext(); | |
566 | - | |
567 | 533 | if (blend_programs_.back().get() == 0) { |
568 | 534 | ALOGE("%s", shader_log.str().c_str()); |
569 | 535 | return 1; |
@@ -592,17 +558,12 @@ int GLWorkerCompositor::Composite(DrmHwcLayer *layers, | ||
592 | 558 | return -EALREADY; |
593 | 559 | } |
594 | 560 | |
595 | - ret = BeginContext(); | |
596 | - if (ret) | |
597 | - return -1; | |
598 | - | |
599 | 561 | GLint frame_width = framebuffer->getWidth(); |
600 | 562 | GLint frame_height = framebuffer->getHeight(); |
601 | 563 | CachedFramebuffer *cached_framebuffer = |
602 | 564 | PrepareAndCacheFramebuffer(framebuffer); |
603 | 565 | if (cached_framebuffer == NULL) { |
604 | 566 | ALOGE("Composite failed because of failed framebuffer"); |
605 | - EndContext(); | |
606 | 567 | return -EINVAL; |
607 | 568 | } |
608 | 569 |
@@ -636,10 +597,8 @@ int GLWorkerCompositor::Composite(DrmHwcLayer *layers, | ||
636 | 597 | } |
637 | 598 | } |
638 | 599 | |
639 | - if (ret) { | |
640 | - EndContext(); | |
600 | + if (ret) | |
641 | 601 | return ret; |
642 | - } | |
643 | 602 | |
644 | 603 | glViewport(0, 0, frame_width, frame_height); |
645 | 604 |
@@ -717,7 +676,6 @@ int GLWorkerCompositor::Composite(DrmHwcLayer *layers, | ||
717 | 676 | |
718 | 677 | glBindFramebuffer(GL_FRAMEBUFFER, 0); |
719 | 678 | |
720 | - EndContext(); | |
721 | 679 | return ret; |
722 | 680 | } |
723 | 681 |
@@ -64,16 +64,6 @@ class GLWorkerCompositor { | ||
64 | 64 | bool Promote(); |
65 | 65 | }; |
66 | 66 | |
67 | - struct { | |
68 | - EGLDisplay saved_egl_display = EGL_NO_DISPLAY; | |
69 | - EGLContext saved_egl_ctx = EGL_NO_CONTEXT; | |
70 | - EGLSurface saved_egl_read = EGL_NO_SURFACE; | |
71 | - EGLSurface saved_egl_draw = EGL_NO_SURFACE; | |
72 | - } private_; | |
73 | - | |
74 | - int BeginContext(); | |
75 | - int EndContext(); | |
76 | - | |
77 | 67 | CachedFramebuffer *FindCachedFramebuffer( |
78 | 68 | const sp<GraphicBuffer> &framebuffer); |
79 | 69 | CachedFramebuffer *PrepareAndCacheFramebuffer( |