void vo_display_frame (RECT_VARS_T* vars, int width, int height, int chroma_width, int chroma_height, uint8_t * const * buf, int num) { int ret; static VC_RECT_T src_rect; static VC_RECT_T dst_rect; static VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, /*alpha 0->255*/ 0 }; int pitch = VO_ALIGN_UP(width,32); assert((height % 16) == 0); assert((chroma_height % 16) == 0); if (num == 0) { vars->resource = vc_dispmanx_resource_create( VC_IMAGE_YUV420, width, height, &vars->vc_image_ptr ); assert( vars->resource ); vars->update = vc_dispmanx_update_start( 10 ); assert( vars->update ); vc_dispmanx_rect_set( &src_rect, 0, 0, width << 16, height << 16 ); vc_dispmanx_rect_set( &dst_rect, 0, 0, vars->info.width, vars->info.height); vars->element = vc_dispmanx_element_add( vars->update, vars->display, 2000, // layer &dst_rect, vars->resource, &src_rect, DISPMANX_PROTECTION_NONE, &alpha, NULL, // clamp VC_IMAGE_ROT0 ); ret = vc_dispmanx_update_submit( vars->update, NULL, NULL); vc_dispmanx_rect_set( &dst_rect, 0, 0, width, (3*height)/2); } ret = vc_dispmanx_resource_write_data( vars->resource, VC_IMAGE_YUV420, pitch, buf[0], &dst_rect ); assert( ret == 0 ); vars->update = vc_dispmanx_update_start( 10 ); assert( vars->update ); //ret = vc_dispmanx_update_submit_sync( vars->update ); ret = vc_dispmanx_update_submit( vars->update, NULL, NULL); assert( ret == 0 ); }
static void display_subpicture(vout_display_t *vd, subpicture_t *subpicture) { vout_display_sys_t *sys = vd->sys; struct dmx_region_t **dmx_region = &sys->dmx_region; struct dmx_region_t *unused_dmx_region; DISPMANX_UPDATE_HANDLE_T update = 0; picture_t *picture; video_format_t *fmt; struct dmx_region_t *dmx_region_next; if(subpicture) { subpicture_region_t *region = subpicture->p_region; while(region) { picture = region->p_picture; fmt = ®ion->fmt; if(!*dmx_region) { if(!update) update = vc_dispmanx_update_start(10); *dmx_region = dmx_region_new(vd, update, region); } else if(((*dmx_region)->bmp_rect.width != (int32_t)fmt->i_visible_width) || ((*dmx_region)->bmp_rect.height != (int32_t)fmt->i_visible_height) || ((*dmx_region)->pos_x != region->i_x) || ((*dmx_region)->pos_y != region->i_y) || ((*dmx_region)->alpha.opacity != (uint32_t)region->i_alpha)) { dmx_region_next = (*dmx_region)->next; if(!update) update = vc_dispmanx_update_start(10); dmx_region_delete(*dmx_region, update); *dmx_region = dmx_region_new(vd, update, region); (*dmx_region)->next = dmx_region_next; } else if((*dmx_region)->picture != picture) { if(!update) update = vc_dispmanx_update_start(10); dmx_region_update(*dmx_region, update, picture); } dmx_region = &(*dmx_region)->next; region = region->p_next; } } /* Remove remaining regions */ unused_dmx_region = *dmx_region; while(unused_dmx_region) { dmx_region_next = unused_dmx_region->next; if(!update) update = vc_dispmanx_update_start(10); dmx_region_delete(unused_dmx_region, update); unused_dmx_region = dmx_region_next; } *dmx_region = NULL; if(update) vc_dispmanx_update_submit_sync(update); }
static void show_cursor(ALLEGRO_DISPLAY_RASPBERRYPI *d) { if (d->cursor_data == NULL || cursor_added) { return; } int width = d->cursor_width; int height = d->cursor_height; uint32_t unused; cursor_resource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888, width, height, &unused); VC_RECT_T r; r.x = 0; r.y = 0; r.width = width; r.height = height; int dpitch = pot(sizeof(uint32_t) * width); dispman_update = vc_dispmanx_update_start(0); vc_dispmanx_resource_write_data(cursor_resource, VC_IMAGE_ARGB8888, dpitch, d->cursor_data, &r); vc_dispmanx_update_submit_sync(dispman_update); ALLEGRO_MOUSE_STATE state; al_get_mouse_state(&state); dst_rect.x = state.x+d->cursor_offset_x; dst_rect.y = state.y+d->cursor_offset_y; dst_rect.width = width; dst_rect.height = height; src_rect.x = 0; src_rect.y = 0; src_rect.width = width << 16; src_rect.height = height << 16; dispman_update = vc_dispmanx_update_start(0); cursor_element = vc_dispmanx_element_add( dispman_update, dispman_display, 0/*layer*/, &dst_rect, cursor_resource, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/ ); vc_dispmanx_update_submit_sync(dispman_update); cursor_added = true; }
void dispmanxtest() { DISPMANX_DISPLAY_HANDLE_T display; int ret; DISPMANX_MODEINFO_T displayinfo; DISPMANX_RESOURCE_HANDLE_T res; int width = 1024; int height = 576; uint32_t vc_image_ptr; DISPMANX_UPDATE_HANDLE_T update; VC_RECT_T dst_rect,src_rect; DISPMANX_ELEMENT_HANDLE_T element; bcm_host_init(); display = vc_dispmanx_display_open(0); ret = vc_dispmanx_display_get_info( display, &displayinfo); assert(ret==0); printf("display is %dx%d\n",displayinfo.width,displayinfo.height); res = vc_dispmanx_resource_create(VC_IMAGE_YUV420,width,height,&vc_image_ptr); vc_image_ptr = vc_dispmanx_resource_get_image_handle(res); printf("vc_image_ptr %x\n",vc_image_ptr); assert(res); update = vc_dispmanx_update_start(10); assert(update); vc_dispmanx_rect_set(&src_rect,0,0,width<<16,height<<16); vc_dispmanx_rect_set(&dst_rect,0,(displayinfo.height - height)/2,width-32,height); element = vc_dispmanx_element_add(update,display,2000,&dst_rect,res,&src_rect,DISPMANX_PROTECTION_NONE,NULL,NULL,DISPMANX_NO_ROTATE); ret = vc_dispmanx_update_submit_sync(update); assert(ret==0); uint8_t *rawfb = (uint8_t*)mapmem(vc_image_ptr,0x1000); for (int i=0; i<0x100; i++) { printf("%02x ",rawfb[i]); } printf("\n"); unmapmem(rawfb,0x1000); puts("sleeping"); sleep(10); update = vc_dispmanx_update_start(10); assert(update); ret = vc_dispmanx_element_remove(update,element); assert(ret==0); ret = vc_dispmanx_update_submit_sync(update); assert(ret==0); ret = vc_dispmanx_resource_delete(res); assert(ret==0); ret = vc_dispmanx_display_close(display); assert(ret==0); }
static void dispmanx_flip(struct dispmanx_page *page, void *data) { struct dispmanx_video *_dispvars = data; if (!_dispvars) return; /* Dispmanx doesn't support issuing more than one pageflip. * If we do, the second CB isn't called. */ if (_dispvars->pageflip_pending > 0) { slock_lock(_dispvars->vsync_cond_mutex); scond_wait(_dispvars->vsync_condition, _dispvars->vsync_cond_mutex); slock_unlock(_dispvars->vsync_cond_mutex); } /* Issue a page flip at the next vblank interval * (will be done at vsync anyway). */ _dispvars->update = vc_dispmanx_update_start(0); vc_dispmanx_element_change_source(_dispvars->update, _dispvars->element, _dispvars->resources[page->numpage]); vc_dispmanx_update_submit(_dispvars->update, vsync_callback, (void*)page); slock_lock(_dispvars->pending_mutex); _dispvars->pageflip_pending++; slock_unlock(_dispvars->pending_mutex); }
bool destroyBackgroundLayer( BACKGROUND_LAYER_T *bg) { int result = 0; bool res = true; if(bg->element) { DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); if(update) { result = vc_dispmanx_element_remove(update, bg->element); if(result != DISPMANX_SUCCESS) res = false; result = vc_dispmanx_update_submit_sync(update); if(result != DISPMANX_SUCCESS) res = false; }else{ res = false; } } result = vc_dispmanx_resource_delete(bg->resource); if(result != DISPMANX_SUCCESS) res = false; return res; }
void vsync(DISPMANX_UPDATE_HANDLE_T u, void* arg) { int ret; DISPMANX_UPDATE_HANDLE_T update; update = vc_dispmanx_update_start( 10 ); assert( update ); ret = vc_dispmanx_element_change_source( update, element, resource[next_resource]); assert( ret == 0 ); ret = vc_dispmanx_update_submit_sync( update ); assert( ret == 0 ); if(next_resource != 2) { int real_next_resource = next_resource ^ 1; next_resource = 2; // use filler if next callback called before this one ends // fill image int n; for (n=0; n<HEIGHT; n+=2) { get_packet(ROW(n)+24); // +24 because clock never changes memcpy(ROW(n+1)+24, ROW(n)+24, 336); // double it up because the hardware scaler // will introduce blurring between lines } // write to resource ret = vc_dispmanx_resource_write_data( resource[real_next_resource], TYPE, PITCH, image, &image_rect ); assert( ret == 0 ); next_resource = real_next_resource; // queue up next real resource } }
static void fbDispmanSetNativeCursor(jlong nativeCursorHandle) { DISPMANX_UPDATE_HANDLE_T update; DispmanCursorImage *cursorImage = (DispmanCursorImage *)jlong_to_ptr(nativeCursorHandle); if (cursorImage != NULL && cursor.element != 0) { if (cursorImage->width != cursor.cursorWidth || cursorImage->height != cursor.cursorHeight) { fbDispmanRemoveDispmanxElement(); cursor.cursorWidth = cursorImage->width; cursor.cursorHeight = cursorImage->height; fbDispmanAddDispmanxElement(); } cursor.currentCursor = nativeCursorHandle; if (cursor.isVisible) { update = vc_dispmanx_update_start(0); vc_dispmanx_element_change_source(update, cursor.element, cursorImage->resource); vc_dispmanx_update_submit_sync(update); } } }
void ViewBackend::commitBuffer(uint32_t handle, uint32_t width, uint32_t height) { if (handle != elementHandle || width != this->width || height != this->height) return; DISPMANX_UPDATE_HANDLE_T updateHandle = vc_dispmanx_update_start(0); VC_RECT_T srcRect, destRect; vc_dispmanx_rect_set(&srcRect, 0, 0, width << 16, height << 16); vc_dispmanx_rect_set(&destRect, 0, 0, width, height); vc_dispmanx_element_change_attributes(updateHandle, elementHandle, 1 << 3 | 1 << 2, 0, 0, &destRect, &srcRect, 0, DISPMANX_NO_ROTATE); vc_dispmanx_update_submit(updateHandle, [](DISPMANX_UPDATE_HANDLE_T, void* data) { auto& backend = *static_cast<ViewBackend*>(data); struct timeval tv; gettimeofday(&tv, nullptr); uint64_t time = tv.tv_sec * 1000 + tv.tv_usec / 1000; ssize_t ret = write(backend.updateFd, &time, sizeof(time)); if (ret != sizeof(time)) fprintf(stderr, "ViewBackend: failed to write to the update eventfd\n"); }, this); }
static void exit_func(void) // Function to be passed to atexit(). { DISPMANX_UPDATE_HANDLE_T dispman_update; int s; // clear screen glClear( GL_COLOR_BUFFER_BIT ); eglSwapBuffers(state->display, state->surface); glDeleteTextures(6, state->tex); eglDestroySurface( state->display, state->surface ); dispman_update = vc_dispmanx_update_start( 0 ); s = vc_dispmanx_element_remove(dispman_update, state->dispman_element); assert(s == 0); vc_dispmanx_update_submit_sync( dispman_update ); s = vc_dispmanx_display_close(state->dispman_display); assert (s == 0); // Release OpenGL resources eglMakeCurrent( state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); eglDestroyContext( state->display, state->context ); eglTerminate( state->display ); #ifndef __circle__ // release texture buffers free(state->tex_buf1); free(state->tex_buf2); free(state->tex_buf3); #endif printk("\ncube closed\n"); } // exit_func()
static EGLNativeWindowType createDispmanxLayer(const QPoint &pos, const QSize &size, int z, DISPMANX_FLAGS_ALPHA_T flags) { VC_RECT_T dst_rect; dst_rect.x = pos.x(); dst_rect.y = pos.y(); dst_rect.width = size.width(); dst_rect.height = size.height(); VC_RECT_T src_rect; src_rect.x = 0; src_rect.y = 0; src_rect.width = size.width() << 16; src_rect.height = size.height() << 16; DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start(0); VC_DISPMANX_ALPHA_T alpha; alpha.flags = flags; alpha.opacity = 0xFF; alpha.mask = 0; DISPMANX_ELEMENT_HANDLE_T dispman_element = vc_dispmanx_element_add( dispman_update, dispman_display, z, &dst_rect, 0, &src_rect, DISPMANX_PROTECTION_NONE, &alpha, (DISPMANX_CLAMP_T *)NULL, (DISPMANX_TRANSFORM_T)0); vc_dispmanx_update_submit_sync(dispman_update); EGL_DISPMANX_WINDOW_T *eglWindow = new EGL_DISPMANX_WINDOW_T; eglWindow->element = dispman_element; eglWindow->width = size.width(); eglWindow->height = size.height(); return eglWindow; }
static void dispmanx_surface_update(void *data, const void *frame, struct dispmanx_surface *surface) { struct dispmanx_video *_dispvars = data; struct dispmanx_page *page = NULL; /* Wait until last issued flip completes to get a free page. Also, dispmanx doesn't support issuing more than one pageflip.*/ slock_lock(_dispvars->pending_mutex); if (_dispvars->pageflip_pending > 0) { scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex); } slock_unlock(_dispvars->pending_mutex); page = dispmanx_get_free_page(_dispvars, surface); /* Frame blitting */ vc_dispmanx_resource_write_data(page->resource, surface->pixformat, surface->pitch, (void*)frame, &(surface->bmp_rect)); /* Issue a page flip that will be done at the next vsync. */ _dispvars->update = vc_dispmanx_update_start(0); vc_dispmanx_element_change_source(_dispvars->update, surface->element, page->resource); vc_dispmanx_update_submit(_dispvars->update, dispmanx_vsync_callback, (void*)page); slock_lock(_dispvars->pending_mutex); _dispvars->pageflip_pending++; slock_unlock(_dispvars->pending_mutex); }
int SliceMngr::blankScreen(){ DISPMANX_UPDATE_HANDLE_T update; update = vc_dispmanx_update_start(0); vc_dispmanx_element_change_layer(update, mBackground.element, 1); vc_dispmanx_element_change_layer(update, mImage.element, 0); return vc_dispmanx_update_submit_sync(update); }
/* Warp the mouse to (x,y) */ static void RPI_WarpMouseGlobal(int x, int y) { RPI_CursorData *curdata; DISPMANX_UPDATE_HANDLE_T update; int ret; VC_RECT_T dst_rect; SDL_Mouse *mouse = SDL_GetMouse(); if (mouse != NULL && mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) { curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata; if (curdata->element != DISPMANX_NO_HANDLE) { update = vc_dispmanx_update_start( 10 ); SDL_assert( update ); vc_dispmanx_rect_set( &dst_rect, x, y, curdata->w, curdata->h); ret = vc_dispmanx_element_change_attributes( update, curdata->element, ELEMENT_CHANGE_DEST_RECT, 0, 0, &dst_rect, NULL, DISPMANX_NO_HANDLE, DISPMANX_NO_ROTATE); SDL_assert( ret == DISPMANX_SUCCESS ); /* Submit asynchronously, otherwise the peformance suffers a lot */ ret = vc_dispmanx_update_submit( update, 0, NULL ); SDL_assert( ret == DISPMANX_SUCCESS ); } } }
static void DISPMANX_BlankBackground(void) { //MAC: Funcion que simplemente pone un element nuevo cuyo resource es de un solo pixel de color negro, //se escala a pantalla completa y listo. // we create a 1x1 black pixel image that is added to display just behind video VC_IMAGE_TYPE_T type = VC_IMAGE_RGB565; uint32_t vc_image_ptr; uint16_t image = 0x0000; // black VC_RECT_T dst_rect, src_rect; dispvars->b_resource = vc_dispmanx_resource_create( type, 1 /*width*/, 1 /*height*/, &vc_image_ptr ); vc_dispmanx_rect_set( &dst_rect, 0, 0, 1, 1); vc_dispmanx_resource_write_data( dispvars->b_resource, type, sizeof(image), &image, &dst_rect ); vc_dispmanx_rect_set( &src_rect, 0, 0, 1<<16, 1<<16); vc_dispmanx_rect_set( &dst_rect, 0, 0, 0, 0); dispvars->b_update = vc_dispmanx_update_start(0); dispvars->b_element = vc_dispmanx_element_add(dispvars->b_update, dispvars->display, -1 /*layer*/, &dst_rect, dispvars->b_resource, &src_rect, DISPMANX_PROTECTION_NONE, NULL, NULL, (DISPMANX_TRANSFORM_T)0 ); vc_dispmanx_update_submit_sync( dispvars->b_update ); }
/* Free a window manager cursor */ static void RPI_FreeCursor(SDL_Cursor * cursor) { int ret; DISPMANX_UPDATE_HANDLE_T update; RPI_CursorData *curdata; if (cursor != NULL) { curdata = (RPI_CursorData *) cursor->driverdata; if (curdata != NULL) { if (curdata->element != DISPMANX_NO_HANDLE) { update = vc_dispmanx_update_start( 10 ); SDL_assert( update ); ret = vc_dispmanx_element_remove( update, curdata->element ); SDL_assert( ret == DISPMANX_SUCCESS ); ret = vc_dispmanx_update_submit_sync( update ); SDL_assert( ret == DISPMANX_SUCCESS ); } if (curdata->resource != DISPMANX_NO_HANDLE) { ret = vc_dispmanx_resource_delete( curdata->resource ); SDL_assert( ret == DISPMANX_SUCCESS ); } SDL_free(cursor->driverdata); } SDL_free(cursor); } }
static void DISPMANX_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) { //En OpenGL también va así. No deberíamos esperar para cambiar el buffer, de hecho la aplicación //piensa que no hay doble buffer (hasta hemos desactivado el double buffer), sino que en lugar //de esperar, simplemente deberíamos actualizar la superficie visible directamente... Pero no //puedo hacer eso porque no tengo acceso a la superficie visible: tengo la superficie de vídeo en RAM //y cada vez que se hace un cambio (o sea, cada vez que llego aquí) copio esa superficie a la VRAM //y espero a cambiar los buffers para no tener tearing, a pesar de que esta función se supone que no //hace eso. Pero en OpenGL se hace lo mismo ya que la única manera de mostrar los cambios es hacer //un GL_SWAP_BUFFERS que también es bloqueante. //Volcamos desde el ram bitmap buffer al dispmanx resource buffer que toque. cada vez a uno. vc_dispmanx_resource_write_data( dispvars->resources[flip_page], dispvars->pix_format, dispvars->pitch, dispvars->pixmem, &(dispvars->bmp_rect) ); //Empieza actualización dispvars->update = vc_dispmanx_update_start( 0 ); vc_dispmanx_element_change_source(dispvars->update, dispvars->element, dispvars->resources[flip_page]); vc_dispmanx_update_submit_sync( dispvars->update ); //vc_dispmanx_update_submit(dispvars->update, NULL, NULL); //Acaba actualización flip_page = !flip_page; return; }
static void frontend_init(void) { uint32_t display_width=0, display_height=0; VC_RECT_T dst_rect; VC_RECT_T src_rect; bcm_host_init(); //initialise dispmanx display and resources fe_screen=(unsigned short *) calloc(1, 640*480*2); graphics_get_display_size(0 /* LCD */, &display_width, &display_height); fe_display = vc_dispmanx_display_open( 0 ); //Create two surfaces for flipping between //Make sure bitmap type matches the source for better performance uint32_t crap; fe_resource = vc_dispmanx_resource_create(VC_IMAGE_RGB565, 640, 480, &crap); vc_dispmanx_rect_set( &dst_rect, 0, 0, display_width, display_height); vc_dispmanx_rect_set( &src_rect, 0, 0, 640 << 16, 480 << 16); //Make sure mame and background overlay the menu program fe_update = vc_dispmanx_update_start( 0 ); // create the 'window' element - based on the first buffer resource (resource0) fe_element = vc_dispmanx_element_add( fe_update, fe_display, 1, &dst_rect, fe_resource, &src_rect, DISPMANX_PROTECTION_NONE, 0, 0, (DISPMANX_TRANSFORM_T) 0 ); vc_dispmanx_update_submit_sync( fe_update ); }
void gp2x_deinit(void) { int ret; gles2_destroy(); // Release OpenGL resources eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); eglDestroySurface( display, surface ); eglDestroyContext( display, context ); eglTerminate( display ); dispman_update = vc_dispmanx_update_start( 0 ); ret = vc_dispmanx_element_remove( dispman_update, dispman_element ); ret = vc_dispmanx_element_remove( dispman_update, dispman_element_bg ); ret = vc_dispmanx_update_submit_sync( dispman_update ); ret = vc_dispmanx_resource_delete( resource0 ); ret = vc_dispmanx_resource_delete( resource1 ); ret = vc_dispmanx_resource_delete( resource_bg ); ret = vc_dispmanx_display_close( dispman_display ); if(gp2x_screen8) free(gp2x_screen8); if(gp2x_screen15) free(gp2x_screen15); gp2x_screen8=0; gp2x_screen15=0; }
static void dispmanx_surface_setup(void *data, int width, int height, int pitch, float aspect, struct dispmanx_surface *surface) { struct dispmanx_video *_dispvars = data; int i, dst_width, dst_height, dst_xpos, dst_ypos; /* Allocate memory for all the pages in each surface * and initialize variables inside each page's struct. */ surface->pages = calloc(surface->numpages, sizeof(struct dispmanx_page)); for (i = 0; i < surface->numpages; i++) { surface->pages[i].used = false; surface->pages[i].dispvars = _dispvars; surface->pages[i].page_used_mutex = slock_new(); } /* Internal frame dimensions. Pitch is total pitch including info * between scanlines */ surface->width = width; surface->height = height; surface->pitch = pitch; surface->aspect = aspect; /* The "visible" width obtained from the core pitch. We blit based on * the "visible" width, for cores with things between scanlines. */ int visible_width = pitch / surface->bpp; dst_width = _dispvars->dispmanx_height * aspect; dst_height = _dispvars->dispmanx_height; /* If we obtain a scaled image width that is bigger than the physical screen width, * then we keep the physical screen width as our maximun width. */ if (dst_width > _dispvars->dispmanx_width) dst_width = _dispvars->dispmanx_width; dst_xpos = (_dispvars->dispmanx_width - dst_width) / 2; dst_ypos = (_dispvars->dispmanx_height - dst_height) / 2; /* We configure the rects now. */ vc_dispmanx_rect_set(&surface->dst_rect, dst_xpos, dst_ypos, dst_width, dst_height); vc_dispmanx_rect_set(&surface->bmp_rect, 0, 0, width, height); vc_dispmanx_rect_set(&surface->src_rect, 0, 0, width << 16, height << 16); for (i = 0; i < surface->numpages; i++) { surface->pages[i].resource = vc_dispmanx_resource_create(surface->pixformat, visible_width, height, &(_dispvars->vc_image_ptr)); } /* Add element. */ _dispvars->update = vc_dispmanx_update_start(0); surface->element = vc_dispmanx_element_add( _dispvars->update,_dispvars->display, surface->layer, &surface->dst_rect, surface->pages[0].resource, &surface->src_rect, DISPMANX_PROTECTION_NONE, &surface->alpha, 0, (DISPMANX_TRANSFORM_T)0); vc_dispmanx_update_submit_sync(_dispvars->update); surface->setup = true; }
ViewBackend::Cursor::Cursor(WPE::LibinputServer::Client& targetClient, DISPMANX_DISPLAY_HANDLE_T displayHandle, uint32_t displayWidth, uint32_t displayHeight) : targetClient(targetClient) , position({ 0, 0 }) , displaySize({ displayWidth, displayHeight }) { static VC_DISPMANX_ALPHA_T alpha = { static_cast<DISPMANX_FLAGS_ALPHA_T>(DISPMANX_FLAGS_ALPHA_FROM_SOURCE), 255, 0 }; DISPMANX_UPDATE_HANDLE_T updateHandle = vc_dispmanx_update_start(0); uint32_t imagePtr; VC_RECT_T rect; vc_dispmanx_rect_set(&rect, 0, 0, CursorData::width, CursorData::height); DISPMANX_RESOURCE_HANDLE_T pointerResource = vc_dispmanx_resource_create(VC_IMAGE_RGBA32, CursorData::width, CursorData::height, &imagePtr); vc_dispmanx_resource_write_data(pointerResource, VC_IMAGE_RGBA32, CursorData::width * 4, CursorData::data, &rect); VC_RECT_T srcRect, destRect; vc_dispmanx_rect_set(&srcRect, 0, 0, CursorData::width << 16, CursorData::height << 16); vc_dispmanx_rect_set(&destRect, position.first, position.second, cursorWidth, cursorHeight); cursorHandle = vc_dispmanx_element_add(updateHandle, displayHandle, 10, &destRect, pointerResource, &srcRect, DISPMANX_PROTECTION_NONE, &alpha, nullptr, DISPMANX_NO_ROTATE); vc_dispmanx_resource_delete(pointerResource); vc_dispmanx_update_submit_sync(updateHandle); }
static int DISPMANX_FlipHWSurface(_THIS, SDL_Surface *surface) { /*if ( switched_away ) { return -2; // no hardware access }*/ //Volcamos desde el ram bitmap buffer al dispmanx resource buffer //que toque. cada vez a uno. vc_dispmanx_resource_write_data( dispvars->resources[flip_page], dispvars->pix_format, dispvars->pitch, dispvars->pixmem, &(dispvars->bmp_rect) ); //**Empieza actualización*** dispvars->update = vc_dispmanx_update_start( 0 ); vc_dispmanx_element_change_source(dispvars->update, dispvars->element, dispvars->resources[flip_page]); vc_dispmanx_update_submit_sync( dispvars->update ); //vc_dispmanx_update_submit(dispvars->update, NULL, NULL); //**Acaba actualización*** flip_page = !flip_page; //MAC Esto no hace falta porque SDL siempre escribe en dispvars->pixmem, //que es el buffer en RAM y que copiamos cada vez a un resource. //surface->pixels = flip_address[flip_page]; return (0); }
uint32_t ViewBackendBCMRPi::createBCMElement(int32_t width, int32_t height) { static VC_DISPMANX_ALPHA_T alpha = { static_cast<DISPMANX_FLAGS_ALPHA_T>(DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 255, 0 }; if (m_elementHandle != DISPMANX_NO_HANDLE) return 0; m_width = std::max(width, 0); m_height = std::max(height, 0); DISPMANX_UPDATE_HANDLE_T updateHandle = vc_dispmanx_update_start(0); VC_RECT_T srcRect, destRect; vc_dispmanx_rect_set(&srcRect, 0, 0, m_width << 16, m_height << 16); vc_dispmanx_rect_set(&destRect, 0, 0, m_width, m_height); m_elementHandle = vc_dispmanx_element_add(updateHandle, m_displayHandle, 0, &destRect, DISPMANX_NO_HANDLE, &srcRect, DISPMANX_PROTECTION_NONE, &alpha, nullptr, DISPMANX_NO_ROTATE); vc_dispmanx_update_submit_sync(updateHandle); return m_elementHandle; }
qboolean RPI_Init (rendererstate_t *info, unsigned char *palette) { static EGL_DISPMANX_WINDOW_T nativewindow; DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; VC_RECT_T dst_rect; VC_RECT_T src_rect; int rw, rh; if (!EGL_LoadLibrary(info->subrenderer)) { Con_Printf("couldn't load EGL library\n"); return false; } bcm_host_init(); graphics_get_display_size(0 /* LCD */, &rw, &rh); Con_Printf("Screen size is actually %i*%i\n", rw, rh); if (info->width < 64 || info->height < 64) { info->width = rw; info->height = rh; } dispman_display = vc_dispmanx_display_open(0 /* LCD */); dispman_update = vc_dispmanx_update_start(0); dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = info->width; dst_rect.height = info->height; src_rect.x = 0; src_rect.y = 0; src_rect.width = info->width << 16; src_rect.height = info->height << 16; vid.pixelwidth = info->width; vid.pixelheight = info->height; dispman_element = vc_dispmanx_element_add(dispman_update, dispman_display, 0/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/); nativewindow.element = dispman_element; nativewindow.width = info->width; nativewindow.height = info->height; vc_dispmanx_update_submit_sync(dispman_update); if (!EGL_Init(info, palette, &nativewindow, EGL_DEFAULT_DISPLAY)) { Con_Printf("couldn't initialise EGL context\n"); return false; } GL_Init(&EGL_Proc); return true; }
static void DISPMANX_FreeBackground (void) { dispvars->b_update = vc_dispmanx_update_start( 0 ); vc_dispmanx_resource_delete( dispvars->b_resource ); vc_dispmanx_element_remove ( dispvars->b_update, dispvars->b_element); vc_dispmanx_update_submit_sync( dispvars->b_update ); }
static void destroyDispmanxLayer(EGLNativeWindowType window) { EGL_DISPMANX_WINDOW_T *eglWindow = static_cast<EGL_DISPMANX_WINDOW_T *>(window); DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start(0); vc_dispmanx_element_remove(dispman_update, eglWindow->element); vc_dispmanx_update_submit_sync(dispman_update); delete eglWindow; }
/// // WinCreate() - RaspberryPi, direct surface (No X, Xlib) // // This function initialized the display and window for EGL // EGLBoolean WinCreate(ESContext *esContext, const char *title) { int32_t success = 0; static EGL_DISPMANX_WINDOW_T nativewindow; DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; VC_RECT_T dst_rect; VC_RECT_T src_rect; int display_width; int display_height; // create an EGL window surface, passing context width/height success = graphics_get_display_size(0 /* LCD */, &display_width, &display_height); if ( success < 0 ) { return EGL_FALSE; } // You can hardcode the resolution here: // <JJW> : But I don't want to hardcode resolution! // display_width = 640; // display_height = 480; dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = display_width; dst_rect.height = display_height; src_rect.x = 0; src_rect.y = 0; src_rect.width = display_width << 16; src_rect.height = display_height << 16; dispman_display = vc_dispmanx_display_open( 0 /* LCD */); dispman_update = vc_dispmanx_update_start( 0 ); dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display, 0/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/); nativewindow.element = dispman_element; nativewindow.width = display_width; nativewindow.height = display_height; vc_dispmanx_update_submit_sync( dispman_update ); //JJW : save window resolution of LCD moniter in esContext esContext->width = display_width; esContext->height = display_height; esContext->hWnd = &nativewindow; return EGL_TRUE; }
EGLNativeWindowType platform_create_native_window (gint width, gint height, gpointer * window_data) { DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; RPIWindowData *data; VC_RECT_T dst_rect; VC_RECT_T src_rect; GstVideoRectangle src, dst, res; uint32_t dp_height; uint32_t dp_width; int ret; ret = graphics_get_display_size (0, &dp_width, &dp_height); if (ret < 0) { GST_ERROR ("Can't open display"); return (EGLNativeWindowType) 0; } GST_DEBUG ("Got display size: %dx%d\n", dp_width, dp_height); GST_DEBUG ("Source size: %dx%d\n", width, height); /* Center width*height frame inside dp_width*dp_height */ src.w = width; src.h = height; src.x = src.y = 0; dst.w = dp_width; dst.h = dp_height; dst.x = dst.y = 0; gst_video_sink_center_rect (src, dst, &res, TRUE); dst_rect.x = res.x; dst_rect.y = res.y; dst_rect.width = res.w; dst_rect.height = res.h; src_rect.x = 0; src_rect.y = 0; src_rect.width = width << 16; src_rect.height = height << 16; dispman_display = vc_dispmanx_display_open (0); dispman_update = vc_dispmanx_update_start (0); dispman_element = vc_dispmanx_element_add (dispman_update, dispman_display, 0, &dst_rect, 0, &src_rect, DISPMANX_PROTECTION_NONE, 0, 0, 0); *window_data = data = g_slice_new0 (RPIWindowData); data->d = dispman_display; data->w.element = dispman_element; data->w.width = width; data->w.height = height; vc_dispmanx_update_submit_sync (dispman_update); return (EGLNativeWindowType) data; }
/** Creates a native window for the GL surface using dispmanx * @param raspitex_state A pointer to the GL preview state. * @return Zero if successful, otherwise, -1 is returned. */ int raspitexutil_create_native_window(RASPITEX_STATE *raspitex_state) { VC_DISPMANX_ALPHA_T alpha = {DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, 0}; VC_RECT_T src_rect = {0}; VC_RECT_T dest_rect = {0}; uint32_t disp_num = 0; // Primary uint32_t layer_num = 0; DISPMANX_ELEMENT_HANDLE_T elem; DISPMANX_UPDATE_HANDLE_T update; alpha.opacity = raspitex_state->opacity; dest_rect.x = raspitex_state->x; dest_rect.y = raspitex_state->y; dest_rect.width = raspitex_state->width; dest_rect.height = raspitex_state->height; vcos_log_trace("%s: %d,%d,%d,%d %d,%d,0x%x,0x%x", VCOS_FUNCTION, src_rect.x, src_rect.y, src_rect.width, src_rect.height, dest_rect.x, dest_rect.y, dest_rect.width, dest_rect.height); src_rect.width = dest_rect.width << 16; src_rect.height = dest_rect.height << 16; raspitex_state->disp = vc_dispmanx_display_open(disp_num); if (raspitex_state->disp == DISPMANX_NO_HANDLE) { vcos_log_error("Failed to open display handle"); goto error; } update = vc_dispmanx_update_start(0); if (update == DISPMANX_NO_HANDLE) { vcos_log_error("Failed to open update handle"); goto error; } elem = vc_dispmanx_element_add(update, raspitex_state->disp, layer_num, &dest_rect, 0, &src_rect, DISPMANX_PROTECTION_NONE, &alpha, NULL, DISPMANX_NO_ROTATE); if (elem == DISPMANX_NO_HANDLE) { vcos_log_error("Failed to create element handle"); goto error; } raspitex_state->win.element = elem; raspitex_state->win.width = raspitex_state->width; raspitex_state->win.height = raspitex_state->height; vc_dispmanx_update_submit_sync(update); raspitex_state->native_window = (EGLNativeWindowType*) &raspitex_state->win; return 0; error: return -1; }
BBEGLContext *createDisplayContext(){ EGLContext context; EGLSurface surface; static const EGLint contextAttribs[]={ EGL_CONTEXT_CLIENT_VERSION,2, EGL_NONE}; context=eglCreateContext(display,config,EGL_NO_CONTEXT,contextAttribs); assert(eglGetError()==EGL_SUCCESS); unsigned int width,height; graphics_get_display_size(0,&width,&height); printf("display size is %dx%d\n",width,height); VC_RECT_T dst={0}; dst.width=width; dst.height=height; VC_RECT_T src={0}; src.width=width<<16; src.height=height<<16; static EGL_DISPMANX_WINDOW_T nativewindow; DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; dispman_display = vc_dispmanx_display_open( 0 /* LCD */); dispman_update = vc_dispmanx_update_start( 0 ); dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display, 0/*layer*/, &dst, 0/*src*/, &src, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, DISPMANX_NO_ROTATE/*transform*/); nativewindow.element = dispman_element; nativewindow.width = width; nativewindow.height = height; vc_dispmanx_update_submit_sync( dispman_update ); surface=eglCreateWindowSurface(display,config,&nativewindow,NULL); eglMakeCurrent(display,surface,surface,context); DeviceContext.width=width; DeviceContext.height=height; DeviceContext.depth=32; DeviceContext.hertz=60; DeviceContext.context=context; DeviceContext.surface=surface; return &DeviceContext; }