Loading minui/graphics_adf.cpp +44 −45 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <fcntl.h> #include <fcntl.h> #include <stdio.h> #include <stdio.h> #include <stdlib.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <sys/mman.h> #include <unistd.h> #include <unistd.h> Loading @@ -28,51 +29,60 @@ #include "minui/minui.h" #include "minui/minui.h" MinuiBackendAdf::MinuiBackendAdf() GRSurfaceAdf::~GRSurfaceAdf() { : intf_fd(-1), dev(), current_surface(0), n_surfaces(0), surfaces() {} if (mmapped_buffer_) { munmap(mmapped_buffer_, pitch * height); } if (fence_fd != -1) { close(fence_fd); } if (fd != -1) { close(fd); } } int MinuiBackendAdf::SurfaceInit(const drm_mode_modeinfo* mode, GRSurfaceAdf* surf) { std::unique_ptr<GRSurfaceAdf> GRSurfaceAdf::Create(int intf_fd, const drm_mode_modeinfo* mode, *surf = {}; __u32 format, int* err) { surf->fence_fd = -1; __u32 offset; surf->fd = adf_interface_simple_buffer_alloc(intf_fd, mode->hdisplay, mode->vdisplay, format, __u32 pitch; &surf->offset, &surf->pitch); auto fd = adf_interface_simple_buffer_alloc(intf_fd, mode->hdisplay, mode->vdisplay, format, if (surf->fd < 0) { &offset, &pitch); return surf->fd; if (fd < 0) { *err = fd; return nullptr; } } surf->width = mode->hdisplay; std::unique_ptr<GRSurfaceAdf> surf = std::unique_ptr<GRSurfaceAdf>( surf->height = mode->vdisplay; new GRSurfaceAdf(mode->hdisplay, mode->vdisplay, pitch, (format == DRM_FORMAT_RGB565 ? 2 : 4), surf->row_bytes = surf->pitch; offset, pitch, fd)); surf->pixel_bytes = (format == DRM_FORMAT_RGB565) ? 2 : 4; auto mmapped = auto mmapped = mmap(nullptr, surf->pitch * surf->height, PROT_WRITE, MAP_SHARED, surf->fd, surf->offset); mmap(nullptr, surf->pitch * surf->height, PROT_WRITE, MAP_SHARED, surf->fd, surf->offset); if (mmapped == MAP_FAILED) { if (mmapped == MAP_FAILED) { int saved_errno = errno; *err = -errno; close(surf->fd); return nullptr; return -saved_errno; } } surf->mmapped_buffer_ = static_cast<uint8_t*>(mmapped); surf->mmapped_buffer_ = static_cast<uint8_t*>(mmapped); return 0; return surf; } } MinuiBackendAdf::MinuiBackendAdf() : intf_fd(-1), dev(), current_surface(0), n_surfaces(0) {} int MinuiBackendAdf::InterfaceInit() { int MinuiBackendAdf::InterfaceInit() { adf_interface_data intf_data; adf_interface_data intf_data; int err = adf_get_interface_data(intf_fd, &intf_data); if (int err = adf_get_interface_data(intf_fd, &intf_data); err < 0) return err; if (err < 0) return err; int ret = 0; int result = 0; err = SurfaceInit(&intf_data.current_mode, &surfaces[0]); surfaces[0] = GRSurfaceAdf::Create(intf_fd, &intf_data.current_mode, format, &result); if (err < 0) { if (!surfaces[0]) { fprintf(stderr, "allocating surface 0 failed: %s\n", strerror(-err)); fprintf(stderr, "Failed to allocate surface 0: %s\n", strerror(-result)); ret = err; goto done; goto done; } } err = SurfaceInit(&intf_data.current_mode, &surfaces[1]); surfaces[1] = GRSurfaceAdf::Create(intf_fd, &intf_data.current_mode, format, &result); if (err < 0) { if (!surfaces[1]) { fprintf(stderr, "allocating surface 1 failed: %s\n", strerror(-err)); fprintf(stderr, "Failed to allocate surface 1: %s\n", strerror(-result)); surfaces[1] = {}; n_surfaces = 1; n_surfaces = 1; } else { } else { n_surfaces = 2; n_surfaces = 2; Loading @@ -80,7 +90,7 @@ int MinuiBackendAdf::InterfaceInit() { done: done: adf_free_interface_data(&intf_data); adf_free_interface_data(&intf_data); return ret; return result; } } int MinuiBackendAdf::DeviceInit(adf_device* dev) { int MinuiBackendAdf::DeviceInit(adf_device* dev) { Loading Loading @@ -153,12 +163,12 @@ GRSurface* MinuiBackendAdf::Init() { } } void MinuiBackendAdf::Sync(GRSurfaceAdf* surf) { void MinuiBackendAdf::Sync(GRSurfaceAdf* surf) { static constexpr unsigned int warningTimeout = 3000; static constexpr unsigned int kWarningTimeout = 3000; if (surf == nullptr) return; if (surf == nullptr) return; if (surf->fence_fd >= 0) { if (surf->fence_fd >= 0) { int err = sync_wait(surf->fence_fd, warningTimeout); int err = sync_wait(surf->fence_fd, kWarningTimeout); if (err < 0) { if (err < 0) { perror("adf sync fence wait error\n"); perror("adf sync fence wait error\n"); } } Loading @@ -169,33 +179,22 @@ void MinuiBackendAdf::Sync(GRSurfaceAdf* surf) { } } GRSurface* MinuiBackendAdf::Flip() { GRSurface* MinuiBackendAdf::Flip() { GRSurfaceAdf* surf = &surfaces[current_surface]; const auto& surf = surfaces[current_surface]; int fence_fd = adf_interface_simple_post(intf_fd, eng_id, surf->width, surf->height, format, int fence_fd = adf_interface_simple_post(intf_fd, eng_id, surf->width, surf->height, format, surf->fd, surf->offset, surf->pitch, -1); surf->fd, surf->offset, surf->pitch, -1); if (fence_fd >= 0) surf->fence_fd = fence_fd; if (fence_fd >= 0) surf->fence_fd = fence_fd; current_surface = (current_surface + 1) % n_surfaces; current_surface = (current_surface + 1) % n_surfaces; Sync(&surfaces[current_surface]); Sync(surfaces[current_surface].get()); return &surfaces[current_surface]; return surfaces[current_surface].get(); } } void MinuiBackendAdf::Blank(bool blank) { void MinuiBackendAdf::Blank(bool blank) { adf_interface_blank(intf_fd, blank ? DRM_MODE_DPMS_OFF : DRM_MODE_DPMS_ON); adf_interface_blank(intf_fd, blank ? DRM_MODE_DPMS_OFF : DRM_MODE_DPMS_ON); } } void MinuiBackendAdf::SurfaceDestroy(GRSurfaceAdf* surf) { if (surf->mmapped_buffer_) { munmap(surf->mmapped_buffer_, surf->pitch * surf->height); } close(surf->fence_fd); close(surf->fd); } MinuiBackendAdf::~MinuiBackendAdf() { MinuiBackendAdf::~MinuiBackendAdf() { adf_device_close(&dev); adf_device_close(&dev); for (unsigned int i = 0; i < n_surfaces; i++) { SurfaceDestroy(&surfaces[i]); } if (intf_fd >= 0) close(intf_fd); if (intf_fd >= 0) close(intf_fd); } } minui/graphics_adf.h +21 −11 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,9 @@ #pragma once #pragma once #include <stdint.h> #include <stdint.h> #include <sys/types.h> #include <memory> #include <adf/adf.h> #include <adf/adf.h> Loading @@ -25,6 +28,11 @@ class GRSurfaceAdf : public GRSurface { class GRSurfaceAdf : public GRSurface { public: public: ~GRSurfaceAdf() override; static std::unique_ptr<GRSurfaceAdf> Create(int intf_fd, const drm_mode_modeinfo* mode, __u32 format, int* err); uint8_t* data() override { uint8_t* data() override { return mmapped_buffer_; return mmapped_buffer_; } } Loading @@ -32,34 +40,36 @@ class GRSurfaceAdf : public GRSurface { private: private: friend class MinuiBackendAdf; friend class MinuiBackendAdf; int fence_fd; GRSurfaceAdf(int width, int height, int row_bytes, int pixel_bytes, __u32 offset, __u32 pitch, int fd; int fd) __u32 offset; : GRSurface(width, height, row_bytes, pixel_bytes), offset(offset), pitch(pitch), fd(fd) {} __u32 pitch; const __u32 offset; const __u32 pitch; int fd; int fence_fd{ -1 }; uint8_t* mmapped_buffer_{ nullptr }; uint8_t* mmapped_buffer_{ nullptr }; }; }; class MinuiBackendAdf : public MinuiBackend { class MinuiBackendAdf : public MinuiBackend { public: public: MinuiBackendAdf(); ~MinuiBackendAdf() override; GRSurface* Init() override; GRSurface* Init() override; GRSurface* Flip() override; GRSurface* Flip() override; void Blank(bool) override; void Blank(bool) override; ~MinuiBackendAdf() override; MinuiBackendAdf(); private: private: int SurfaceInit(const drm_mode_modeinfo* mode, GRSurfaceAdf* surf); int InterfaceInit(); int InterfaceInit(); int DeviceInit(adf_device* dev); int DeviceInit(adf_device* dev); void SurfaceDestroy(GRSurfaceAdf* surf); void Sync(GRSurfaceAdf* surf); void Sync(GRSurfaceAdf* surf); int intf_fd; int intf_fd; adf_id_t eng_id; adf_id_t eng_id; __u32 format; __u32 format; adf_device dev; adf_device dev; unsigned int current_surface; size_t current_surface; unsigned int n_surfaces; size_t n_surfaces; GRSurfaceAdf surfaces[2]; std::unique_ptr<GRSurfaceAdf> surfaces[2]; }; }; minui/graphics_drm.cpp +3 −7 Original line number Original line Diff line number Diff line Loading @@ -102,15 +102,15 @@ std::unique_ptr<GRSurfaceDrm> GRSurfaceDrm::Create(int drm_fd, int width, int he return nullptr; return nullptr; } } std::unique_ptr<GRSurfaceDrm> surface = std::make_unique<GRSurfaceDrm>(drm_fd); // Cannot use std::make_unique to access non-public ctor. surface->handle = create_dumb.handle; auto surface = std::unique_ptr<GRSurfaceDrm>(new GRSurfaceDrm( width, height, create_dumb.pitch, create_dumb.bpp / 8, drm_fd, create_dumb.handle)); uint32_t handles[4], pitches[4], offsets[4]; uint32_t handles[4], pitches[4], offsets[4]; handles[0] = surface->handle; handles[0] = surface->handle; pitches[0] = create_dumb.pitch; pitches[0] = create_dumb.pitch; offsets[0] = 0; offsets[0] = 0; if (drmModeAddFB2(drm_fd, width, height, format, handles, pitches, offsets, &surface->fb_id, 0) != if (drmModeAddFB2(drm_fd, width, height, format, handles, pitches, offsets, &surface->fb_id, 0) != 0) { 0) { perror("Failed to drmModeAddFB2"); perror("Failed to drmModeAddFB2"); Loading @@ -124,10 +124,6 @@ std::unique_ptr<GRSurfaceDrm> GRSurfaceDrm::Create(int drm_fd, int width, int he return nullptr; return nullptr; } } surface->height = height; surface->width = width; surface->row_bytes = create_dumb.pitch; surface->pixel_bytes = create_dumb.bpp / 8; auto mmapped = mmap(nullptr, surface->height * surface->row_bytes, PROT_READ | PROT_WRITE, auto mmapped = mmap(nullptr, surface->height * surface->row_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, drm_fd, map_dumb.offset); MAP_SHARED, drm_fd, map_dumb.offset); if (mmapped == MAP_FAILED) { if (mmapped == MAP_FAILED) { Loading minui/graphics_drm.h +3 −4 Original line number Original line Diff line number Diff line Loading @@ -20,7 +20,6 @@ #include <memory> #include <memory> #include <android-base/macros.h> #include <xf86drmMode.h> #include <xf86drmMode.h> #include "graphics.h" #include "graphics.h" Loading @@ -28,7 +27,6 @@ class GRSurfaceDrm : public GRSurface { class GRSurfaceDrm : public GRSurface { public: public: explicit GRSurfaceDrm(int drm_fd) : drm_fd_(drm_fd) {} ~GRSurfaceDrm() override; ~GRSurfaceDrm() override; // Creates a GRSurfaceDrm instance. // Creates a GRSurfaceDrm instance. Loading @@ -41,13 +39,14 @@ class GRSurfaceDrm : public GRSurface { private: private: friend class MinuiBackendDrm; friend class MinuiBackendDrm; GRSurfaceDrm(int width, int height, int row_bytes, int pixel_bytes, int drm_fd, uint32_t handle) : GRSurface(width, height, row_bytes, pixel_bytes), drm_fd_(drm_fd), handle(handle) {} const int drm_fd_; const int drm_fd_; uint32_t fb_id{ 0 }; uint32_t fb_id{ 0 }; uint32_t handle{ 0 }; uint32_t handle{ 0 }; uint8_t* mmapped_buffer_{ nullptr }; uint8_t* mmapped_buffer_{ nullptr }; DISALLOW_COPY_AND_ASSIGN(GRSurfaceDrm); }; }; class MinuiBackendDrm : public MinuiBackend { class MinuiBackendDrm : public MinuiBackend { Loading minui/graphics_fbdev.cpp +32 −36 Original line number Original line Diff line number Diff line Loading @@ -26,21 +26,27 @@ #include <sys/types.h> #include <sys/types.h> #include <unistd.h> #include <unistd.h> #include <memory> #include "minui/minui.h" #include "minui/minui.h" MinuiBackendFbdev::MinuiBackendFbdev() : gr_draw(nullptr), fb_fd(-1) {} std::unique_ptr<GRSurfaceFbdev> GRSurfaceFbdev::Create(int width, int height, int row_bytes, int pixel_bytes) { // Cannot use std::make_unique to access non-public ctor. return std::unique_ptr<GRSurfaceFbdev>(new GRSurfaceFbdev(width, height, row_bytes, pixel_bytes)); } void MinuiBackendFbdev::Blank(bool blank) { void MinuiBackendFbdev::Blank(bool blank) { int ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK); int ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK); if (ret < 0) perror("ioctl(): blank"); if (ret < 0) perror("ioctl(): blank"); } } void MinuiBackendFbdev::SetDisplayedFramebuffer(unsigned n) { void MinuiBackendFbdev::SetDisplayedFramebuffer(size_t n) { if (n > 1 || !double_buffered) return; if (n > 1 || !double_buffered) return; vi.yres_virtual = gr_framebuffer[0].height * 2; vi.yres_virtual = gr_framebuffer[0]->height * 2; vi.yoffset = n * gr_framebuffer[0].height; vi.yoffset = n * gr_framebuffer[0]->height; vi.bits_per_pixel = gr_framebuffer[0].pixel_bytes * 8; vi.bits_per_pixel = gr_framebuffer[0]->pixel_bytes * 8; if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) { if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) { perror("active fb swap failed"); perror("active fb swap failed"); } } Loading Loading @@ -96,35 +102,31 @@ GRSurface* MinuiBackendFbdev::Init() { memset(bits, 0, fi.smem_len); memset(bits, 0, fi.smem_len); gr_framebuffer[0].width = vi.xres; gr_framebuffer[0] = gr_framebuffer[0].height = vi.yres; GRSurfaceFbdev::Create(vi.xres, vi.yres, fi.line_length, vi.bits_per_pixel / 8); gr_framebuffer[0].row_bytes = fi.line_length; gr_framebuffer[0]->buffer_ = static_cast<uint8_t*>(bits); gr_framebuffer[0].pixel_bytes = vi.bits_per_pixel / 8; memset(gr_framebuffer[0]->buffer_, 0, gr_framebuffer[0]->height * gr_framebuffer[0]->row_bytes); gr_framebuffer[0].buffer_ = static_cast<uint8_t*>(bits); memset(gr_framebuffer[0].buffer_, 0, gr_framebuffer[0].height * gr_framebuffer[0].row_bytes); gr_framebuffer[1] = GRSurfaceFbdev::Create(gr_framebuffer[0]->width, gr_framebuffer[0]->height, gr_framebuffer[0]->row_bytes, gr_framebuffer[0]->pixel_bytes); /* check if we can use double buffering */ /* check if we can use double buffering */ if (vi.yres * fi.line_length * 2 <= fi.smem_len) { if (vi.yres * fi.line_length * 2 <= fi.smem_len) { double_buffered = true; double_buffered = true; gr_framebuffer[1] = gr_framebuffer[0]; gr_framebuffer[1]->buffer_ = gr_framebuffer[1].buffer_ = gr_framebuffer[0]->buffer_ + gr_framebuffer[0]->height * gr_framebuffer[0]->row_bytes; gr_framebuffer[0].buffer_ + gr_framebuffer[0].height * gr_framebuffer[0].row_bytes; gr_draw = gr_framebuffer + 1; } else { } else { double_buffered = false; double_buffered = false; // Without double-buffering, we allocate RAM for a buffer to // Without double-buffering, we allocate RAM for a buffer to draw in, and then "flipping" the // draw in, and then "flipping" the buffer consists of a // buffer consists of a memcpy from the buffer we allocated to the framebuffer. // memcpy from the buffer we allocated to the framebuffer. memory_buffer.resize(gr_framebuffer[1]->height * gr_framebuffer[1]->row_bytes); gr_framebuffer[1]->buffer_ = memory_buffer.data(); gr_draw = new GRSurfaceFbdev; *gr_draw = gr_framebuffer[0]; gr_draw->buffer_ = new uint8_t[gr_draw->height * gr_draw->row_bytes]; } } gr_draw = gr_framebuffer[1].get(); memset(gr_draw->buffer_, 0, gr_draw->height * gr_draw->row_bytes); memset(gr_draw->buffer_, 0, gr_draw->height * gr_draw->row_bytes); fb_fd = fd; fb_fd = fd; SetDisplayedFramebuffer(0); SetDisplayedFramebuffer(0); Loading @@ -139,25 +141,19 @@ GRSurface* MinuiBackendFbdev::Init() { GRSurface* MinuiBackendFbdev::Flip() { GRSurface* MinuiBackendFbdev::Flip() { if (double_buffered) { if (double_buffered) { // Change gr_draw to point to the buffer currently displayed, // Change gr_draw to point to the buffer currently displayed, then flip the driver so we're // then flip the driver so we're displaying the other buffer // displaying the other buffer instead. // instead. gr_draw = gr_framebuffer[displayed_buffer].get(); gr_draw = gr_framebuffer + displayed_buffer; SetDisplayedFramebuffer(1 - displayed_buffer); SetDisplayedFramebuffer(1 - displayed_buffer); } else { } else { // Copy from the in-memory surface to the framebuffer. // Copy from the in-memory surface to the framebuffer. memcpy(gr_framebuffer[0].buffer_, gr_draw->buffer_, gr_draw->height * gr_draw->row_bytes); memcpy(gr_framebuffer[0]->buffer_, gr_draw->buffer_, gr_draw->height * gr_draw->row_bytes); } } return gr_draw; return gr_draw; } } MinuiBackendFbdev::~MinuiBackendFbdev() { MinuiBackendFbdev::~MinuiBackendFbdev() { if (fb_fd != -1) { close(fb_fd); close(fb_fd); fb_fd = -1; if (!double_buffered && gr_draw) { delete[] gr_draw->buffer_; delete gr_draw; } } gr_draw = nullptr; } } Loading
minui/graphics_adf.cpp +44 −45 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <fcntl.h> #include <fcntl.h> #include <stdio.h> #include <stdio.h> #include <stdlib.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <sys/mman.h> #include <unistd.h> #include <unistd.h> Loading @@ -28,51 +29,60 @@ #include "minui/minui.h" #include "minui/minui.h" MinuiBackendAdf::MinuiBackendAdf() GRSurfaceAdf::~GRSurfaceAdf() { : intf_fd(-1), dev(), current_surface(0), n_surfaces(0), surfaces() {} if (mmapped_buffer_) { munmap(mmapped_buffer_, pitch * height); } if (fence_fd != -1) { close(fence_fd); } if (fd != -1) { close(fd); } } int MinuiBackendAdf::SurfaceInit(const drm_mode_modeinfo* mode, GRSurfaceAdf* surf) { std::unique_ptr<GRSurfaceAdf> GRSurfaceAdf::Create(int intf_fd, const drm_mode_modeinfo* mode, *surf = {}; __u32 format, int* err) { surf->fence_fd = -1; __u32 offset; surf->fd = adf_interface_simple_buffer_alloc(intf_fd, mode->hdisplay, mode->vdisplay, format, __u32 pitch; &surf->offset, &surf->pitch); auto fd = adf_interface_simple_buffer_alloc(intf_fd, mode->hdisplay, mode->vdisplay, format, if (surf->fd < 0) { &offset, &pitch); return surf->fd; if (fd < 0) { *err = fd; return nullptr; } } surf->width = mode->hdisplay; std::unique_ptr<GRSurfaceAdf> surf = std::unique_ptr<GRSurfaceAdf>( surf->height = mode->vdisplay; new GRSurfaceAdf(mode->hdisplay, mode->vdisplay, pitch, (format == DRM_FORMAT_RGB565 ? 2 : 4), surf->row_bytes = surf->pitch; offset, pitch, fd)); surf->pixel_bytes = (format == DRM_FORMAT_RGB565) ? 2 : 4; auto mmapped = auto mmapped = mmap(nullptr, surf->pitch * surf->height, PROT_WRITE, MAP_SHARED, surf->fd, surf->offset); mmap(nullptr, surf->pitch * surf->height, PROT_WRITE, MAP_SHARED, surf->fd, surf->offset); if (mmapped == MAP_FAILED) { if (mmapped == MAP_FAILED) { int saved_errno = errno; *err = -errno; close(surf->fd); return nullptr; return -saved_errno; } } surf->mmapped_buffer_ = static_cast<uint8_t*>(mmapped); surf->mmapped_buffer_ = static_cast<uint8_t*>(mmapped); return 0; return surf; } } MinuiBackendAdf::MinuiBackendAdf() : intf_fd(-1), dev(), current_surface(0), n_surfaces(0) {} int MinuiBackendAdf::InterfaceInit() { int MinuiBackendAdf::InterfaceInit() { adf_interface_data intf_data; adf_interface_data intf_data; int err = adf_get_interface_data(intf_fd, &intf_data); if (int err = adf_get_interface_data(intf_fd, &intf_data); err < 0) return err; if (err < 0) return err; int ret = 0; int result = 0; err = SurfaceInit(&intf_data.current_mode, &surfaces[0]); surfaces[0] = GRSurfaceAdf::Create(intf_fd, &intf_data.current_mode, format, &result); if (err < 0) { if (!surfaces[0]) { fprintf(stderr, "allocating surface 0 failed: %s\n", strerror(-err)); fprintf(stderr, "Failed to allocate surface 0: %s\n", strerror(-result)); ret = err; goto done; goto done; } } err = SurfaceInit(&intf_data.current_mode, &surfaces[1]); surfaces[1] = GRSurfaceAdf::Create(intf_fd, &intf_data.current_mode, format, &result); if (err < 0) { if (!surfaces[1]) { fprintf(stderr, "allocating surface 1 failed: %s\n", strerror(-err)); fprintf(stderr, "Failed to allocate surface 1: %s\n", strerror(-result)); surfaces[1] = {}; n_surfaces = 1; n_surfaces = 1; } else { } else { n_surfaces = 2; n_surfaces = 2; Loading @@ -80,7 +90,7 @@ int MinuiBackendAdf::InterfaceInit() { done: done: adf_free_interface_data(&intf_data); adf_free_interface_data(&intf_data); return ret; return result; } } int MinuiBackendAdf::DeviceInit(adf_device* dev) { int MinuiBackendAdf::DeviceInit(adf_device* dev) { Loading Loading @@ -153,12 +163,12 @@ GRSurface* MinuiBackendAdf::Init() { } } void MinuiBackendAdf::Sync(GRSurfaceAdf* surf) { void MinuiBackendAdf::Sync(GRSurfaceAdf* surf) { static constexpr unsigned int warningTimeout = 3000; static constexpr unsigned int kWarningTimeout = 3000; if (surf == nullptr) return; if (surf == nullptr) return; if (surf->fence_fd >= 0) { if (surf->fence_fd >= 0) { int err = sync_wait(surf->fence_fd, warningTimeout); int err = sync_wait(surf->fence_fd, kWarningTimeout); if (err < 0) { if (err < 0) { perror("adf sync fence wait error\n"); perror("adf sync fence wait error\n"); } } Loading @@ -169,33 +179,22 @@ void MinuiBackendAdf::Sync(GRSurfaceAdf* surf) { } } GRSurface* MinuiBackendAdf::Flip() { GRSurface* MinuiBackendAdf::Flip() { GRSurfaceAdf* surf = &surfaces[current_surface]; const auto& surf = surfaces[current_surface]; int fence_fd = adf_interface_simple_post(intf_fd, eng_id, surf->width, surf->height, format, int fence_fd = adf_interface_simple_post(intf_fd, eng_id, surf->width, surf->height, format, surf->fd, surf->offset, surf->pitch, -1); surf->fd, surf->offset, surf->pitch, -1); if (fence_fd >= 0) surf->fence_fd = fence_fd; if (fence_fd >= 0) surf->fence_fd = fence_fd; current_surface = (current_surface + 1) % n_surfaces; current_surface = (current_surface + 1) % n_surfaces; Sync(&surfaces[current_surface]); Sync(surfaces[current_surface].get()); return &surfaces[current_surface]; return surfaces[current_surface].get(); } } void MinuiBackendAdf::Blank(bool blank) { void MinuiBackendAdf::Blank(bool blank) { adf_interface_blank(intf_fd, blank ? DRM_MODE_DPMS_OFF : DRM_MODE_DPMS_ON); adf_interface_blank(intf_fd, blank ? DRM_MODE_DPMS_OFF : DRM_MODE_DPMS_ON); } } void MinuiBackendAdf::SurfaceDestroy(GRSurfaceAdf* surf) { if (surf->mmapped_buffer_) { munmap(surf->mmapped_buffer_, surf->pitch * surf->height); } close(surf->fence_fd); close(surf->fd); } MinuiBackendAdf::~MinuiBackendAdf() { MinuiBackendAdf::~MinuiBackendAdf() { adf_device_close(&dev); adf_device_close(&dev); for (unsigned int i = 0; i < n_surfaces; i++) { SurfaceDestroy(&surfaces[i]); } if (intf_fd >= 0) close(intf_fd); if (intf_fd >= 0) close(intf_fd); } }
minui/graphics_adf.h +21 −11 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,9 @@ #pragma once #pragma once #include <stdint.h> #include <stdint.h> #include <sys/types.h> #include <memory> #include <adf/adf.h> #include <adf/adf.h> Loading @@ -25,6 +28,11 @@ class GRSurfaceAdf : public GRSurface { class GRSurfaceAdf : public GRSurface { public: public: ~GRSurfaceAdf() override; static std::unique_ptr<GRSurfaceAdf> Create(int intf_fd, const drm_mode_modeinfo* mode, __u32 format, int* err); uint8_t* data() override { uint8_t* data() override { return mmapped_buffer_; return mmapped_buffer_; } } Loading @@ -32,34 +40,36 @@ class GRSurfaceAdf : public GRSurface { private: private: friend class MinuiBackendAdf; friend class MinuiBackendAdf; int fence_fd; GRSurfaceAdf(int width, int height, int row_bytes, int pixel_bytes, __u32 offset, __u32 pitch, int fd; int fd) __u32 offset; : GRSurface(width, height, row_bytes, pixel_bytes), offset(offset), pitch(pitch), fd(fd) {} __u32 pitch; const __u32 offset; const __u32 pitch; int fd; int fence_fd{ -1 }; uint8_t* mmapped_buffer_{ nullptr }; uint8_t* mmapped_buffer_{ nullptr }; }; }; class MinuiBackendAdf : public MinuiBackend { class MinuiBackendAdf : public MinuiBackend { public: public: MinuiBackendAdf(); ~MinuiBackendAdf() override; GRSurface* Init() override; GRSurface* Init() override; GRSurface* Flip() override; GRSurface* Flip() override; void Blank(bool) override; void Blank(bool) override; ~MinuiBackendAdf() override; MinuiBackendAdf(); private: private: int SurfaceInit(const drm_mode_modeinfo* mode, GRSurfaceAdf* surf); int InterfaceInit(); int InterfaceInit(); int DeviceInit(adf_device* dev); int DeviceInit(adf_device* dev); void SurfaceDestroy(GRSurfaceAdf* surf); void Sync(GRSurfaceAdf* surf); void Sync(GRSurfaceAdf* surf); int intf_fd; int intf_fd; adf_id_t eng_id; adf_id_t eng_id; __u32 format; __u32 format; adf_device dev; adf_device dev; unsigned int current_surface; size_t current_surface; unsigned int n_surfaces; size_t n_surfaces; GRSurfaceAdf surfaces[2]; std::unique_ptr<GRSurfaceAdf> surfaces[2]; }; };
minui/graphics_drm.cpp +3 −7 Original line number Original line Diff line number Diff line Loading @@ -102,15 +102,15 @@ std::unique_ptr<GRSurfaceDrm> GRSurfaceDrm::Create(int drm_fd, int width, int he return nullptr; return nullptr; } } std::unique_ptr<GRSurfaceDrm> surface = std::make_unique<GRSurfaceDrm>(drm_fd); // Cannot use std::make_unique to access non-public ctor. surface->handle = create_dumb.handle; auto surface = std::unique_ptr<GRSurfaceDrm>(new GRSurfaceDrm( width, height, create_dumb.pitch, create_dumb.bpp / 8, drm_fd, create_dumb.handle)); uint32_t handles[4], pitches[4], offsets[4]; uint32_t handles[4], pitches[4], offsets[4]; handles[0] = surface->handle; handles[0] = surface->handle; pitches[0] = create_dumb.pitch; pitches[0] = create_dumb.pitch; offsets[0] = 0; offsets[0] = 0; if (drmModeAddFB2(drm_fd, width, height, format, handles, pitches, offsets, &surface->fb_id, 0) != if (drmModeAddFB2(drm_fd, width, height, format, handles, pitches, offsets, &surface->fb_id, 0) != 0) { 0) { perror("Failed to drmModeAddFB2"); perror("Failed to drmModeAddFB2"); Loading @@ -124,10 +124,6 @@ std::unique_ptr<GRSurfaceDrm> GRSurfaceDrm::Create(int drm_fd, int width, int he return nullptr; return nullptr; } } surface->height = height; surface->width = width; surface->row_bytes = create_dumb.pitch; surface->pixel_bytes = create_dumb.bpp / 8; auto mmapped = mmap(nullptr, surface->height * surface->row_bytes, PROT_READ | PROT_WRITE, auto mmapped = mmap(nullptr, surface->height * surface->row_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, drm_fd, map_dumb.offset); MAP_SHARED, drm_fd, map_dumb.offset); if (mmapped == MAP_FAILED) { if (mmapped == MAP_FAILED) { Loading
minui/graphics_drm.h +3 −4 Original line number Original line Diff line number Diff line Loading @@ -20,7 +20,6 @@ #include <memory> #include <memory> #include <android-base/macros.h> #include <xf86drmMode.h> #include <xf86drmMode.h> #include "graphics.h" #include "graphics.h" Loading @@ -28,7 +27,6 @@ class GRSurfaceDrm : public GRSurface { class GRSurfaceDrm : public GRSurface { public: public: explicit GRSurfaceDrm(int drm_fd) : drm_fd_(drm_fd) {} ~GRSurfaceDrm() override; ~GRSurfaceDrm() override; // Creates a GRSurfaceDrm instance. // Creates a GRSurfaceDrm instance. Loading @@ -41,13 +39,14 @@ class GRSurfaceDrm : public GRSurface { private: private: friend class MinuiBackendDrm; friend class MinuiBackendDrm; GRSurfaceDrm(int width, int height, int row_bytes, int pixel_bytes, int drm_fd, uint32_t handle) : GRSurface(width, height, row_bytes, pixel_bytes), drm_fd_(drm_fd), handle(handle) {} const int drm_fd_; const int drm_fd_; uint32_t fb_id{ 0 }; uint32_t fb_id{ 0 }; uint32_t handle{ 0 }; uint32_t handle{ 0 }; uint8_t* mmapped_buffer_{ nullptr }; uint8_t* mmapped_buffer_{ nullptr }; DISALLOW_COPY_AND_ASSIGN(GRSurfaceDrm); }; }; class MinuiBackendDrm : public MinuiBackend { class MinuiBackendDrm : public MinuiBackend { Loading
minui/graphics_fbdev.cpp +32 −36 Original line number Original line Diff line number Diff line Loading @@ -26,21 +26,27 @@ #include <sys/types.h> #include <sys/types.h> #include <unistd.h> #include <unistd.h> #include <memory> #include "minui/minui.h" #include "minui/minui.h" MinuiBackendFbdev::MinuiBackendFbdev() : gr_draw(nullptr), fb_fd(-1) {} std::unique_ptr<GRSurfaceFbdev> GRSurfaceFbdev::Create(int width, int height, int row_bytes, int pixel_bytes) { // Cannot use std::make_unique to access non-public ctor. return std::unique_ptr<GRSurfaceFbdev>(new GRSurfaceFbdev(width, height, row_bytes, pixel_bytes)); } void MinuiBackendFbdev::Blank(bool blank) { void MinuiBackendFbdev::Blank(bool blank) { int ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK); int ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK); if (ret < 0) perror("ioctl(): blank"); if (ret < 0) perror("ioctl(): blank"); } } void MinuiBackendFbdev::SetDisplayedFramebuffer(unsigned n) { void MinuiBackendFbdev::SetDisplayedFramebuffer(size_t n) { if (n > 1 || !double_buffered) return; if (n > 1 || !double_buffered) return; vi.yres_virtual = gr_framebuffer[0].height * 2; vi.yres_virtual = gr_framebuffer[0]->height * 2; vi.yoffset = n * gr_framebuffer[0].height; vi.yoffset = n * gr_framebuffer[0]->height; vi.bits_per_pixel = gr_framebuffer[0].pixel_bytes * 8; vi.bits_per_pixel = gr_framebuffer[0]->pixel_bytes * 8; if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) { if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) { perror("active fb swap failed"); perror("active fb swap failed"); } } Loading Loading @@ -96,35 +102,31 @@ GRSurface* MinuiBackendFbdev::Init() { memset(bits, 0, fi.smem_len); memset(bits, 0, fi.smem_len); gr_framebuffer[0].width = vi.xres; gr_framebuffer[0] = gr_framebuffer[0].height = vi.yres; GRSurfaceFbdev::Create(vi.xres, vi.yres, fi.line_length, vi.bits_per_pixel / 8); gr_framebuffer[0].row_bytes = fi.line_length; gr_framebuffer[0]->buffer_ = static_cast<uint8_t*>(bits); gr_framebuffer[0].pixel_bytes = vi.bits_per_pixel / 8; memset(gr_framebuffer[0]->buffer_, 0, gr_framebuffer[0]->height * gr_framebuffer[0]->row_bytes); gr_framebuffer[0].buffer_ = static_cast<uint8_t*>(bits); memset(gr_framebuffer[0].buffer_, 0, gr_framebuffer[0].height * gr_framebuffer[0].row_bytes); gr_framebuffer[1] = GRSurfaceFbdev::Create(gr_framebuffer[0]->width, gr_framebuffer[0]->height, gr_framebuffer[0]->row_bytes, gr_framebuffer[0]->pixel_bytes); /* check if we can use double buffering */ /* check if we can use double buffering */ if (vi.yres * fi.line_length * 2 <= fi.smem_len) { if (vi.yres * fi.line_length * 2 <= fi.smem_len) { double_buffered = true; double_buffered = true; gr_framebuffer[1] = gr_framebuffer[0]; gr_framebuffer[1]->buffer_ = gr_framebuffer[1].buffer_ = gr_framebuffer[0]->buffer_ + gr_framebuffer[0]->height * gr_framebuffer[0]->row_bytes; gr_framebuffer[0].buffer_ + gr_framebuffer[0].height * gr_framebuffer[0].row_bytes; gr_draw = gr_framebuffer + 1; } else { } else { double_buffered = false; double_buffered = false; // Without double-buffering, we allocate RAM for a buffer to // Without double-buffering, we allocate RAM for a buffer to draw in, and then "flipping" the // draw in, and then "flipping" the buffer consists of a // buffer consists of a memcpy from the buffer we allocated to the framebuffer. // memcpy from the buffer we allocated to the framebuffer. memory_buffer.resize(gr_framebuffer[1]->height * gr_framebuffer[1]->row_bytes); gr_framebuffer[1]->buffer_ = memory_buffer.data(); gr_draw = new GRSurfaceFbdev; *gr_draw = gr_framebuffer[0]; gr_draw->buffer_ = new uint8_t[gr_draw->height * gr_draw->row_bytes]; } } gr_draw = gr_framebuffer[1].get(); memset(gr_draw->buffer_, 0, gr_draw->height * gr_draw->row_bytes); memset(gr_draw->buffer_, 0, gr_draw->height * gr_draw->row_bytes); fb_fd = fd; fb_fd = fd; SetDisplayedFramebuffer(0); SetDisplayedFramebuffer(0); Loading @@ -139,25 +141,19 @@ GRSurface* MinuiBackendFbdev::Init() { GRSurface* MinuiBackendFbdev::Flip() { GRSurface* MinuiBackendFbdev::Flip() { if (double_buffered) { if (double_buffered) { // Change gr_draw to point to the buffer currently displayed, // Change gr_draw to point to the buffer currently displayed, then flip the driver so we're // then flip the driver so we're displaying the other buffer // displaying the other buffer instead. // instead. gr_draw = gr_framebuffer[displayed_buffer].get(); gr_draw = gr_framebuffer + displayed_buffer; SetDisplayedFramebuffer(1 - displayed_buffer); SetDisplayedFramebuffer(1 - displayed_buffer); } else { } else { // Copy from the in-memory surface to the framebuffer. // Copy from the in-memory surface to the framebuffer. memcpy(gr_framebuffer[0].buffer_, gr_draw->buffer_, gr_draw->height * gr_draw->row_bytes); memcpy(gr_framebuffer[0]->buffer_, gr_draw->buffer_, gr_draw->height * gr_draw->row_bytes); } } return gr_draw; return gr_draw; } } MinuiBackendFbdev::~MinuiBackendFbdev() { MinuiBackendFbdev::~MinuiBackendFbdev() { if (fb_fd != -1) { close(fb_fd); close(fb_fd); fb_fd = -1; if (!double_buffered && gr_draw) { delete[] gr_draw->buffer_; delete gr_draw; } } gr_draw = nullptr; } }