Skip to content

Instantly share code, notes, and snippets.

@AndrewFromMelbourne
Last active August 29, 2015 14:03
Show Gist options
  • Save AndrewFromMelbourne/dd193fe0d7e6ac5c5343 to your computer and use it in GitHub Desktop.
Save AndrewFromMelbourne/dd193fe0d7e6ac5c5343 to your computer and use it in GitHub Desktop.
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "bcm_host.h"
void
takeSnapshot(
DISPMANX_DISPLAY_HANDLE_T display,
DISPMANX_MODEINFO_T *info,
VC_IMAGE_TYPE_T type,
int width,
int height,
int pitch,
void *buffer)
{
uint32_t vc_image_ptr;
DISPMANX_RESOURCE_HANDLE_T resource =
vc_dispmanx_resource_create(type,
width,
height,
&vc_image_ptr);
vc_dispmanx_snapshot(display, resource, DISPMANX_NO_ROTATE);
VC_RECT_T rect;
vc_dispmanx_rect_set(&rect, 0, 0, width, height);
vc_dispmanx_resource_read_data(resource, &rect, buffer, pitch);
int result = vc_dispmanx_resource_delete(resource);
assert(result == 0);
}
void
showSnapshot(
DISPMANX_DISPLAY_HANDLE_T display,
DISPMANX_MODEINFO_T *info,
VC_IMAGE_TYPE_T type,
int width,
int height,
int pitch,
void *buffer)
{
uint32_t vc_image_ptr;
DISPMANX_RESOURCE_HANDLE_T resource =
vc_dispmanx_resource_create(type, width, height, &vc_image_ptr);
assert(resource != 0);
VC_RECT_T dst_rect;
vc_dispmanx_rect_set(&dst_rect, 0, 0, width, height);
int result = vc_dispmanx_resource_write_data(resource,
type,
pitch,
buffer,
&dst_rect);
assert(result == 0);
DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0);
assert(update != 0);
VC_RECT_T src_rect;
vc_dispmanx_rect_set(&src_rect, 0, 0, width << 16, height << 16);
vc_dispmanx_rect_set(&dst_rect,
(info->width - width) / 2,
(info->height - height) / 2,
width,
height);
VC_DISPMANX_ALPHA_T alpha =
{
DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,
255, /*alpha 0->255*/
0
};
DISPMANX_ELEMENT_HANDLE_T element =
vc_dispmanx_element_add(update,
display,
3, // layer
&dst_rect,
resource,
&src_rect,
DISPMANX_PROTECTION_NONE,
&alpha,
NULL, // clamp
DISPMANX_NO_ROTATE);
assert(element != 0);
result = vc_dispmanx_update_submit_sync(update);
assert(result == 0);
sleep(10);
update = vc_dispmanx_update_start(0);
assert(update != 0);
result = vc_dispmanx_element_remove(update, element);
assert(result == 0);
result = vc_dispmanx_update_submit_sync(update);
assert(result == 0);
result = vc_dispmanx_resource_delete(resource);
assert(result == 0);
}
void
fullscreen(
bool useWidthAndHeight,
DISPMANX_DISPLAY_HANDLE_T display,
DISPMANX_MODEINFO_T *info)
{
VC_IMAGE_TYPE_T type = VC_IMAGE_RGBA32;
uint32_t vc_image_ptr;
DISPMANX_RESOURCE_HANDLE_T resource =
vc_dispmanx_resource_create(type, 2, 2, &vc_image_ptr);
assert(resource != 0);
uint32_t image[32];
memset(image, 0, sizeof(image));
image[0] = 0xFF0000FF;
image[1] = 0xFF00FFFF;
image[16] = 0xFFFF0000;
image[17] = 0xFFFFFF00;
VC_RECT_T dst_rect;
vc_dispmanx_rect_set(&dst_rect, 0, 0, 2, 2);
int result = vc_dispmanx_resource_write_data(resource,
type,
16 * sizeof(uint32_t),
image,
&dst_rect);
assert(result == 0);
DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0);
assert(update != 0);
VC_RECT_T src_rect;
vc_dispmanx_rect_set(&src_rect, 0, 0, 2 << 16, 2 << 16);
printf("filling screen with 2x2 pixels, ");
if (useWidthAndHeight)
{
printf("streched using width and height\n");
vc_dispmanx_rect_set(&dst_rect, 0, 0, info->width, info->height);
}
else
{
printf("streched using zeroed destination rectangle\n");
vc_dispmanx_rect_set(&dst_rect, 0, 0, 0, 0);
}
VC_DISPMANX_ALPHA_T alpha =
{
DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,
255, /*alpha 0->255*/
0
};
DISPMANX_ELEMENT_HANDLE_T element =
vc_dispmanx_element_add(update,
display,
2, // layer
&dst_rect,
resource,
&src_rect,
DISPMANX_PROTECTION_NONE,
&alpha,
NULL, // clamp
DISPMANX_NO_ROTATE);
assert(element != 0);
result = vc_dispmanx_update_submit_sync(update);
assert(result == 0);
sleep(2);
int width = info->width / 2;
int height = info->height / 2;
int pitch = ALIGN_UP(width * 4, 32);
void *buffer = calloc(1, pitch * height);
printf("taking snapshot %dx%d\n", width, height);
takeSnapshot(display, info, type, width, height, pitch, buffer);
update = vc_dispmanx_update_start(0);
assert(update != 0);
result = vc_dispmanx_element_remove(update, element);
assert(result == 0);
result = vc_dispmanx_update_submit_sync(update);
assert(result == 0);
result = vc_dispmanx_resource_delete(resource);
assert(result == 0);
printf("displaying snapshot %dx%d\n", width, height);
showSnapshot(display, info, type, width, height, pitch, buffer);
free(buffer);
}
int main(void)
{
bcm_host_init();
DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(0);
assert(display != 0);
DISPMANX_MODEINFO_T info;
int result = vc_dispmanx_display_get_info(display, &info);
assert(result == 0);
bool useWidthAndHeight = false;
fullscreen(useWidthAndHeight, display, &info);
useWidthAndHeight = true;
fullscreen(useWidthAndHeight, display, &info);
result = vc_dispmanx_display_close(display);
assert(result == 0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment