📄 agl_drv.c
字号:
/*
*
* INTEL CORPORATION PROPRIETARY INFORMATION
* This software is supplied under the terms of a license agreement or
* nondisclosure agreement with Intel Corporation and may not be copied
* or disclosed except in accordance with the terms of that agreement.
* Copyright(c) 2001-2006 Intel Corporation. All Rights Reserved.
*
*/
#include <umc_defs.h>
#ifdef UMC_ENABLE_AGL_VIDEO_RENDER
#include "agl_drv.h"
#include <pthread.h>
#include <stdio.h>
#include <ippi.h>
#include <ipps.h>
#include <Carbon/Carbon.h>
/* -------------------------------------------------------------------------- */
#define MODULE "AGL(video driver)"
#define FUNCTION "<Undefined Function>"
#define ERR_STRING(msg) VIDEO_DRV_ERR_STRING(MODULE, FUNCTION, msg)
#define ERR_SET(err, msg) VIDEO_DRV_ERR_SET (MODULE, err, FUNCTION, msg)
#define WRN_SET(err, msg) VIDEO_DRV_WRN_SET (MODULE, err, FUNCTION, msg)
#define DBG_SET(msg) VIDEO_DRV_DBG_SET (MODULE, FUNCTION, msg)
/* -------------------------------------------------------------------------- */
/* Name: INTERPOLATION_TYPE.
*
* Purpose:
* Define interpolation type for frames resizing (used ippiResize).
*/
#define UMC_AGL_INTER_TYPE IPPI_INTER_NN
/* -------------------------------------------------------------------------- */
const VideoDrvSpec AGLVideoDrvSpec =
{
VM_STRING(MODULE),
VideoDrvFalse,
VideoDrvVideoMemInternal | VideoDrvVideoMemExternal,
umc_agl_Init,
umc_agl_Close,
umc_vdrv_CreateBuffers,
umc_vdrv_FreeBuffers,
NULL,
NULL,
NULL,
NULL,
umc_agl_RenderFrame,
umc_agl_SetVideoMode,
umc_agl_GetWindow,
umc_agl_RunEventLoop
};
/* -------------------------------------------------------------------------- */
/* Name: umc_agl_mutex.
*
* Purpose:
* 1. This global variable is used to permit multythreading calls of
* umc_agl_Init function. Without this mutex applications failed on calling
* Carbon function CreateNewWindow. For other information see bugzilla,
* bug #3720.
* 2. This global variable is used to permit multythreading calls of
* umc_agl_RunEventLoop.
*/
static pthread_mutex_t umc_agl_mutex = PTHREAD_MUTEX_INITIALIZER;
/* -------------------------------------------------------------------------- */
/* Name: umc_agl_GetAvailableRect.
*
* Purpose:
* Modifies <src_rect> if it can't be displayed on the screen.
*
* Parameters:
* src_rect - source rectangle;
* dst_rect - destination rectangle.
*/
vm_status umc_agl_GetAvailableRect(const VideoDrvRect* src_rect, Rect* dst_rect)
{
#undef FUNCTION
#define FUNCTION "umc_agl_GetAvailableRect"
vm_status result = VM_OK;
Rect disp_rect;
DBG_SET("+");
if (VM_OK == result)
{
if ((NULL == src_rect) || (NULL == dst_rect))
{
ERR_SET(VM_NULL_PTR, "null ptr");
}
}
if (VM_OK == result)
{
/* Getting available rectangle from the current graphics device. */
if (noErr != GetAvailableWindowPositioningBounds(GetGDevice(), &disp_rect))
ERR_SET(VM_OPERATION_FAILED, "GetAvailableWindowPositioningBounds");
}
if (VM_OK == result)
{
dst_rect->left = src_rect->x;
dst_rect->top = src_rect->y;
dst_rect->right = dst_rect->left + src_rect->w;
dst_rect->bottom = dst_rect->top + src_rect->h;
/* Modifying of the source rectangle (if needed). */
if (dst_rect->left < disp_rect.left) dst_rect->left = disp_rect.left;
/* 2 - for window title region. */
if (dst_rect->top < 2*disp_rect.top) dst_rect->top = 2*disp_rect.top;
if (dst_rect->right > disp_rect.right) dst_rect->right = disp_rect.right;
if (dst_rect->bottom > disp_rect.bottom) dst_rect->bottom = disp_rect.bottom;
}
DBG_SET("-");
}
/* -------------------------------------------------------------------------- */
/* Name: umc_agl_WindowEventHandler.
*
* Purpose:
* Handle windows events.
*
* Parameters:
* See MacOS help references for list and description of parameters for this
* function.
*/
OSStatus umc_agl_WindowEventHandler(EventHandlerCallRef inCallRef,
EventRef inEvent,
void *inUserData)
{
#undef FUNCTION
#define FUNCTION "umc_agl_WindowEventHandler"
OSStatus result = noErr;
VideoDriver* driver = (VideoDriver*)inUserData;
UInt32 eventKind = GetEventKind(inEvent);
VideoDrvRect rect;
Rect bounds_rect;
DBG_SET("+");
switch (eventKind)
{
case kEventWindowBoundsChanged:
result = GetEventParameter(inEvent,
kEventParamCurrentBounds, typeQDRectangle,
NULL, sizeof(Rect), NULL, &bounds_rect);
if (noErr == result)
{
rect.x = bounds_rect.left;
rect.w = bounds_rect.right - bounds_rect.left;
rect.y = bounds_rect.top;
rect.h = bounds_rect.bottom - bounds_rect.top;
umc_agl_SetVideoMode(driver, &rect, VideoDrvOrdinary);
}
break;
default:
CallNextEventHandler(inCallRef, inEvent); /* Standard handler call. */
break;
}
DBG_SET("-");
return result;
}
/* -------------------------------------------------------------------------- */
/* vm_status */
VIDEO_DRV_INIT_FUNC (umc_agl_Init, driver, params)
{
#undef FUNCTION
#define FUNCTION "umc_agl_Init"
vm_status result = VM_OK;
AGLDrv* drv = (AGLDrv*)ippsMalloc_8u(sizeof(AGLDrv));
AGLVideoDrvParams* pParams = (AGLVideoDrvParams*) params;
WindowAttributes windowAttr;
VideoDrvRect obtainedRect;
EventTypeSpec windowEvents[] =
{
{kEventClassWindow, kEventWindowBoundsChanged}
};
ProcessSerialNumber frProcess, curProcess;
Boolean sameProcess;
DBG_SET("+");
pthread_mutex_lock(&umc_agl_mutex);
if (VM_OK == result)
{
if (drv == NULL)
{
ERR_SET(VM_OPERATION_FAILED, "memory allocation");
}
}
if (VM_OK == result)
{
if ((NULL == driver) || (NULL == pParams))
{
ERR_SET(VM_NULL_PTR, "null ptr");
}
}
if (VM_OK == result)
{
driver->m_pDrv = drv;
driver->img_width = pParams->common.img_width;
driver->img_height = pParams->common.img_height;
driver->m_VideoMemType = VideoDrvVideoMemInternal;
ippsZero_8u((Ipp8u*)&(driver->m_VideoMemInfo), sizeof(VideoDrvVideoMemInfo));
ippsCopy_8u((const Ipp8u*)&AGLVideoDrvSpec, (Ipp8u*)&(driver->m_DrvSpec), sizeof(VideoDrvSpec));
drv->screen_buffer = NULL;
drv->agl_ctx = NULL;
drv->win = NULL;
umc_agl_GetAvailableRect(&(pParams->common.win_rect),&(drv->win_rect));
}
if (VM_OK == result)
{
vm_mutex_set_invalid(&(drv->mtx_resize));
result = vm_mutex_init(&(drv->mtx_resize));
}
if (VM_OK == result)
{
windowAttr = kWindowStandardDocumentAttributes |
kWindowStandardHandlerAttribute |
kWindowLiveResizeAttribute |
kWindowCompositingAttribute;
/* Creating a window. */
if (noErr != CreateNewWindow(kDocumentWindowClass,
windowAttr,
&(drv->win_rect),
&(drv->win)))
{
ERR_SET(VM_OPERATION_FAILED, "CreateNewWindow");
}
}
if (VM_OK == result)
{
/* Trying to install standard window event handler. */
if (noErr != InstallStandardEventHandler(GetWindowEventTarget(drv->win)))
{
WRN_SET(VM_OK, "InstallStandardEventHandler");
}
/* Trying to install window event handler. */
if (noErr != InstallWindowEventHandler(drv->win,
NewEventHandlerUPP(umc_agl_WindowEventHandler),
GetEventTypeCount(windowEvents),
windowEvents,
driver,
&(drv->win_handler)))
{
WRN_SET(VM_OK, "InstallWindowEventHandler");
}
}
if (VM_OK == result)
{
ShowWindow(drv->win);
}
if (VM_OK == result)
{
/* Choosing pixel format */
GLint attrib[] = {AGL_RGBA, AGL_DOUBLEBUFFER, AGL_NONE};
drv->agl_fmt = aglChoosePixelFormat(NULL, 0, attrib);
if (AGL_NO_ERROR != aglGetError())
{
ERR_SET(VM_OPERATION_FAILED, "aglChoosePixelFormat");
}
drv->agl_ctx = NULL;
}
if (result == VM_OK)
{
obtainedRect.x = drv->win_rect.left;
obtainedRect.y = drv->win_rect.top;
obtainedRect.w = drv->win_rect.right - drv->win_rect.left;
obtainedRect.h = drv->win_rect.bottom - drv->win_rect.top;
result = umc_agl_SetVideoMode(driver, &obtainedRect, VideoDrvOrdinary);
}
if (VM_OK == result)
{
/* Driver was initialized successfully. Transforming application to
* foreground one.
*/
if ((noErr == GetFrontProcess(&frProcess)) &&
(noErr == GetCurrentProcess(&curProcess)))
{
if ((noErr == SameProcess(&frProcess, &curProcess, &sameProcess)) &&
(false == sameProcess))
{
TransformProcessType(&curProcess,
kProcessTransformToForegroundApplication);
}
SetFrontProcessWithOptions(&curProcess,kSetFrontProcessFrontWindowOnly);
}
}
else
{
/* Driver initialization failed. Releasing memory. */
if (drv != NULL) { ippsFree(drv); driver->m_pDrv = NULL; }
}
pthread_mutex_unlock(&umc_agl_mutex);
DBG_SET("-");
return result;
}
/* -------------------------------------------------------------------------- */
/* vm_status */
VIDEO_DRV_SET_VIDEO_MODE_FUNC(umc_agl_SetVideoMode, driver, rect, mode)
{
#undef FUNCTION
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -