texture_info * renderer_sdl2::texture_update(const render_primitive &prim) { quad_setup_data setup; texture_info *texture; auto win = assert_window(); setup.compute(prim, win->prescale()); texture = texture_find(prim, setup); // if we didn't find one, create a new texture if (texture == nullptr && prim.texture.base != nullptr) { texture = global_alloc(texture_info(this, prim.texture, setup, prim.flags)); /* add us to the texture list */ m_texlist.prepend(*texture); } if (texture != nullptr) { if (prim.texture.base != nullptr && texture->texinfo().seqid != prim.texture.seqid) { texture->texinfo().seqid = prim.texture.seqid; // if we found it, but with a different seqid, copy the data texture->set_data(prim.texture, prim.flags); } } return texture; }
render_primitive_list *renderer_sdl2::get_primitives() { auto win = assert_window(); if (win == nullptr) return nullptr; osd_dim nd = win->get_size(); if (nd != m_blit_dim) { m_blit_dim = nd; notify_changed(); } win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect()); return &win->target()->get_primitives(); }
void renderer_sdl2::destroy_all_textures() { auto win = assert_window(); if (win == nullptr) return; if(win->m_primlist) { win->m_primlist->acquire_lock(); m_texlist.reset(); win->m_primlist->release_lock(); } else m_texlist.reset(); }
int renderer_sdl2::create() { // create renderer /* Enable bilinear filtering in case it is supported. * This applies to all texture operations. However, artwort is pre-scaled * and thus shouldn't be affected. */ if (video_config.filter) { SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); } else { SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); } auto win = assert_window(); if (video_config.waitvsync) m_sdl_renderer = SDL_CreateRenderer(win->platform_window<SDL_Window*>(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); else m_sdl_renderer = SDL_CreateRenderer(win->platform_window<SDL_Window*>(), -1, SDL_RENDERER_ACCELERATED); if (!m_sdl_renderer) { fatalerror("Error on creating renderer: %s\n", SDL_GetError()); } //SDL_SelectRenderer(window().sdl_window); m_blittimer = 3; //SDL_RenderPresent(m_sdl_renderer); osd_printf_verbose("Leave renderer_sdl2::create\n"); struct SDL_RendererInfo render_info; SDL_GetRendererInfo(m_sdl_renderer, &render_info); drawsdl_show_info(&render_info); return 0; }
int renderer_gdi::draw(const int update) { auto win = assert_window(); // we don't have any special resize behaviors if (win->m_resize_state == RESIZE_STATE_PENDING) win->m_resize_state = RESIZE_STATE_NORMAL; // get the target bounds RECT bounds; GetClientRect(win->platform_window<HWND>(), &bounds); // compute width/height/pitch of target int width = rect_width(&bounds); int height = rect_height(&bounds); int pitch = (width + 3) & ~3; // make sure our temporary bitmap is big enough if (pitch * height * 4 > m_bmsize) { m_bmsize = pitch * height * 4 * 2; global_free_array(m_bmdata); m_bmdata = global_alloc_array(uint8_t, m_bmsize); } // draw the primitives to the bitmap win->m_primlist->acquire_lock(); software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*win->m_primlist, m_bmdata, width, height, pitch); win->m_primlist->release_lock(); // fill in bitmap-specific info m_bminfo.bmiHeader.biWidth = pitch; m_bminfo.bmiHeader.biHeight = -height; // blit to the screen StretchDIBits(win->m_dc, 0, 0, width, height, 0, 0, width, height, m_bmdata, &m_bminfo, DIB_RGB_COLORS, SRCCOPY); return 0; }
int renderer_sdl2::draw(int update) { texture_info *texture=nullptr; float vofs, hofs; int blit_pixels = 0; if (video_config.novideo) { return 0; } auto win = assert_window(); osd_dim wdim = win->get_size(); if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height)) { destroy_all_textures(); m_width = wdim.width(); m_height = wdim.height(); SDL_RenderSetViewport(m_sdl_renderer, nullptr); m_blittimer = 3; clear_flags(FI_CHANGED); } //SDL_SelectRenderer(window().sdl_window); if (m_blittimer > 0) { /* SDL Underlays need alpha = 0 ! */ SDL_SetRenderDrawBlendMode(m_sdl_renderer, SDL_BLENDMODE_NONE); //SDL_SetRenderDrawColor(0,0,0,255); SDL_SetRenderDrawColor(m_sdl_renderer, 0,0,0,0); SDL_RenderFillRect(m_sdl_renderer, nullptr); m_blittimer--; } // compute centering parameters vofs = hofs = 0.0f; if (video_config.centerv || video_config.centerh) { int ch, cw; ch = wdim.height(); cw = wdim.width(); if (video_config.centerv) { vofs = (ch - m_blit_dim.height()) / 2.0f; } if (video_config.centerh) { hofs = (cw - m_blit_dim.width()) / 2.0f; } } m_last_hofs = hofs; m_last_vofs = vofs; win->m_primlist->acquire_lock(); // now draw for (render_primitive &prim : *win->m_primlist) { Uint8 sr, sg, sb, sa; switch (prim.type) { case render_primitive::LINE: sr = (int)(255.0f * prim.color.r); sg = (int)(255.0f * prim.color.g); sb = (int)(255.0f * prim.color.b); sa = (int)(255.0f * prim.color.a); SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags))); SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa); SDL_RenderDrawLine(m_sdl_renderer, prim.bounds.x0 + hofs, prim.bounds.y0 + vofs, prim.bounds.x1 + hofs, prim.bounds.y1 + vofs); break; case render_primitive::QUAD: texture = texture_update(prim); if (texture) blit_pixels += (texture->raw_height() * texture->raw_width()); render_quad(texture, prim, round_nearest(hofs + prim.bounds.x0), round_nearest(vofs + prim.bounds.y0)); break; default: throw emu_fatalerror("Unexpected render_primitive type\n"); } } win->m_primlist->release_lock(); m_last_blit_pixels = blit_pixels; m_last_blit_time = -osd_ticks(); SDL_RenderPresent(m_sdl_renderer); m_last_blit_time += osd_ticks(); return 0; }