Code:
procedure TBroadcomHack.InitEGL(var eDisplay: EGLDisplay;
var eConfig: EGLConfig; var eSurface: EGLSurface; var eContext: EGLContext;
var assumedpfd: TAssumedPFD);
var
hr: integer;
num_config: EGLint;
Attr: array[0..10] of EGLint = (
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE);
CtxAttr:array[0..3] of EGLint = (
EGL_CONTEXT_CLIENT_VERSION,2,
EGL_NONE,
EGL_NONE);
dispman_alpha: VC_DISPMANX_ALPHA_T;
scale: float;
w, h: longint;
begin
try
if Mother^.Debug.Verbose then AddLog(' ..Raspberry Pi detected, creating a Broadcom specific surface...');
// Tested on RPi2, got glitches and flickering at sizes close to 1920 x 1080
// - presumably, buffers too large to fit in RAM or something
// Have to limit.
// P.S. Changed to making the hardware surface smaller, it got hardware scaling!
w:= min(VIRTUAL_RES_WIDTH, Mother^.Display.WindowClientRect.Width);
h:= min(VIRTUAL_RES_HEIGHT_MAX, Mother^.Display.WindowClientRect.Height);
scale:= min(w / Mother^.Display.WindowClientRect.Width, h / Mother^.Display.WindowClientRect.Height);
AdjustRect(myrect);
if Mother^.Debug.Verbose then AddLog(' ..Surface rect calculated as %0',[RectToStr(myrect)]);
Mother^.Display.ClientRect.Width:= trunc(scale * myrect.width);
Mother^.Display.ClientRect.Height:= trunc(scale * myrect.height);
if Mother^.Debug.Verbose then
AddLog(' .. Hardware surface size %0x%1 (scale %2)',
[Mother^.Display.ClientRect.Width, Mother^.Display.ClientRect.Height, scale]);
dst_rect.x:= myrect.left;
dst_rect.y:= myrect.top;
dst_rect.width:= myrect.width;
dst_rect.height:= myrect.height;
src_rect.x:= 0;
src_rect.y:= 0;
src_rect.width:= Mother^.Display.ClientRect.Width shl 16;
src_rect.height:= Mother^.Display.ClientRect.Height shl 16;
dispman_alpha.flags:= DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
dispman_alpha.opacity:= $FF;
dispman_alpha.mask:= 0;
dx_dispman_update:= vc_dispmanx_update_start( 0 );
dx_dispman_element:= vc_dispmanx_element_add (
dx_dispman_update, dx_display_handle,
0{layer}, @dst_rect, 0{src}, @src_rect,
DISPMANX_PROTECTION_NONE,
@dispman_alpha,//nil{alpha},
nil{clamp}, 0{transform}
);
f_nativewindow.element:= dx_dispman_element;
f_nativewindow.width:= myrect.width;
f_nativewindow.height:= myrect.height;
vc_dispmanx_update_submit_sync( dx_dispman_update );
f_has_surface:= true;
// get an EGL display connection
eDisplay:= eglGetDisplay(EGL_DEFAULT_DISPLAY);
if eDisplay = EGL_NO_DISPLAY
then Die('eglGetDisplay() returned EGL_NO_DISPLAY');
if Mother^.Debug.Verbose
then AddLog(' ..display %0',[eDisplay]);
// initialize the EGL display connection
if 0 = eglInitialize( eDisplay, @f_vmajo, @f_vmino )
then Die('eglInitialize() failed: ' + EGlErrorCodeToString(eglGetError()));
if Mother^.Debug.Verbose
then AddLog(' ..EGL version %0.%1',[f_vmajo, f_vmino]);
// get an appropriate EGL frame buffer configuration
if 0 = eglGetConfigs(eDisplay, nil, 0, @num_config)
then Die('eglGetConfigs() faled');
if Mother^.Debug.Verbose
then AddLog(' ..#EGL configs %0',[num_config]);
hr:= eglChooseConfig(eDisplay, @Attr[0], @eConfig, 1, @num_config);
if (EGL_FALSE = hr) or (num_config <> 1)
then Die('eglChooseConfig() faled');
assumedpfd.r:= Attr[1];
assumedpfd.g:= Attr[3];
assumedpfd.b:= Attr[5];
assumedpfd.a:= Attr[7];
assumedpfd.depth:= 0;
assumedpfd.rect:= myrect;
assumedpfd.rect.width:= Mother^.Display.ClientRect.Width;
assumedpfd.rect.height:= Mother^.Display.ClientRect.Height;
// create an EGL rendering context
eContext:= eglCreateContext(eDisplay, eConfig, EGL_NO_CONTEXT, @CtxAttr[0]);
if eContext = EGL_NO_CONTEXT
then Die('eglCreateContext() returned EGL_NO_CONTEXT');
CheckEGlError();
if Mother^.Debug.Verbose then AddLog(' ..context %0',[eContext]);
// create an EGL window surface
eSurface:= eglCreateWindowSurface(eDisplay, eConfig,
ptruint(@f_nativewindow), //Dirty! native window type boils to TXID,
//but that's just a fance name for ptruint (see culong)
//So yes, X handles are opaque pointers too.
nil);
if eSurface = EGL_NO_SURFACE then Die(MI_ERROR_CANTINITOPENGL,['eglCreateWindowSurface() returned EGL_NO_SURFACE']);
CheckEGlError();
if Mother^.Debug.Verbose then AddLog(' ..surface %0',[eSurface]);
if 0 = eglGetConfigs(eDisplay, nil, 0, @num_config)
then Die(EGlErrorCodeToString(eglGetError()));
except
Die(RuEn(
'Не удалось поставить VideoCore костыль для специфичной EGL от Broadcom',
'Failed to start the VideoCore hack for the peculiar Broadcom EGL'
));
end;
end;
Bookmarks