static void gdi_set_osd_msg(void *data, video_frame_info_t *video_info, const char *msg, const void *params, void *font) { font_driver_render_msg(video_info, font, msg, params); }
static void vita_set_osd_msg(void *data, const char *msg, const void *params, void *font) { video_frame_info_t video_info; video_driver_build_info(&video_info); font_driver_render_msg(&video_info, font, msg, params); }
static void gl1_set_osd_msg(void *data, video_frame_info_t *video_info, const char *msg, const void *params, void *font) { font_driver_render_msg(video_info, font, msg, (const struct font_params *)params); }
static void d3d_set_osd_msg(void *data, const char *msg, const struct font_params *params, void *font) { d3d_video_t *d3d = (d3d_video_t*)data; if (d3d->renderchain_driver->set_font_rect && params) d3d->renderchain_driver->set_font_rect(d3d, params); font_driver_render_msg(NULL, msg, params); }
static bool vita2d_gfx_frame(void *data, const void *frame, unsigned width, unsigned height, uint64_t frame_count, unsigned pitch, const char *msg, video_frame_info_t *video_info) { void *tex_p; vita_video_t *vita = (vita_video_t *)data; if (frame) { if(!(vita->texture&&vita2d_texture_get_datap(vita->texture)==frame)) { unsigned i; unsigned int stride; if ((width != vita->width || height != vita->height) && vita->texture) { vita2d_free_texture(vita->texture); vita->texture = NULL; } if (!vita->texture) { RARCH_LOG("Creating texture: %ix%i\n", width, height); vita->width = width; vita->height = height; vita->texture = vita2d_create_empty_texture_format(width, height, vita->format); vita2d_texture_set_filters(vita->texture,vita->tex_filter,vita->tex_filter); } tex_p = vita2d_texture_get_datap(vita->texture); stride = vita2d_texture_get_stride(vita->texture); if (vita->format == SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1RGB) { stride /= 4; pitch /= 4; uint32_t *tex32 = tex_p; const uint32_t *frame32 = frame; for (i = 0; i < height; i++) memcpy_neon(&tex32[i*stride],&frame32[i*pitch],pitch*sizeof(uint32_t)); } else { stride /= 2; pitch /= 2; uint16_t *tex16 = tex_p; const uint16_t *frame16 = frame; for (i = 0; i < height; i++) memcpy_neon(&tex16[i*stride],&frame16[i*pitch],width*sizeof(uint16_t)); } } } if (vita->should_resize) vita2d_gfx_update_viewport(vita); vita2d_start_drawing(); vita2d_draw_rectangle(0,0,PSP_FB_WIDTH,PSP_FB_HEIGHT,vita2d_get_clear_color()); if (vita->texture) { if (vita->fullscreen) vita2d_draw_texture_scale(vita->texture, 0, 0, PSP_FB_WIDTH / (float)vita->width, PSP_FB_HEIGHT / (float)vita->height); else { const float radian = 90 * 0.0174532925f; const float rad = vita->rotation * radian; float scalex = vita->vp.width / (float)vita->width; float scaley = vita->vp.height / (float)vita->height; vita2d_draw_texture_scale_rotate(vita->texture,vita->vp.x, vita->vp.y, scalex, scaley, rad); } } #ifdef HAVE_OVERLAY if (vita->overlay_enable) vita2d_render_overlay(vita); #endif if (vita->menu.active) { #ifdef HAVE_MENU menu_driver_frame(video_info); #endif if(vita->menu.texture) { if (vita->fullscreen) vita2d_draw_texture_scale(vita->menu.texture, 0, 0, PSP_FB_WIDTH / (float)vita->menu.width, PSP_FB_HEIGHT / (float)vita->menu.height); else { if (vita->menu.width > vita->menu.height) { float scale = PSP_FB_HEIGHT / (float)vita->menu.height; float w = vita->menu.width * scale; vita2d_draw_texture_scale(vita->menu.texture, PSP_FB_WIDTH / 2.0f - w/2.0f, 0.0f, scale, scale); } else { float scale = PSP_FB_WIDTH / (float)vita->menu.width; float h = vita->menu.height * scale; vita2d_draw_texture_scale(vita->menu.texture, 0.0f, PSP_FB_HEIGHT / 2.0f - h/2.0f, scale, scale); } } } } if(!string_is_empty(msg)) font_driver_render_msg(video_info, NULL, msg, NULL); vita2d_end_drawing(); vita2d_swap_buffers(); return true; }
static bool switch_frame(void *data, const void *frame, unsigned width, unsigned height, uint64_t frame_count, unsigned pitch, const char *msg, video_frame_info_t *video_info) { static uint64_t last_frame = 0; unsigned x, y; result_t r; int tgtw, tgth, centerx, centery; uint32_t *out_buffer = NULL; switch_video_t *sw = data; int xsf = 1280 / width; int ysf = 720 / height; int sf = xsf; if (ysf < sf) sf = ysf; tgtw = width * sf; tgth = height * sf; centerx = (1280-tgtw)/2; centery = (720-tgth)/2; // clear image to black for(y = 0; y < 720; y++) { for(x = 0; x < 1280; x++) { sw->image[y*1280+x] = 0xFF000000; } } if(width > 0 && height > 0) { if(sw->last_width != width || sw->last_height != height) { scaler_ctx_gen_reset(&sw->scaler); sw->scaler.in_width = width; sw->scaler.in_height = height; sw->scaler.in_stride = pitch; sw->scaler.in_fmt = sw->rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGB565; sw->scaler.out_width = tgtw; sw->scaler.out_height = tgth; sw->scaler.out_stride = 1280 * sizeof(uint32_t); sw->scaler.out_fmt = SCALER_FMT_ABGR8888; sw->scaler.scaler_type = SCALER_TYPE_POINT; if(!scaler_ctx_gen_filter(&sw->scaler)) { RARCH_ERR("failed to generate scaler for main image\n"); return false; } sw->last_width = width; sw->last_height = height; } scaler_ctx_scale(&sw->scaler, sw->image + (centery * 1280) + centerx, frame); } #if defined(HAVE_MENU) if (sw->menu_texture.enable) { menu_driver_frame(video_info); if (sw->menu_texture.pixels) { #if 0 if (sw->menu_texture.fullscreen) { #endif scaler_ctx_scale(&sw->menu_texture.scaler, sw->image + ((720-sw->menu_texture.tgth)/2)*1280 + ((1280-sw->menu_texture.tgtw)/2), sw->menu_texture.pixels); #if 0 } else { } #endif } } else if (video_info->statistics_show) { struct font_params *osd_params = (struct font_params*) &video_info->osd_stat_params; if (osd_params) { font_driver_render_msg(video_info, NULL, video_info->stat_text, (const struct font_params*)&video_info->osd_stat_params); } } #endif #if 0 if (frame_count > 6000) { display_finalize(); exit(0); } #endif if (msg && strlen(msg) > 0) RARCH_LOG("message: %s\n", msg); r = surface_dequeue_buffer(&sw->surface, &out_buffer); if (sw->vsync) switch_wait_vsync(sw); svcSleepThread(10000); if(r != RESULT_OK) { return true; // just skip the frame } gfx_slow_swizzling_blit(out_buffer, sw->image, 1280, 720, 0, 0); r = surface_queue_buffer(&sw->surface); if (r != RESULT_OK) return false; last_frame = svcGetSystemTick(); return true; }
static bool gl1_gfx_frame(void *data, const void *frame, unsigned frame_width, unsigned frame_height, uint64_t frame_count, unsigned pitch, const char *msg, video_frame_info_t *video_info) { gfx_ctx_mode_t mode; const void *frame_to_copy = NULL; unsigned width = 0; unsigned height = 0; unsigned bits = gl1_video_bits; bool draw = true; gl1_t *gl1 = (gl1_t*)data; unsigned pot_width = 0; unsigned pot_height = 0; gl1_context_bind_hw_render(gl1, false); /* FIXME: Force these settings off as they interfere with the rendering */ video_info->xmb_shadows_enable = false; video_info->menu_shader_pipeline = 0; if (!frame || !frame_width || !frame_height) return true; if (gl1->should_resize) { gfx_ctx_mode_t mode; gl1->should_resize = false; mode.width = width; mode.height = height; video_info->cb_set_resize(video_info->context_data, mode.width, mode.height); gl1_gfx_set_viewport(gl1, video_info, video_info->width, video_info->height, false, true); } glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if ( gl1_video_width != frame_width || gl1_video_height != frame_height || gl1_video_pitch != pitch) { if (frame_width > 4 && frame_height > 4) { gl1_video_width = frame_width; gl1_video_height = frame_height; gl1_video_pitch = pitch; pot_width = get_pot(frame_width); pot_height = get_pot(frame_height); if (gl1_video_buf) free(gl1_video_buf); gl1_video_buf = (unsigned char*)malloc(pot_width * pot_height * 4); } } width = gl1_video_width; height = gl1_video_height; pitch = gl1_video_pitch; pot_width = get_pot(width); pot_height = get_pot(height); if ( frame_width == 4 && frame_height == 4 && (frame_width < width && frame_height < height) ) draw = false; if (draw && gl1_video_buf) { if (bits == 32) { unsigned y; /* copy lines into top-left portion of larger (power-of-two) buffer */ for (y = 0; y < height; y++) memcpy(gl1_video_buf + ((pot_width * (bits / 8)) * y), (const unsigned char*)frame + (pitch * y), width * (bits / 8)); } else if (bits == 16) conv_rgb565_argb8888(gl1_video_buf, frame, width, height, pot_width * sizeof(unsigned), pitch); frame_to_copy = gl1_video_buf; } if (gl1->video_width != width || gl1->video_height != height) { gl1->video_width = width; gl1->video_height = height; } video_context_driver_get_video_size(&mode); gl1->screen_width = mode.width; gl1->screen_height = mode.height; if (draw) { if (frame_to_copy) { draw_tex(gl1, pot_width, pot_height, width, height, gl1->tex, frame_to_copy); } } if (gl1_menu_frame && video_info->menu_is_alive) { frame_to_copy = NULL; width = gl1_menu_width; height = gl1_menu_height; pitch = gl1_menu_pitch; bits = gl1_menu_bits; pot_width = get_pot(width); pot_height = get_pot(height); if (gl1_menu_size_changed) { gl1_menu_size_changed = false; if (gl1_menu_video_buf) { free(gl1_menu_video_buf); gl1_menu_video_buf = NULL; } } if (!gl1_menu_video_buf) gl1_menu_video_buf = (unsigned char*)malloc(pot_width * pot_height * 4); if (bits == 16 && gl1_menu_video_buf) { conv_rgba4444_argb8888(gl1_menu_video_buf, gl1_menu_frame, width, height, pot_width * sizeof(unsigned), pitch); frame_to_copy = gl1_menu_video_buf; if (gl1->menu_texture_full_screen) { glViewport(0, 0, video_info->width, video_info->height); draw_tex(gl1, pot_width, pot_height, width, height, gl1->menu_tex, frame_to_copy); glViewport(gl1->vp.x, gl1->vp.y, gl1->vp.width, gl1->vp.height); } else draw_tex(gl1, pot_width, pot_height, width, height, gl1->menu_tex, frame_to_copy); } } #ifdef HAVE_MENU if (gl1->menu_texture_enable) menu_driver_frame(video_info); else if (video_info->statistics_show) { struct font_params *osd_params = (struct font_params*) &video_info->osd_stat_params; if (osd_params) { font_driver_render_msg(video_info, NULL, video_info->stat_text, (const struct font_params*)&video_info->osd_stat_params); #if 0 osd_params->y = 0.350f; osd_params->scale = 0.75f; font_driver_render_msg(video_info, NULL, video_info->chat_text, (const struct font_params*)&video_info->osd_stat_params); #endif } } #ifdef HAVE_MENU_WIDGETS menu_widgets_frame(video_info); #endif #endif #ifdef HAVE_OVERLAY if (gl1->overlay_enable) gl1_render_overlay(gl1, video_info); #endif if (msg) font_driver_render_msg(video_info, NULL, msg, NULL); video_info->cb_update_window_title( video_info->context_data, video_info); /* Screenshots. */ if (gl1->readback_buffer_screenshot) gl1_readback(gl1, 4, GL_RGBA, GL_UNSIGNED_BYTE, gl1->readback_buffer_screenshot); /* emscripten has to do black frame insertion in its main loop */ #ifndef EMSCRIPTEN /* Disable BFI during fast forward, slow-motion, * and pause to prevent flicker. */ if ( video_info->black_frame_insertion && !video_info->input_driver_nonblock_state && !video_info->runloop_is_slowmotion && !video_info->runloop_is_paused) { video_info->cb_swap_buffers(video_info->context_data, video_info); glClear(GL_COLOR_BUFFER_BIT); } #endif video_info->cb_swap_buffers(video_info->context_data, video_info); /* check if we are fast forwarding or in menu, if we are ignore hard sync */ if (video_info->hard_sync && !video_info->input_driver_nonblock_state && !gl1->menu_texture_enable) { glClear(GL_COLOR_BUFFER_BIT); glFinish(); } gl1_context_bind_hw_render(gl1, true); return true; }
static bool gdi_gfx_frame(void *data, const void *frame, unsigned frame_width, unsigned frame_height, uint64_t frame_count, unsigned pitch, const char *msg, video_frame_info_t *video_info) { gfx_ctx_mode_t mode; const void *frame_to_copy = frame; unsigned width = 0; unsigned height = 0; unsigned bits = gdi_video_bits; bool draw = true; gdi_t *gdi = (gdi_t*)data; HWND hwnd = win32_get_window(); if (!frame || !frame_width || !frame_height) return true; #ifdef HAVE_MENU menu_driver_frame(video_info); #endif if (gdi_video_width != frame_width || gdi_video_height != frame_height || gdi_video_pitch != pitch) { if (frame_width > 4 && frame_height > 4) { gdi_video_width = frame_width; gdi_video_height = frame_height; gdi_video_pitch = pitch; } } if (gdi_menu_frame && video_info->menu_is_alive) { frame_to_copy = gdi_menu_frame; width = gdi_menu_width; height = gdi_menu_height; pitch = gdi_menu_pitch; bits = gdi_menu_bits; } else { width = gdi_video_width; height = gdi_video_height; pitch = gdi_video_pitch; if (frame_width == 4 && frame_height == 4 && (frame_width < width && frame_height < height)) draw = false; if (video_info->menu_is_alive) draw = false; } if (hwnd && !gdi->winDC) { gdi->winDC = GetDC(hwnd); gdi->memDC = CreateCompatibleDC(gdi->winDC); gdi->video_width = width; gdi->video_height = height; gdi->bmp = CreateCompatibleBitmap(gdi->winDC, gdi->video_width, gdi->video_height); } gdi->bmp_old = (HBITMAP)SelectObject(gdi->memDC, gdi->bmp); if (gdi->video_width != width || gdi->video_height != height) { SelectObject(gdi->memDC, gdi->bmp_old); DeleteObject(gdi->bmp); gdi->video_width = width; gdi->video_height = height; gdi->bmp = CreateCompatibleBitmap(gdi->winDC, gdi->video_width, gdi->video_height); gdi->bmp_old = (HBITMAP)SelectObject(gdi->memDC, gdi->bmp); } video_context_driver_get_video_size(&mode); gdi->screen_width = mode.width; gdi->screen_height = mode.height; BITMAPINFO *info = (BITMAPINFO*)calloc(1, sizeof(*info) + (3 * sizeof(RGBQUAD))); info->bmiHeader.biBitCount = bits; info->bmiHeader.biWidth = pitch / (bits / 8); info->bmiHeader.biHeight = -height; info->bmiHeader.biPlanes = 1; info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); info->bmiHeader.biSizeImage = 0; if (bits == 16) { unsigned *masks = (unsigned*)info->bmiColors; info->bmiHeader.biCompression = BI_BITFIELDS; /* default 16-bit format on Windows is XRGB1555 */ if (frame_to_copy == gdi_menu_frame) { /* map RGB444 color bits for RGUI */ masks[0] = 0xF000; masks[1] = 0x0F00; masks[2] = 0x00F0; } else { /* map RGB565 color bits for core */ masks[0] = 0xF800; masks[1] = 0x07E0; masks[2] = 0x001F; } } else info->bmiHeader.biCompression = BI_RGB; if (draw) { StretchDIBits(gdi->memDC, 0, 0, width, height, 0, 0, width, height, frame_to_copy, info, DIB_RGB_COLORS, SRCCOPY); } SelectObject(gdi->memDC, gdi->bmp_old); free(info); if (msg) font_driver_render_msg(video_info, NULL, msg, NULL); InvalidateRect(hwnd, NULL, false); video_info->cb_update_window_title( video_info->context_data, video_info); return true; }
static bool caca_gfx_frame(void *data, const void *frame, unsigned frame_width, unsigned frame_height, uint64_t frame_count, unsigned pitch, const char *msg) { size_t len = 0; void *buffer = NULL; const void *frame_to_copy = frame; unsigned width = 0; unsigned height = 0; bool draw = true; (void)data; (void)frame; (void)frame_width; (void)frame_height; (void)pitch; (void)msg; if (!frame || !frame_width || !frame_height) return true; if (caca_video_width != frame_width || caca_video_height != frame_height || caca_video_pitch != pitch) { if (frame_width > 4 && frame_height > 4) { caca_video_width = frame_width; caca_video_height = frame_height; caca_video_pitch = pitch; caca_gfx_free(NULL); caca_gfx_create(); } } if (!caca_cv) return true; if (caca_menu_frame) frame_to_copy = caca_menu_frame; width = caca_get_canvas_width(caca_cv); height = caca_get_canvas_height(caca_cv); if (frame_to_copy == frame && frame_width == 4 && frame_height == 4 && (frame_width < width && frame_height < height)) draw = false; caca_clear_canvas(caca_cv); #ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_FRAME, NULL); #endif if (msg) font_driver_render_msg(NULL, msg, NULL); if (draw) { caca_dither_bitmap(caca_cv, 0, 0, width, height, caca_dither, frame_to_copy); buffer = caca_export_canvas_to_memory(caca_cv, "caca", &len); if (buffer) { if (len) caca_refresh_display(caca_display); free(buffer); } } return true; }
static void caca_set_osd_msg(void *data, const char *msg, const struct font_params *params, void *font) { font_driver_render_msg(font, msg, params); }