Skip to content

Commit d86cf94

Browse files
committed
implement both overlay and fbtarget code paths
1 parent bac2176 commit d86cf94

File tree

3 files changed

+112
-86
lines changed

3 files changed

+112
-86
lines changed

include/backend/sfhwc/sfhwc.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,21 @@ class SfHwcSurface : public SurfaceBackendImpl, public HWComposerNativeWindow
7070
return renderer;
7171
}
7272

73-
void present(HWComposerNativeWindowBuffer *buffer) override;
73+
void present(HWComposerNativeWindowBuffer *buffer) override;
74+
void presentAsOverlay(HWComposerNativeWindowBuffer *buffer);
75+
void presentAsFramebufferTarget(HWComposerNativeWindowBuffer *buffer);
7476

7577
Surface *m_surface;
7678
SfHwcBackend *m_backend;
7779

80+
std::list<SfHwcBuffer *> m_frameBuffers;
81+
7882
double m_vsyncDelta;
7983
vec2 m_size;
8084
vec2 m_dpi;
8185

86+
bool m_useOverlay;
87+
8288
hwc_display_contents_1_t *m_hwcList;
8389

8490
EGLDisplay m_eglDisplay;
@@ -151,6 +157,9 @@ class SfHwcBuffer
151157

152158
void fillWithCrap();
153159

160+
int fence() const { return m_fence; }
161+
void setFence(int fd) { m_fence = fd; }
162+
154163
private:
155164
gralloc_module_t *grallocModule() const { return m_backend->grallocModule; }
156165
alloc_device_t *allocDevice() const { return m_backend->allocDevice; }
@@ -161,6 +170,7 @@ class SfHwcBuffer
161170
int m_stride;
162171
int m_width;
163172
int m_height;
173+
int m_fence;
164174
};
165175

166176
#ifndef RENGINE_MAX_TOUCH_POINTS

include/backend/sfhwc/sfhwcbuffer.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ inline SfHwcBuffer::SfHwcBuffer(SfHwcBackend *backend, int w, int h, int format,
3535
, m_stride(0)
3636
, m_width(w)
3737
, m_height(w)
38+
, m_fence(-1)
3839
{
3940
if (w == 0 || h == 0)
4041
return;
@@ -136,4 +137,4 @@ inline void SfHwcBuffer::fillWithCrap()
136137
}
137138
}
138139

139-
RENGINE_END_NAMESPACE
140+
RENGINE_END_NAMESPACE

include/backend/sfhwc/sfhwcsurface.h

+99-84
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,14 @@ inline SfHwcSurface::SfHwcSurface(Surface *surface, SfHwcBackend *backend, vec2
120120
, m_backend(backend)
121121
, m_vsyncDelta(0)
122122
, m_size(size)
123+
, m_useOverlay(false)
123124
{
125+
char *overlay = getenv("RENGINE_SURFACE_USE_OVERLAY");
126+
if (overlay && atoi(overlay) != 0) {
127+
logi << "Using HWC_OVERLAY code path in HWC" << std::endl;
128+
m_useOverlay = true;
129+
}
130+
124131
int bufferCount = 3;
125132
char *overrideBufferCount = getenv("RENGINE_SURFACE_BUFFER_COUNT");
126133
if (overrideBufferCount) {
@@ -189,15 +196,34 @@ inline void SfHwcSurface::initHwc()
189196
memset(m_hwcList, 0, size);
190197

191198
m_hwcList->retireFenceFd = -1;
199+
m_hwcList->outbufAcquireFenceFd = -1;
192200
m_hwcList->flags = HWC_GEOMETRY_CHANGED;
193201
m_hwcList->numHwLayers = 2;
194202

195203
sfhwc_initialize_layer(&m_hwcList->hwLayers[0], HWC_FRAMEBUFFER, 0, 0, m_size.x, m_size.y);
196-
m_hwcList->hwLayers[0].planeAlpha = 1;
204+
205+
// The Qualcomm HWC doesn't support planar alpha, so by setting 1 we force
206+
// it to take the GLES composited path, in which case, the
207+
// HWC_FRAMEBUFFER_TARGET is used for direct presentation rather than
208+
// composition.
209+
if (m_useOverlay)
210+
m_hwcList->hwLayers[0].planeAlpha = 255;
211+
else
212+
m_hwcList->hwLayers[0].planeAlpha = 1;
197213

198214
sfhwc_initialize_layer(&m_hwcList->hwLayers[1], HWC_FRAMEBUFFER_TARGET, 0, 0, m_size.x, m_size.y);
199215
sfhwc_dump_display_contents(m_hwcList);
200216

217+
int bufferCount = 3;
218+
char *overrideBufferCount = getenv("RENGINE_SURFACE_TARGETBUFFER_COUNT");
219+
if (overrideBufferCount) {
220+
bufferCount = std::max(1, std::min(atoi(overrideBufferCount), 10));
221+
}
222+
logi << "using " << bufferCount << " HWC_FRAMEBUFFER_TARGET buffers";
223+
for (int i=0; i<bufferCount; ++i) {
224+
SfHwcBuffer *buffer = new SfHwcBuffer(m_backend, 720, 1280, HAL_PIXEL_FORMAT_BGRA_8888, GRALLOC_USAGE_HW_COMPOSER);
225+
m_frameBuffers.push_back(buffer);
226+
}
201227
}
202228

203229
inline void SfHwcSurface::initEgl()
@@ -253,115 +279,104 @@ inline void SfHwcSurface::initEgl()
253279

254280
inline void SfHwcSurface::present(HWComposerNativeWindowBuffer *buffer)
255281
{
256-
// logw << "buffer=" << (void *) buffer << std::endl;
257-
258-
int status = 0; (void) status;
259-
260-
static SfHwcBuffer *staticBuffer = 0;
261-
if (!staticBuffer) {
262-
staticBuffer = new SfHwcBuffer(m_backend, 720, 1280);
263-
staticBuffer->lock();
264-
staticBuffer->fillWithCrap();
265-
staticBuffer->unlock();
266-
}
282+
static auto lastFrame = std::chrono::steady_clock::now();
283+
auto thisFrame = std::chrono::steady_clock::now();
284+
auto delta = std::chrono::duration_cast<std::chrono::milliseconds>(thisFrame - lastFrame).count();
285+
if (delta > 30)
286+
logw << "MISSED A FRAME: " << delta << std::endl;
287+
lastFrame = thisFrame;
288+
289+
if (m_useOverlay)
290+
presentAsOverlay(buffer);
291+
else
292+
presentAsFramebufferTarget(buffer);
293+
}
267294

268-
static SfHwcBuffer *staticBuffer2 = 0;
269-
if (!staticBuffer2) {
270-
staticBuffer2 = new SfHwcBuffer(m_backend, 720, 1280);
271-
staticBuffer2->lock();
272-
staticBuffer2->fillWithCrap();
273-
staticBuffer2->unlock();
274-
}
295+
inline void SfHwcSurface::presentAsOverlay(HWComposerNativeWindowBuffer *buffer)
296+
{
297+
logw << "buffer=" << (void *) buffer << std::endl;
275298

276-
hwc_composer_device_1_t *hwc = m_backend->hwcDevice;
299+
int status = 0; (void) status;
277300

278-
// static auto lastFrame = std::chrono::steady_clock::now();
279-
// auto thisFrame = std::chrono::steady_clock::now();
280-
// auto delta = std::chrono::duration_cast<std::chrono::milliseconds>(thisFrame - lastFrame).count();
281-
// if (delta > 30)
282-
// logw << "MISSED A FRAME: " << delta << std::endl;
283-
// lastFrame = thisFrame;
301+
hwc_composer_device_1_t *hwc = m_backend->hwcDevice;
284302

285303
int fd = getFenceBufferFd(buffer);
286304
setFenceBufferFd(buffer, -1);
287-
#if 0
288-
if (fd != -1) {
289-
auto start = std::chrono::steady_clock::now();
290-
sync_wait(fd, -1);
291-
close(fd);
292-
auto end = std::chrono::steady_clock::now();
293-
auto delta = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / 1000.0;
294-
logw << " - sync waited on libhybris buffer: " << delta << ", buffer=" << buffer << std::endl;
295-
fd = -1;
296-
}
297-
#endif
298305

299-
hwc_layer_1_t *fb = &m_hwcList->hwLayers[0];
300-
fb->handle = staticBuffer->handle();
301-
fb->acquireFenceFd = -1;
302-
fb->releaseFenceFd = -1;
303-
fb->blending = 1;
304-
305-
static int counter = 0;
306-
counter = counter == 1 ? 0 : 1;
306+
hwc_layer_1_t *fb = &m_hwcList->hwLayers[0];
307+
fb->handle = buffer->handle;
308+
fb->acquireFenceFd = fd;
309+
fb->releaseFenceFd = -1;
307310

308311
hwc_layer_1_t *fbt = &m_hwcList->hwLayers[1];
309-
fbt->handle = buffer->handle;
310-
fbt->acquireFenceFd = fd;
312+
fbt->handle = m_frameBuffers.front()->handle();
313+
fbt->acquireFenceFd = m_frameBuffers.front()->fence();
311314
fbt->releaseFenceFd = -1;
312315

313-
// sfhwc_dump_display_contents(m_hwcList);
314-
// sfhwc_dump_hwc_device(hwc);
316+
// advance the framebuffers..
317+
m_frameBuffers.push_back(m_frameBuffers.front());
318+
m_frameBuffers.pop_front();
319+
320+
status = hwc->prepare(hwc, 1, &m_hwcList); assert(status == 0);
321+
status = hwc->set(hwc, 1, &m_hwcList); assert(status == 0);
322+
323+
sfhwc_dump_hwc_device(hwc);
324+
325+
if (fb->releaseFenceFd != -1) {
326+
setFenceBufferFd(buffer, fb->releaseFenceFd);
327+
fb->releaseFenceFd = -1;
328+
}
329+
330+
// cycle the framebuffer target
331+
m_frameBuffers.back()->setFence(fbt->releaseFenceFd);
332+
333+
if (m_hwcList->retireFenceFd != -1) {
334+
close(m_hwcList->retireFenceFd);
335+
m_hwcList->retireFenceFd = -1;
336+
}
337+
}
315338

316-
status = hwc->prepare(hwc, 1, &m_hwcList);
317-
assert(status == 0);
318-
// sfhwc_dump_display_contents(m_hwcList);
319-
// sfhwc_dump_hwc_device(hwc);
339+
inline void SfHwcSurface::presentAsFramebufferTarget(HWComposerNativeWindowBuffer *buffer)
340+
{
341+
logw << "buffer=" << (void *) buffer << std::endl;
320342

321-
// auto start = std::chrono::steady_clock::now();
343+
int status = 0; (void) status;
322344

323-
// logi << " --> calling set" << std::endl;
345+
hwc_composer_device_1_t *hwc = m_backend->hwcDevice;
324346

325-
status = hwc->set(hwc, 1, &m_hwcList);
347+
int fd = getFenceBufferFd(buffer);
348+
setFenceBufferFd(buffer, -1);
326349

327-
// logi << " <-- set completed" << std::endl;
350+
hwc_layer_1_t *fb = &m_hwcList->hwLayers[0];
351+
// Just pass a dummy handle that we have, we're not using these anyway..
352+
fb->handle = m_frameBuffers.front()->handle();
353+
fb->acquireFenceFd = -1;
354+
fb->releaseFenceFd = -1;
328355

329-
assert(status == 0);
330-
// sfhwc_dump_hwc_device(hwc);
356+
hwc_layer_1_t *fbt = &m_hwcList->hwLayers[1];
357+
fbt->handle = buffer->handle;
358+
fbt->acquireFenceFd = fd;
359+
fbt->releaseFenceFd = -1;
331360

332-
// auto end = std::chrono::steady_clock::now();
333-
// auto delta = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / 1000.0;
361+
status = hwc->prepare(hwc, 1, &m_hwcList); assert(status == 0);
362+
status = hwc->set(hwc, 1, &m_hwcList); assert(status == 0);
334363

335-
// logw << " - set completed in " << delta << std::endl;
364+
if (fbt->releaseFenceFd != -1) {
365+
setFenceBufferFd(buffer, fbt->releaseFenceFd);
366+
fbt->releaseFenceFd = -1;
367+
}
336368

369+
// Since we're taking the fb target code path, this buffer should be unused
370+
// so this should in theory never happen...
337371
if (fb->releaseFenceFd != -1) {
338-
#if 1
339-
setFenceBufferFd(buffer, fb->releaseFenceFd);
340-
fb->releaseFenceFd = -1;
341-
#else
342-
auto start = std::chrono::steady_clock::now();
343-
sync_wait(fb->releaseFenceFd, -1);
344372
close(fb->releaseFenceFd);
345373
fb->releaseFenceFd = -1;
346-
auto end = std::chrono::steady_clock::now();
347-
auto delta = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / 1000.0;
348-
logw << " - waited for fb release fd, " << delta << std::endl;
349-
#endif
350374
}
351375

352-
if (fbt->releaseFenceFd != -1) {
353-
close(fbt->releaseFenceFd);
354-
fbt->releaseFenceFd = -1;
355-
// logw << " - closed fbt release fd" << std::endl;
376+
if (m_hwcList->retireFenceFd != -1) {
377+
close(m_hwcList->retireFenceFd);
378+
m_hwcList->retireFenceFd = -1;
356379
}
357-
358-
if (m_hwcList->retireFenceFd != -1) {
359-
close(m_hwcList->retireFenceFd);
360-
m_hwcList->retireFenceFd = -1;
361-
// logw << " - closed retire fence fd.." << std::endl;
362-
}
363-
364-
// logd << " -> frame on screen" << std::endl;
365380
}
366381

367382
RENGINE_END_NAMESPACE

0 commit comments

Comments
 (0)