📄 agl_drv.c
字号:
#define FUNCTION "umc_agl_SetVideoMode"
vm_status result = VM_OK;
AGLDrv* drv = (AGLDrv*)((NULL != driver)? driver->m_pDrv: NULL);
VideoDrvRect src_rect;
Rect title_rect;
Ipp32s w, h;
DBG_SET("+");
if ((NULL == drv) || (NULL == rect))
{
ERR_SET(VM_NULL_PTR, "null ptr");
}
vm_mutex_lock(&(drv->mtx_resize)); /* Preventing rendering. */
if (VM_OK == result)
{
memcpy(&src_rect, rect, sizeof(VideoDrvRect));
/* Sizes corrections:
* - width alignment at 8: needed for resizing using ippiResize().
*/
src_rect.w &= ~7;
/* Resizing window. */
umc_agl_GetAvailableRect(&src_rect, &(drv->win_rect));
w = drv->win_rect.right - drv->win_rect.left;
h = drv->win_rect.bottom - drv->win_rect.top;
MoveWindow(drv->win, drv->win_rect.left, drv->win_rect.top, true);
SizeWindow(drv->win, w, h, true);
/* Resizing of the screen buffer. */
if (NULL != drv->screen_buffer) ippsFree(drv->screen_buffer);
if ((w == driver->img_width) && (h == driver->img_height))
drv->screen_buffer = NULL; /* Some optimization. */
else
drv->screen_buffer = ippsMalloc_8u(w*h*3);
/* Changing AGL context.
*
* Remark: this is done because aglUpdateContext doesn't work properly.
*/
if ((NULL != drv->agl_ctx) && (GL_TRUE != aglDestroyContext(drv->agl_ctx)))
{
WRN_SET(VM_OK, "aglDestroyContext");
}
if (VM_OK == result)
{
/* Creating an AGL context */
drv->agl_ctx = aglCreateContext(drv->agl_fmt, NULL);
if(AGL_NO_ERROR != aglGetError())
{
ERR_SET(VM_OPERATION_FAILED, "aglCreateContext");
}
}
}
vm_mutex_unlock(&(drv->mtx_resize));
DBG_SET("-");
return result;
}
/* -------------------------------------------------------------------------- */
/* void */
VIDEO_DRV_CLOSE_FUNC(umc_agl_Close, driver)
{
#undef FUNCTION
#define FUNCTION "umc_agl_Close"
vm_status result = VM_OK;
AGLDrv* drv = (AGLDrv*)((NULL != driver)? driver->m_pDrv: NULL);
DBG_SET("+");
if (NULL == drv)
{
ERR_SET(VM_NULL_PTR, "null ptr");
}
if (VM_OK == result)
{
if (vm_mutex_is_valid(&(drv->mtx_resize)))
{
vm_mutex_unlock (&(drv->mtx_resize));
vm_mutex_destroy(&(drv->mtx_resize));
}
/* Destroy AGL rendering context */
aglDestroyContext(drv->agl_ctx);
/* Free resources used by pixel format */
aglDestroyPixelFormat(drv->agl_fmt);
if (NULL != drv->screen_buffer)
{
ippsFree(drv->screen_buffer);
drv->screen_buffer = NULL;
}
ippsFree(drv);
driver->m_pDrv = NULL;
}
DBG_SET("-");
return;
}
/* -------------------------------------------------------------------------- */
/* Name: umc_agl_SetWorkRegion.
*
* Purpose:
* Set clip (output) rectangle for rendering.
*
* Parameters:
* driver - pointer to the driver specification;
* rect - user specified rectangle in the window for output (can be NULL).
*/
vm_status umc_agl_SetWorkRegion(VideoDriver *driver, VideoDrvRect *rect)
{
#undef FUNCTION
#define FUNCTION "umc_agl_SetWorkRegion"
vm_status result = VM_OK;
AGLDrv* drv = (AGLDrv*)((NULL != driver)? driver->m_pDrv: NULL);
RgnHandle workRgn = NewRgn(), userRgn = NewRgn();
Rect rectWork;
DBG_SET("+");
if (NULL == drv)
{
ERR_SET(VM_NULL_PTR, "null ptr");
}
if (VM_OK == result)
{
/* Attaching the context to the window and setting context current. */
if (GL_TRUE != aglSetDrawable(drv->agl_ctx, GetWindowPort(drv->win)))
{
ERR_SET(VM_OK, "aglSetDrawable");
}
}
if (VM_OK == result)
{
/* Setting work region. */
if (noErr != GetWindowRegion(drv->win, kWindowContentRgn, workRgn))
{
ERR_SET(VM_OK, "GetWindowRegion");
}
}
if (VM_OK == result)
{
/* Defining work region in window's local coordinates. */
GetRegionBounds(workRgn, &rectWork);
OffsetRgn(workRgn, -rectWork.left, -rectWork.top);
if (NULL != rect)
{
/* Defining user specified region in window's local coordinates. */
SetEmptyRgn(userRgn);
OpenRgn();
MoveTo(rect->x, rect->y);
LineTo(rect->x + rect->w, rect->y);
LineTo(rect->x + rect->w, rect->y + rect->h);
LineTo(rect->x, rect->y+rect->h);
CloseRgn(userRgn);
/* Resetting work region as intersection of previous work and user's
* regions.
*/
SectRgn(workRgn, userRgn, workRgn);
}
aglSetInteger(drv->agl_ctx, AGL_CLIP_REGION, (const GLint*)workRgn);
aglEnable(drv->agl_ctx, AGL_CLIP_REGION);
}
DisposeRgn(workRgn);
DisposeRgn(userRgn);
DBG_SET("-");
return result;
}
/* -------------------------------------------------------------------------- */
/* vm_status */
VIDEO_DRV_RENDER_FRAME_FUNC (umc_agl_RenderFrame, driver, frame, rect)
{
#undef FUNCTION
#define FUNCTION "umc_agl_RenderFrame"
vm_status result = VM_OK;
AGLDrv* drv = (AGLDrv*)((NULL != driver)? driver->m_pDrv: NULL);
GLboolean render_fl = GL_TRUE;
IppiSize srcSize, dstSize;
IppiRect srcRect;
Ipp32s srcStep, dstStep;
Ipp8u* buffer = NULL;
DBG_SET("+");
if (NULL == drv)
{
ERR_SET(VM_NULL_PTR, "null ptr");
}
vm_mutex_lock (&(drv->mtx_resize)); /* Preventing resize. */
if (VM_OK == result)
{
if (VM_OK != umc_agl_SetWorkRegion(driver, rect))
{
render_fl = GL_FALSE;
WRN_SET(VM_OK, "umc_agl_SetWorkRegion");
}
/* Setting the OpenGL current context. */
if (GL_TRUE != aglSetCurrentContext(drv->agl_ctx))
{
render_fl = GL_FALSE;
WRN_SET(VM_OK, "aglSetCurrentContext");
}
if (render_fl == GL_TRUE)
{
/* Setting destination image sizes. */
dstSize.width = drv->win_rect.right - drv->win_rect.left;
dstSize.height = drv->win_rect.bottom - drv->win_rect.top;
if (NULL != drv->screen_buffer)
{
buffer = drv->screen_buffer;
/* Preparing for resize. */
srcSize.width = driver->img_width;
srcSize.height = driver->img_height;
srcRect.x = 0;
srcRect.y = 0;
srcRect.width = srcSize.width;
srcRect.height = srcSize.height;
srcStep = 3*(srcSize.width);
dstStep = 3*(dstSize.width);
/* Resizing. */
if (ippStsNoErr != ippiResize_8u_C3R(frame, srcSize, srcStep, srcRect,
drv->screen_buffer, dstStep, dstSize,
(Ipp64f)dstSize.width / (Ipp64f)srcRect.width,
(Ipp64f)dstSize.height / (Ipp64f)srcRect.height,
UMC_AGL_INTER_TYPE))
ERR_SET(VM_OPERATION_FAILED, "ippiResize_8u_C3R");
}
else buffer = frame;
/* Microsoft to Direct buffer conversion. */
/* Horizontal and Vertical Flip. */
glRasterPos2f(-1, 1);
glPixelZoom(1, -1);
glEnable(GL_ALPHA_TEST);
glClearColor(1,1,1,0);
glClear(GL_COLOR_BUFFER_BIT);
glDrawPixels(dstSize.width,
dstSize.height,
GL_BGR,
GL_UNSIGNED_BYTE,
buffer);
aglSwapBuffers(drv->agl_ctx);
}
}
vm_mutex_unlock (&(drv->mtx_resize));
DBG_SET("-");
return result;
}
/* -------------------------------------------------------------------------- */
/* void* */
VIDEO_DRV_GET_WINDOW_FUNC(umc_agl_GetWindow, driver)
{
#undef FUNCTION
#define FUNCTION "umc_agl_GetWindow"
void* win;
AGLDrv* drv = (AGLDrv*)((NULL != driver)? driver->m_pDrv: NULL);
DBG_SET("+");
if (NULL == drv)
{
win = NULL;
DBG_SET("null ptr");
}
else
{
win = drv->win;
}
DBG_SET("-");
return win;
}
/* -------------------------------------------------------------------------- */
/* vm_status */
VIDEO_DRV_RUN_EVENT_LOOP_FUNC(umc_agl_RunEventLoop, driver)
{
#undef FUNCTION
#define FUNCTION "umc_agl_RunEventLoop"
vm_status result = VM_OK;
AGLDrv* drv = (AGLDrv*)((NULL != driver)? driver->m_pDrv: NULL);
EventRef theEvent;
EventTargetRef theTarget;
OSStatus theErr;
DBG_SET("+");
if (NULL == drv)
{
ERR_SET(VM_NULL_PTR, "null ptr");
}
pthread_mutex_lock(&umc_agl_mutex);
if (VM_OK == result)
{
do
{
/* Getting all events from queue. */
theTarget = GetEventDispatcherTarget();
theErr = ReceiveNextEvent(0, NULL, kEventDurationNoWait, true, &theEvent);
if ((noErr == theErr) && (NULL != theEvent))
{
SendEventToEventTarget(theEvent, theTarget);
ReleaseEvent(theEvent);
}
else break;
} while (1);
}
pthread_mutex_unlock(&umc_agl_mutex);
DBG_SET("-");
return result;
}
#endif /* defined(UMC_ENABLE_AGL_VIDEO_RENDER) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -