Skip to content
This repository has been archived by the owner on Sep 21, 2021. It is now read-only.

Commit

Permalink
implement display cleanup (closes #74)
Browse files Browse the repository at this point in the history
  • Loading branch information
misson20000 committed Feb 19, 2018
1 parent a28e4f0 commit a76073a
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 11 deletions.
11 changes: 9 additions & 2 deletions include/libtransistor/display/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,24 @@ result_t display_init();
/**
* @brief Open a display layer
*
* @param surface Description
* @param surface Surface structure to initialize
*/
result_t display_open_layer(surface_t *surface);

/**
* @brief Get a V-Sync event
*
* @param event Description
* @param event Output
*/
result_t display_get_vsync_event(revent_h *event);

/**
* @brief Close a display layer
*
* @param surface Surface to close
*/
void display_close_layer(surface_t *surface);

/**
* @brief Finalize Display
*/
Expand Down
23 changes: 23 additions & 0 deletions include/libtransistor/display/graphic_buffer_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ typedef enum {
RGB_888 = 0x3, ///< Only RGB channels, no alpha
} pixel_format_t;

/**
* @enum disconnect_mode_t
* @brief Disconnection mode
*
* https://source.android.com/reference/hidl/android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer#disconnectmode
*/
typedef enum {
API,
ALL_LOCAL
} disconnect_mode_t;

/**
* @struct compositor_timing_t
* @brief Description here...
Expand Down Expand Up @@ -171,6 +182,18 @@ result_t igbp_query(igbp_t *igbp, int what, int *status, int *value);
*/
result_t igbp_connect(igbp_t *igbp, int api, bool producer_controlled_by_app, int *status, queue_buffer_output_t *qbo);

/**
* @brief Disconnect from the IGraphicBufferProducer
*
* @param igbp IGBP to disconnect from
* @param api Description
* @param mode Disconnect mode
* @param status Status output
*
* https://source.android.com/reference/hidl/android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer#disconnect
*/
result_t igbp_disconnect(igbp_t *igbp, int api, disconnect_mode_t mode, int *status);

/**
* @brief Set a pre-allocated buffer on the IGraphicBufferProducer
*
Expand Down
3 changes: 2 additions & 1 deletion include/libtransistor/display/surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,5 @@ result_t surface_dequeue_buffer(surface_t *surface, uint32_t **image);
* @param surface Surface to submit buffer for
*/
result_t surface_queue_buffer(surface_t *surface);
// no surface_destroy() yet

void surface_destroy(surface_t *surface);
7 changes: 7 additions & 0 deletions include/libtransistor/gpu/gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ result_t gpu_initialize();
*/
result_t gpu_buffer_initialize(gpu_buffer_t *gpu_b, void *addr, size_t size, uint32_t heapmask, uint32_t flags, uint32_t alignment, uint8_t kind);

/**
* @brief Destroys a GPU buffer
*
* @param gpu_b GPU buffer to destroy
*/
result_t gpu_buffer_destroy(gpu_buffer_t *gpu_b, uint64_t *refcount, uint32_t *flags);

/**
* @brief Get a GPU buffer's ID
*
Expand Down
13 changes: 13 additions & 0 deletions include/libtransistor/gpu/nv_ioc.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define NVMAP_IOC_CREATE 0xC0080101
#define NVMAP_IOC_FROM_ID 0xC0080103
#define NVMAP_IOC_ALLOC 0xC0200104
#define NVMAP_IOC_FREE 0xC0180105
#define NVMAP_IOC_PARAM 0xC00C0109
#define NVMAP_IOC_GET_ID 0xC008010E

Expand Down Expand Up @@ -49,6 +50,18 @@ typedef struct {
uint64_t addr;
} nvmap_ioc_alloc_args;

/**
* @struct nvmap_ioc_free_args
* @brief Memory freeing args structure for the nvmap object.
*/
typedef struct {
uint32_t handle;
uint32_t pad;
uint64_t refcount; ///< out
uint32_t size; ///< out
uint32_t flags; ///< out (1=NOT_FREED_YET)
} nvmap_ioc_free_args;

/**
* @struct nvmap_ioc_param_args
* @brief Info query args structure for an nvmap object.
Expand Down
7 changes: 7 additions & 0 deletions include/libtransistor/ipc/vi.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ result_t vi_create_stray_layer(uint32_t unknown, display_t *display, uint64_t *l
*/
result_t vi_open_layer(const char *display_name, uint64_t layer_id, aruid_t aruid, igbp_t *igbp);

/**
* @brief Close a managed layer
*
* @param layer_id ID of existing managed layer
*/
result_t vi_close_layer(uint64_t layer_id);

/**
* @brief Create a managed layer
*
Expand Down
14 changes: 12 additions & 2 deletions lib/display/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,25 @@ result_t display_open_layer(surface_t *surface) {
return RESULT_OK;

fail_surface:
// TODO: destroy
surface_destroy(surface);
// surface takes ownership of IGBP and layer
return r;
fail_igbp:
// TODO: destroy
vi_adjust_refcount(igbp.igbp_binder.handle, -1, 1);
vi_close_layer(layer_id);
fail_managed_layer:
vi_destroy_managed_layer(layer_id);
fail:
return r;
}

void display_close_layer(surface_t *surface) {
surface_destroy(surface);
vi_adjust_refcount(surface->igbp.igbp_binder.handle, -1, 1);
vi_close_layer(surface->layer_id);
vi_destroy_managed_layer(surface->layer_id);
}

result_t display_get_vsync_event(revent_h *event) {
if(display.vsync == 0) {
result_t r;
Expand Down
25 changes: 25 additions & 0 deletions lib/display/graphic_buffer_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,31 @@ result_t igbp_connect(igbp_t *igbp, int api, bool producer_controlled_by_app, in
return RESULT_OK;
}

result_t igbp_disconnect(igbp_t *igbp, int api, disconnect_mode_t mode, int *status) {
result_t r;

parcel_t parcel;
parcel_initialize(&parcel);

parcel_write_interface_token(&parcel, INTERFACE_TOKEN);
parcel_write_u32(&parcel, api);
parcel_write_u32(&parcel, mode);

parcel_t response;
r = binder_transact_parcel(&(igbp->igbp_binder), DISCONNECT, 0, &parcel, &response);
if(r) {
return r;
}

if(parcel_read_remaining(&response) < sizeof(uint32_t)) {
return LIBTRANSISTOR_ERR_PARCEL_DATA_UNDERRUN;
}

*status = parcel_read_u32(&response);

return RESULT_OK;
}

result_t igbp_set_preallocated_buffer(igbp_t *igbp, int slot, graphic_buffer_t *gb) {
result_t r;

Expand Down
16 changes: 15 additions & 1 deletion lib/display/surface.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include<libtransistor/types.h>
#include<libtransistor/err.h>
#include<libtransistor/svc.h>
#include<libtransistor/ipc/vi.h>
#include<libtransistor/display/graphic_buffer_queue.h>
#include<libtransistor/display/surface.h>

Expand Down Expand Up @@ -83,12 +84,25 @@ result_t surface_create(surface_t *surface, uint64_t layer_id, igbp_t igbp) {
fail_memory:
//free(surface->gpu_buffer_memory_alloc);
fail_connect:
// TODO: disconnect?
igbp_disconnect(&surface->igbp, 2, ALL_LOCAL, &status);
fail:
surface->state = SURFACE_STATE_INVALID;
return r;
}

void surface_destroy(surface_t *surface) {
int status;
igbp_disconnect(&surface->igbp, 2, ALL_LOCAL, &status);
vi_adjust_refcount(surface->igbp.igbp_binder.handle, -1, 1);
vi_destroy_managed_layer(surface->layer_id);
surface->state = SURFACE_STATE_INVALID;

gpu_buffer_destroy(&surface->gpu_buffer, NULL, NULL);

svcSetMemoryAttribute(surface->gpu_buffer_memory, 0x780000, 0x0, 0x0);
// TODO: free memory
}

result_t surface_dequeue_buffer(surface_t *surface, uint32_t **image) {
result_t r;

Expand Down
17 changes: 17 additions & 0 deletions lib/gpu/gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ result_t gpu_buffer_initialize(gpu_buffer_t *gpu_b, void *addr, size_t size, uin
return RESULT_OK;
}

result_t gpu_buffer_destroy(gpu_buffer_t *gpu_b, uint64_t *refcount, uint32_t *flags) {
nvmap_ioc_free_args nvm_free;
nvm_free.handle = gpu_b->nvmap_handle;
if(nv_ioctl(nvmap_fd, NVMAP_IOC_FREE, &nvm_free, sizeof(nvm_free)) != 0) {
return nv_result;
}

if(refcount) {
*refcount = nvm_free.refcount;
}
if(flags) {
*flags = nvm_free.flags;
}

return RESULT_OK;
}

result_t gpu_buffer_get_id(gpu_buffer_t *gpu_b, uint32_t *id) {
nvmap_ioc_get_id_args nvm_get_id;
nvm_get_id.handle = gpu_b->nvmap_handle;
Expand Down
9 changes: 9 additions & 0 deletions lib/ipc/vi.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ result_t vi_open_layer(const char *display_name, uint64_t layer_id, uint64_t aru
return 0;
}

result_t vi_close_layer(uint64_t layer_id) {
ipc_request_t rq = ipc_default_request;
rq.request_id = 2021;
rq.raw_data_size = sizeof(layer_id);
rq.raw_data = &layer_id;

return ipc_send(iads_object, &rq, &ipc_default_response_fmt);
}

result_t vi_create_managed_layer(uint32_t unknown, display_t *display, uint64_t aruid, uint64_t *layer_id) {
struct {
uint32_t unknown;
Expand Down
14 changes: 9 additions & 5 deletions test/test_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ int main() {
ASSERT_OK(fail_display, display_open_layer(&surf));

revent_h vsync;
ASSERT_OK(fail_display, display_get_vsync_event(&vsync));
ASSERT_OK(fail_display_layer, display_get_vsync_event(&vsync));

uint32_t *reswitched_logo_pixels = reswitched_logo_data;
for(int i = 0; i < sizeof(reswitched_logo_data)/4; i++) {
Expand All @@ -37,7 +37,7 @@ int main() {
for(int i = 0; i < 600; i++) {
printf("begin frame %d\n", i);
uint32_t *out_buffer;
ASSERT_OK(fail_display, surface_dequeue_buffer(&surf, &out_buffer));
ASSERT_OK(fail_display_event, surface_dequeue_buffer(&surf, &out_buffer));

for(int p = 0; p < (0x3c0000/sizeof(uint32_t)); p++) {
out_buffer[p] = 0xFF0000FF;
Expand All @@ -46,17 +46,21 @@ int main() {
int y = (sin((double) i * 6.28 / 60.0) * 300.0 + 350.0);
gfx_slow_swizzling_blit(out_buffer, reswitched_logo_data, 64, 64, x, y);

ASSERT_OK(fail_display, surface_queue_buffer(&surf));
ASSERT_OK(fail_display_event, surface_queue_buffer(&surf));

uint32_t handle_idx;
r = svcWaitSynchronization(&handle_idx, &vsync, 1, 33333333);
if(r != RESULT_OK) {
printf("vsync timed out\n");
goto fail_display;
goto fail_display_event;
}
ASSERT_OK(fail_display, svcResetSignal(vsync));
ASSERT_OK(fail_display_event, svcResetSignal(vsync));
}

fail_display_event:
svcCloseHandle(vsync);
fail_display_layer:
display_close_layer(&surf);
fail_display:
display_finalize();
fail_vi:
Expand Down

0 comments on commit a76073a

Please sign in to comment.