static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture) { vout_display_sys_t *sys = vd->sys; assert(sys->display); /* Our surface can be lost so be sure to check this * and restore it if need be */ if (IDirectDrawSurface2_IsLost(sys->display) == DDERR_SURFACELOST) { if (IDirectDrawSurface2_Restore(sys->display) == DD_OK) { if (sys->use_overlay) DirectXUpdateOverlay(vd, NULL); } } if (sys->restore_overlay) DirectXUpdateOverlay(vd, NULL); /* */ DirectXUnlock(picture); if (sys->use_overlay) { /* Flip the overlay buffers if we are using back buffers */ if (picture->p_sys->surface != picture->p_sys->front_surface) { HRESULT hr = IDirectDrawSurface2_Flip(picture->p_sys->front_surface, NULL, DDFLIP_WAIT); if (hr != DD_OK) msg_Warn(vd, "could not flip overlay (error %li)", hr); } } else { /* Blit video surface to display with the NOTEARING option */ DDBLTFX ddbltfx; ZeroMemory(&ddbltfx, sizeof(ddbltfx)); ddbltfx.dwSize = sizeof(ddbltfx); ddbltfx.dwDDFX = DDBLTFX_NOTEARING; HRESULT hr = IDirectDrawSurface2_Blt(sys->display, &sys->rect_dest_clipped, picture->p_sys->surface, &sys->rect_src_clipped, DDBLT_ASYNC, &ddbltfx); if (hr != DD_OK) msg_Warn(vd, "could not blit surface (error %li)", hr); } DirectXLock(picture); if (sys->is_first_display) { IDirectDraw_WaitForVerticalBlank(sys->ddobject, DDWAITVB_BLOCKBEGIN, NULL); if (sys->use_overlay) { HBRUSH brush = CreateSolidBrush(sys->i_rgb_colorkey); /* set the colorkey as the backgound brush for the video window */ SetClassLongPtr(sys->hvideownd, GCLP_HBRBACKGROUND, (LONG_PTR)brush); } } CommonDisplay(vd); picture_Release(picture); VLC_UNUSED(subpicture); }
/* flip_with_forefront_bitmap: * Worker function for DirectDraw page flipping. */ static int flip_with_forefront_bitmap(BITMAP *bmp, int wait) { DDRAW_SURFACE *surf; HRESULT hr; /* flip only in the foreground */ if (!_win_app_foreground) { _win_thread_switch_out(); return 0; } /* retrieve the underlying surface */ surf = DDRAW_SURFACE_OF(bmp); if (surf == flipping_page[0]) return 0; ASSERT((surf == flipping_page[1]) || (surf == flipping_page[2])); /* flip the contents of the surfaces */ hr = IDirectDrawSurface2_Flip(flipping_page[0]->id, surf->id, wait ? DDFLIP_WAIT : 0); /* if the surface has been lost, try to restore all surfaces */ if (hr == DDERR_SURFACELOST) { if (restore_all_ddraw_surfaces() == 0) hr = IDirectDrawSurface2_Flip(flipping_page[0]->id, surf->id, wait ? DDFLIP_WAIT : 0); } if (FAILED(hr)) { _TRACE(PREFIX_E "Can't flip (%s)\n", dd_err(hr)); return -1; } /* attach the surface to the former forefront bitmap */ surf->parent_bmp = flipping_page[0]->parent_bmp; surf->parent_bmp->extra = surf; /* make the bitmap point to the forefront surface */ flipping_page[0]->parent_bmp = bmp; bmp->extra = flipping_page[0]; return 0; }
int directdraw_draw(void *pic, int w, int h) { DDSURFACEDESC descriptor; RECT rct; HWND hwndp; #define fourcc(a,b,c,d) (( ((uint32_t)a) | ( ((uint32_t)b) << 8 ) | ( ((uint32_t)c) << 16 ) | ( ((uint32_t)d) << 24 ) )) int bh = h, bw = w; //w = default_sw; //h = default_sh; vdata.getdata(get_window_video, 0, &hwndp, 0); if(!hwndp) return 0; if(video_window_parent != hwndp) { video_uninit(); video_init(hwndp); video_window_parent = hwndp; } if(w != d_width || h != d_height) { if(size_in_list(w, h))size_is_ok = 1; else size_is_ok = 0; if(w && h) { d_width = w; d_height = h; if(lpDDS_secondary) IDirectDrawSurface2_Release(lpDDS_secondary); memset(&descriptor, 0, sizeof(descriptor)); descriptor.dwSize = sizeof(descriptor); descriptor.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; descriptor.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; descriptor.dwWidth = d_width; descriptor.dwHeight = d_height; if(FAILED(IDirectDraw2_CreateSurface(lpDD, &descriptor, &lpDDS_secondary, 0))) return 0; lpDDS_back = lpDDS_secondary; } } if(use_osd_surface) { GetClientRect(video_window, &rct); if(rct.right != window_w || rct.bottom != window_h || osd_created == 0) { window_w = rct.right; window_h = rct.bottom; if(surface_osd) IDirectDrawSurface2_Release(surface_osd); memset( &descriptor, 0, sizeof(descriptor)); descriptor.dwSize = sizeof(descriptor); descriptor.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; descriptor.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; descriptor.dwWidth = window_w; descriptor.dwHeight = window_h; if(FAILED(IDirectDraw2_CreateSurface(lpDD, &descriptor, &surface_osd, 0))) return 0; osd_created = 1; } } IDirectDrawSurface2_Restore(lpDDS); if(pic) IDirectDrawSurface2_Restore(lpDDS_secondary); memset(&descriptor, 0, sizeof(descriptor)); descriptor.dwSize = sizeof(descriptor); if(pic) { HRESULT res; if(size_is_ok) { res = IDirectDrawSurface2_Lock(lpDDS_back, 0, &descriptor, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0); if(FAILED(res)) return 0; memcpy(descriptor.lpSurface, pic, w * h * 4); IDirectDrawSurface2_Unlock(lpDDS_back, descriptor.lpSurface); }else{ HBITMAP bmp; HDC hdc, cdc; bmp = CreateBitmap(w, h, 1, 32, pic); if(!FAILED(IDirectDrawSurface2_GetDC(lpDDS_back, &hdc))) { cdc = CreateCompatibleDC(0); SelectObject(cdc, bmp); BitBlt(hdc, 0, 0, w, h, cdc, 0, 0, SRCCOPY); IDirectDrawSurface2_ReleaseDC(lpDDS_back, hdc); DeleteDC(cdc); } DeleteObject(bmp); } IDirectDrawSurface2_Flip(lpDDS, 0, DDFLIP_WAIT); } return 1; }