📄 gapi.cpp
字号:
atts[12] = EGL_SURFACE_TYPE; atts[13] = EGL_PIXMAP_BIT; atts[14] = EGL_NONE; /*whenever window is resized we must reinit OGL-ES*/ GAPI_ReleaseOGL_ES(gctx); if (!gctx->fullscreen) { RECT rc; ::GetClientRect(gctx->hWnd, &rc); gctx->bb_width = rc.right-rc.left; gctx->bb_height = rc.bottom-rc.top; dc = GetDC(gctx->hWnd); createPixmap(gctx, dc, 1); ReleaseDC(gctx->hWnd, dc); } gctx->egldpy = eglGetDisplay(/*gctx->dpy*/EGL_DEFAULT_DISPLAY); if (!eglInitialize(gctx->egldpy, &maj, &min)) { gctx->egldpy = NULL; return GF_IO_ERR; } eglGetConfigs(gctx->egldpy, NULL, 0, &n); if (!eglChooseConfig(gctx->egldpy, atts, &gctx->eglconfig, 1, &n)) { return GF_IO_ERR; } if (gctx->fullscreen) { gctx->surface = eglCreateWindowSurface(gctx->egldpy, gctx->eglconfig, gctx->hWnd, 0); } else { gctx->surface = eglCreatePixmapSurface(gctx->egldpy, gctx->eglconfig, gctx->bitmap, 0); } if (!gctx->surface) { return GF_IO_ERR; } gctx->eglctx = eglCreateContext(gctx->egldpy, gctx->eglconfig, NULL, NULL); if (!gctx->eglctx) { eglDestroySurface(gctx->egldpy, gctx->surface); gctx->surface = 0L; return GF_IO_ERR; } if (!eglMakeCurrent(gctx->egldpy, gctx->surface, gctx->surface, gctx->eglctx)) { eglDestroyContext(gctx->egldpy, gctx->eglctx); gctx->eglctx = 0L; eglDestroySurface(gctx->egldpy, gctx->surface); gctx->surface = 0L; return GF_IO_ERR; } evt.type = GF_EVENT_VIDEO_SETUP; dr->on_event(dr->evt_cbk_hdl, &evt); return GF_OK;}#endifvoid GAPI_ReleaseObjects(GAPIPriv *ctx){#ifdef GPAC_USE_OGL_ES if (ctx->is_3D) GAPI_ReleaseOGL_ES(ctx); else#endif if (ctx->bitmap) DeleteObject(ctx->bitmap); else if (ctx->backbuffer) free(ctx->backbuffer); ctx->backbuffer = NULL; ctx->bitmap = NULL;}GF_Err GAPI_Setup(GF_VideoOutput *dr, void *os_handle, void *os_display, Bool noover, GF_GLConfig *cfg){ struct GXDisplayProperties gx = GXGetDisplayProperties(); RECT rc; GAPICTX(dr); gctx->hWnd = (HWND) os_handle; /*get keys in both 2D and 3D modes*/ gctx->keys = GXGetDefaultKeys(GX_NORMALKEYS);#if 0 /*FIXME - not supported in rasterizer*/ if (gx.ffFormat & kfDirect444) { gctx->pixel_format = GF_PIXEL_RGB_444; gctx->BPP = 2; gctx->bitsPP = 12; } else #endif if (gx.ffFormat & kfDirect555) { gctx->pixel_format = GF_PIXEL_RGB_555; gctx->BPP = 2; gctx->bits_per_pixel = 15; } else if (gx.ffFormat & kfDirect565) { gctx->pixel_format = GF_PIXEL_RGB_565; gctx->BPP = 2; gctx->bits_per_pixel = 16; } else if (gx.ffFormat & kfDirect888) { gctx->pixel_format = GF_PIXEL_RGB_24; gctx->BPP = 3; gctx->bits_per_pixel = 24; } else { return GF_NOT_SUPPORTED; } dr->max_screen_width = gctx->screen_w = gx.cxWidth; dr->max_screen_height = gctx->screen_h = gx.cyHeight; is_landscape = (gx.ffFormat & kfLandscape) ? 1 : 0; gctx->x_pitch = gx.cbxPitch; gctx->y_pitch = gx.cbyPitch; if (cfg) {#ifdef GPAC_USE_OGL_ES gctx->gl_cfg = *cfg; gctx->is_3D = 1;#else return GF_NOT_SUPPORTED;#endif } GAPI_SetupWindow(dr); if (!gctx->hWnd) return GF_IO_ERR;#ifdef GPAC_USE_OGL_ES if (gctx->is_3D) return GF_OK;#endif /*setup GX*/ if (!GXOpenDisplay(gctx->hWnd, 0L)) { MessageBox(NULL, _T("Cannot open display"), _T("GAPI Error"), MB_OK); return GF_IO_ERR; } GetClientRect(gctx->hWnd, &rc); gctx->backup_w = rc.right - rc.left; gctx->backup_h = rc.bottom - rc.top; return GAPI_InitBackBuffer(dr, gctx->backup_w, gctx->backup_h);}static void GAPI_Shutdown(GF_VideoOutput *dr){ GAPICTX(dr); gf_mx_p(gctx->mx); GAPI_ReleaseObjects(gctx); GXCloseDisplay(); GAPI_ShutdownWindow(dr); gf_mx_v(gctx->mx);}static GF_Err GAPI_SetFullScreen(GF_VideoOutput *dr, Bool bOn, u32 *outWidth, u32 *outHeight){ GF_Err e; GAPICTX(dr); if (!gctx) return GF_BAD_PARAM; if (bOn == gctx->fullscreen) return GF_OK;#ifdef GPAC_USE_OGL_ES if (gctx->is_3D) { gctx->fullscreen = bOn; return GAPI_SetupOGL_ES(dr); }#endif gf_mx_p(gctx->mx); GAPI_ReleaseObjects(gctx); GXCloseDisplay(); e = GF_OK; if (bOn) { if (!GXOpenDisplay(GetParent(gctx->hWnd), GX_FULLSCREEN)) { GXOpenDisplay(gctx->hWnd, 0L); gctx->fullscreen = 0; e = GF_IO_ERR; } else { gctx->fullscreen = 1; } } else { GXOpenDisplay(gctx->hWnd, 0L); gctx->fullscreen = 0; } is_landscape = 0; if (!e) { if (gctx->fullscreen) { gctx->backup_w = *outWidth; gctx->backup_h = *outHeight; if ((gctx->bb_width > gctx->bb_height) && (gctx->screen_w > gctx->screen_h)) is_landscape = 0; else if ((gctx->bb_width < gctx->bb_height) && (gctx->screen_w < gctx->screen_h)) is_landscape = 0; else is_landscape = 1; if (is_landscape) { gctx->fs_w = gctx->screen_h; gctx->fs_h = gctx->screen_w; } else { gctx->fs_w = gctx->screen_w; gctx->fs_h = gctx->screen_h; } *outWidth = gctx->fs_w; *outHeight = gctx->fs_h; } else { *outWidth = gctx->backup_w; *outHeight = gctx->backup_h; } e = GAPI_InitBackBuffer(dr, *outWidth, *outHeight); } gf_mx_v(gctx->mx); return e;}GF_Err GAPI_ClearFS(GAPIPriv *gctx, unsigned char *ptr, s32 x_pitch, s32 y_pitch){ s32 i, j; gf_mx_p(gctx->mx); if (gctx->BPP==3) { for (i=0; i< (s32)gctx->fs_h; i++) { unsigned char *_ptr = ptr + i*y_pitch; for (j=0; j<(s32)gctx->fs_w; j++) { _ptr[0] = _ptr[1] = _ptr[2] = 0; _ptr += x_pitch; } } } else { for (i=0; i<(s32)gctx->fs_h; i++) { unsigned char *_ptr = ptr + i*y_pitch; for (j=0; j<(s32)gctx->fs_w; j++) { * ((unsigned short *)_ptr) = 0; _ptr += x_pitch; } } } gf_mx_v(gctx->mx); return GF_OK;}static GF_Err GAPI_FlipBackBuffer(GF_VideoOutput *dr){ GF_VideoSurface src, dst; unsigned char *ptr; GAPICTX(dr); s32 pitch_y = gctx->y_pitch; s32 pitch_x = gctx->x_pitch; if (!gctx || !gctx->gx_mode) return GF_BAD_PARAM; gf_mx_p(gctx->mx); /*get a pointer to video memory*/ ptr = (unsigned char *) GXBeginDraw(); if (!ptr) { gf_mx_v(gctx->mx); return GF_IO_ERR; } src.video_buffer = gctx->backbuffer; src.width = gctx->bb_width; src.height = gctx->bb_height; src.pitch = gctx->bb_pitch; src.pixel_format = gctx->pixel_format; src.is_hardware_memory = 0; dst.width = gctx->dst_blt.w; dst.height = gctx->dst_blt.h; dst.pixel_format = gctx->pixel_format; dst.is_hardware_memory = 1; if (gctx->fullscreen) { if (is_landscape) { if (gctx->y_pitch>0) { pitch_x = -gctx->y_pitch; /*start of frame-buffer is top-left corner*/ if (gctx->x_pitch>0) { ptr += gctx->screen_h * gctx->y_pitch; pitch_y = gctx->x_pitch; } /*start of frame-buffer is top-right corner*/ else { ptr += gctx->screen_h * gctx->y_pitch + gctx->screen_w * gctx->x_pitch; pitch_y = -gctx->x_pitch; } } else { pitch_x = gctx->y_pitch; /*start of frame-buffer is bottom-left corner*/ if (gctx->x_pitch>0) { pitch_y = gctx->x_pitch; } /*start of frame-buffer is bottom-right corner*/ else { ptr += gctx->screen_w * gctx->x_pitch; pitch_y = gctx->x_pitch; } } } if (gctx->erase_dest) { gctx->erase_dest = 0; GAPI_ClearFS(gctx, ptr, pitch_x, pitch_y); } } else { gctx->dst_blt.x += gctx->off_x; gctx->dst_blt.y += gctx->off_y; } ptr += gctx->dst_blt.x * pitch_x + pitch_y * gctx->dst_blt.y; dst.video_buffer = (char*)ptr; dst.pitch = pitch_y; gf_stretch_bits(&dst, &src, NULL, NULL, pitch_x, 0xFF, 0, NULL, NULL); GXEndDraw(); gf_mx_v(gctx->mx); return GF_OK;}static GF_Err GAPI_Flush(GF_VideoOutput *dr, GF_Window *dest){ GF_Err e; GAPICTX(dr); if (!gctx) return GF_BAD_PARAM; gf_mx_p(gctx->mx); #ifdef GPAC_USE_OGL_ES if (gctx->is_3D) { if (gctx->fullscreen && gctx->surface && gctx->egldpy) { if (gctx->erase_dest) { InvalidateRect(gctx->hWnd, NULL, TRUE); gctx->erase_dest = 0; } eglSwapBuffers(gctx->egldpy, gctx->surface); } else { InvalidateRect(gctx->hWnd, NULL, gctx->erase_dest); gctx->erase_dest = 0; } gf_mx_v(gctx->mx); return GF_OK; }#endif e = GF_OK; if (gctx->backbuffer) { if (dest) { gctx->dst_blt = *dest; } else { assert(0); gctx->dst_blt.x = gctx->dst_blt.y = 0; gctx->dst_blt.w = gctx->bb_width; gctx->dst_blt.h = gctx->bb_height; } if (gctx->gx_mode) { if (!gctx->fullscreen && gctx->erase_dest) { InvalidateRect(gctx->hWnd, NULL, TRUE); gctx->erase_dest = 0; } e = GAPI_FlipBackBuffer(dr); } else { InvalidateRect(gctx->hWnd, NULL, gctx->erase_dest); gctx->erase_dest = 0; } } gf_mx_v(gctx->mx); return e;}static GF_Err GAPI_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt){ GAPICTX(dr); if (!evt) return GF_OK; switch (evt->type) { case GF_EVENT_SHOWHIDE: if (gctx->hWnd) ShowWindow(gctx->hWnd, evt->show.show_type ? SW_SHOW : SW_HIDE); break; case GF_EVENT_SIZE: /*nothing to do since we don't own the window*/ break; case GF_EVENT_VIDEO_SETUP:#ifdef GPAC_USE_OGL_ES if (gctx->is_3D) return GAPI_SetupOGL_ES(the_video_driver);#endif return GAPI_InitBackBuffer(dr, evt->size.width, evt->size.height); } return GF_OK;}static GF_Err GAPI_InitBackBuffer(GF_VideoOutput *dr, u32 VideoWidth, u32 VideoHeight){ GAPICTX(dr); if (!gctx || !VideoWidth || !VideoHeight) return GF_BAD_PARAM; gf_mx_p(gctx->mx); GAPI_ReleaseObjects(gctx); gctx->bb_size = VideoWidth * VideoHeight * gctx->BPP; gctx->bb_width = VideoWidth; gctx->bb_height = VideoHeight; gctx->bb_pitch = VideoWidth * gctx->BPP; if (gctx->force_gx || gctx->fullscreen) { gctx->backbuffer = (char *) malloc(sizeof(unsigned char) * gctx->bb_size); gctx->gx_mode = 1; } else { HDC dc = GetDC(gctx->hWnd); createPixmap(gctx, dc, 0); ::ReleaseDC(gctx->hWnd, dc); gctx->gx_mode = 0; } RECT rc; GetWindowRect(gctx->hWnd, &rc); gctx->off_x = rc.left; gctx->off_y = rc.top; gctx->erase_dest = 1; gf_mx_v(gctx->mx); return GF_OK;}static GF_Err GAPI_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *vi, Bool do_lock){ GAPICTX(dr); if (do_lock) { if (!vi) return GF_BAD_PARAM; vi->width = gctx->bb_width; vi->height = gctx->bb_height; vi->pitch = gctx->bb_pitch; vi->pixel_format = gctx->pixel_format; vi->video_buffer = gctx->backbuffer; vi->is_hardware_memory = 0; } return GF_OK;}static void *NewGAPIVideoOutput(){ GAPIPriv *priv; GF_VideoOutput *driv = (GF_VideoOutput *) malloc(sizeof(GF_VideoOutput)); memset(driv, 0, sizeof(GF_VideoOutput)); GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "GAPI Video Output", "gpac distribution") priv = (GAPIPriv *) malloc(sizeof(GAPIPriv)); memset(priv, 0, sizeof(GAPIPriv)); priv->mx = gf_mx_new(); driv->opaque = priv; priv->force_gx = 0; /*alpha and keying to do*/ driv->hw_caps = GF_VIDEO_HW_CAN_ROTATE;#ifdef GPAC_USE_OGL_ES driv->hw_caps = GF_VIDEO_HW_HAS_OPENGL;#endif driv->Setup = GAPI_Setup; driv->Shutdown = GAPI_Shutdown; driv->Flush = GAPI_Flush; driv->ProcessEvent = GAPI_ProcessEvent; driv->Blit = NULL; driv->LockBackBuffer = GAPI_LockBackBuffer; driv->SetFullScreen = GAPI_SetFullScreen; return (void *)driv;}static void DeleteVideoOutput(void *ifce){ GF_VideoOutput *driv = (GF_VideoOutput *) ifce; GAPICTX(driv); GAPI_Shutdown(driv); gf_mx_del(gctx->mx); free(gctx); free(driv);}/*interface query*/Bool QueryInterface(u32 InterfaceType){ if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return 1; return 0;}/*interface create*/GF_BaseInterface *LoadInterface(u32 InterfaceType){ if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return (GF_BaseInterface *) NewGAPIVideoOutput(); return NULL;}/*interface destroy*/void ShutdownInterface(GF_BaseInterface *ifce){ GF_VideoOutput *dd = (GF_VideoOutput *)ifce; switch (dd->InterfaceType) { case GF_VIDEO_OUTPUT_INTERFACE: DeleteVideoOutput(dd); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -