forked from KolibriOS/kolibrios
sdk: new pixlib. Now with OpenGL taste.
git-svn-id: svn://kolibrios.org@5371 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
2d2c139857
commit
3287cff0b2
55
contrib/sdk/sources/pixlib-3/Makefile
Normal file
55
contrib/sdk/sources/pixlib-3/Makefile
Normal file
@ -0,0 +1,55 @@
|
||||
LIBRARY= pixlib3
|
||||
|
||||
CC = kos32-gcc
|
||||
AR = kos32-ar
|
||||
LD = kos32-ld
|
||||
STRIP = kos32-strip
|
||||
|
||||
ARFLAGS = crs
|
||||
CFLAGS = -U_Win32 -U_WIN32 -U__MINGW32__ -c -O2 -fno-ident -fomit-frame-pointer
|
||||
LDFLAGS:= -shared -s -nostdlib -Map px.map -T ../newlib/dll.lds --entry _DllStartup --image-base=0
|
||||
LDFLAGS+= --file-alignment 256
|
||||
|
||||
INCLUDES= -I. -I../newlib/libc/include
|
||||
|
||||
PXGL_INCLUDES= $(INCLUDES) -I../libdrm/intel -I../libdrm/include
|
||||
PXGL_INCLUDES+= -I ../Mesa/include -I../Mesa/src/gbm/main
|
||||
|
||||
LIBPATH:= -L../../lib -L/home/autobuild/tools/win32/mingw32/lib
|
||||
|
||||
LIBS:= -ldll -legl.dll -lGL.dll -lc.dll -lgcc
|
||||
#LIBS+= -ldrm.dll
|
||||
|
||||
DEFINES:= -DNDEBUG
|
||||
PXGL_DEFINES:= $(DEFINES) -D__unix__ -DMESA_EGL_NO_X11_HEADERS
|
||||
|
||||
SRC_PIXLIB = pixlib3.c
|
||||
SRC_PXGL = egl.c pxgl.c
|
||||
|
||||
OBJ_PIXLIB = $(patsubst %.c, %.o, $(SRC_PIXLIB))
|
||||
OBJ_PXGL = $(patsubst %.c, %.o, $(SRC_PXGL))
|
||||
|
||||
# targets
|
||||
|
||||
all: lib$(LIBRARY).a pixlib-gl.dll
|
||||
|
||||
lib$(LIBRARY).a: $(OBJ_PIXLIB) Makefile
|
||||
$(AR) $(ARFLAGS) lib$(LIBRARY).a $(OBJ_PIXLIB)
|
||||
mv -f lib$(LIBRARY).a ../../lib
|
||||
|
||||
pixlib-gl.dll: $(OBJ_PXGL) Makefile
|
||||
$(LD) $(LDFLAGS) $(PXFLAGS) $(LIBPATH) -o $@ $(OBJ_PXGL) $(LIBS)
|
||||
mv -f $@ ../../bin
|
||||
|
||||
pixlib3.o : pixlib3.c Makefile
|
||||
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
%.o : %.c Makefile
|
||||
$(CC) $(CFLAGS) $(PXGL_DEFINES) $(PXGL_INCLUDES) -o $@ $<
|
||||
|
||||
clean:
|
||||
-rm -f *.o
|
||||
|
||||
|
||||
|
||||
|
116
contrib/sdk/sources/pixlib-3/egl.c
Normal file
116
contrib/sdk/sources/pixlib-3/egl.c
Normal file
@ -0,0 +1,116 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <drm/i915_drm.h>
|
||||
#include <kos32sys.h>
|
||||
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#include "EGL/egl.h"
|
||||
#include "EGL/eglext.h"
|
||||
#include "GL/gl.h"
|
||||
#include "gbm.h"
|
||||
#include "pxgl.h"
|
||||
|
||||
static struct gbm_device *gbm;
|
||||
|
||||
static EGLConfig choose_config(EGLDisplay *dpy)
|
||||
{
|
||||
EGLConfig config = NULL;
|
||||
EGLint config_attribs[32];
|
||||
EGLint num_configs, i;
|
||||
|
||||
i = 0;
|
||||
config_attribs[i++] = EGL_RED_SIZE;
|
||||
config_attribs[i++] = 1;
|
||||
config_attribs[i++] = EGL_GREEN_SIZE;
|
||||
config_attribs[i++] = 1;
|
||||
config_attribs[i++] = EGL_BLUE_SIZE;
|
||||
config_attribs[i++] = 1;
|
||||
config_attribs[i++] = EGL_DEPTH_SIZE;
|
||||
config_attribs[i++] = 1;
|
||||
|
||||
config_attribs[i++] = EGL_SURFACE_TYPE;
|
||||
config_attribs[i++] = EGL_WINDOW_BIT;
|
||||
|
||||
config_attribs[i++] = EGL_RENDERABLE_TYPE;
|
||||
config_attribs[i++] = EGL_OPENGL_BIT;
|
||||
config_attribs[i] = EGL_NONE;
|
||||
|
||||
eglChooseConfig(dpy, config_attribs, &config, 1, &num_configs);
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
int egl_initialize(EGLDisplay *dpy, EGLConfig *config, EGLContext *context)
|
||||
{
|
||||
EGLint major, minor;
|
||||
int fd;
|
||||
|
||||
fd = get_service("DISPLAY");
|
||||
if(fd == 0)
|
||||
return -1;
|
||||
|
||||
gbm = gbm_create_device(fd);
|
||||
if( gbm == NULL)
|
||||
{
|
||||
DBG("failed to initialize GBM device\n");
|
||||
goto err_0;
|
||||
};
|
||||
|
||||
*dpy = eglGetDisplay(gbm);
|
||||
|
||||
if (!eglInitialize(*dpy, &major, &minor))
|
||||
{
|
||||
DBG("failed to initialize EGL display\n");
|
||||
goto err_1;
|
||||
};
|
||||
|
||||
DBG("EGL_VERSION = %s\n", eglQueryString(*dpy, EGL_VERSION));
|
||||
DBG("EGL_VENDOR = %s\n", eglQueryString(*dpy, EGL_VENDOR));
|
||||
DBG("EGL_EXTENSIONS = %s\n", eglQueryString(*dpy, EGL_EXTENSIONS));
|
||||
DBG("EGL_CLIENT_APIS = %s\n", eglQueryString(*dpy, EGL_CLIENT_APIS));
|
||||
|
||||
*config = choose_config(*dpy);
|
||||
if( *config == NULL)
|
||||
{
|
||||
DBG("failed to choose a config\n");
|
||||
goto err_2;
|
||||
};
|
||||
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
*context = eglCreateContext(*dpy, *config, EGL_NO_CONTEXT, NULL);
|
||||
if (context == NULL)
|
||||
{
|
||||
DBG("failed to create context\n");
|
||||
goto err_2;
|
||||
};
|
||||
|
||||
if (!eglMakeCurrent(*dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, *context))
|
||||
{
|
||||
DBG("failed to make context current");
|
||||
goto err_3;
|
||||
};
|
||||
|
||||
return 0;
|
||||
|
||||
err_3:
|
||||
eglDestroyContext(*dpy, *context);
|
||||
err_2:
|
||||
eglTerminate(*dpy);
|
||||
err_1:
|
||||
gbm_device_destroy(gbm);
|
||||
err_0:
|
||||
return -1;
|
||||
};
|
||||
|
||||
void egl_destroy(EGLDisplay dpy, EGLContext context)
|
||||
{
|
||||
eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglDestroyContext(dpy, context);
|
||||
eglTerminate(dpy);
|
||||
gbm_device_destroy(gbm);
|
||||
};
|
||||
|
18
contrib/sdk/sources/pixlib-3/pixdriver.h
Normal file
18
contrib/sdk/sources/pixlib-3/pixdriver.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef __PIXDRIVER_H__
|
||||
#define __PIXDRIVER_H__
|
||||
|
||||
struct pix_driver
|
||||
{
|
||||
uint32_t driver_caps;
|
||||
bitmap_t *(*create_bitmap)(uint32_t width, uint32_t height);
|
||||
int (*destroy_bitmap)(bitmap_t *bitmap);
|
||||
void *(*lock_bitmap)(bitmap_t *bitmap, uint32_t *pitch);
|
||||
int (*resize_bitmap)(bitmap_t *bitmap, uint32_t width, uint32_t height);
|
||||
int (*blit_bitmap)(bitmap_t * bitmap, int dst_x, int dst_y,
|
||||
uint32_t w, uint32_t h, int src_x, int src_y);
|
||||
int (*create_client)(int x, int y, uint32_t width, uint32_t height);
|
||||
int (*resize_client)(int x, int y, uint32_t width, uint32_t height);
|
||||
void (*fini)(void);
|
||||
};
|
||||
|
||||
#endif
|
17
contrib/sdk/sources/pixlib-3/pixlib.ver
Normal file
17
contrib/sdk/sources/pixlib-3/pixlib.ver
Normal file
@ -0,0 +1,17 @@
|
||||
LIBDRM {
|
||||
global: DllStartup;
|
||||
init_pixlib;
|
||||
done_pixlib;
|
||||
create_bitmap;
|
||||
resize_bitmap;
|
||||
destroy_bitmap;
|
||||
lock_bitmap;
|
||||
blit_bitmap;
|
||||
|
||||
local: __chkstk;
|
||||
__chkstk_ms;
|
||||
_alloca;
|
||||
__uxa_lock;
|
||||
_nm__tls_alloc;
|
||||
*;
|
||||
};
|
264
contrib/sdk/sources/pixlib-3/pixlib3.c
Normal file
264
contrib/sdk/sources/pixlib-3/pixlib3.c
Normal file
@ -0,0 +1,264 @@
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <stdbool.h>
|
||||
#include <kos32sys.h>
|
||||
|
||||
#include "pixlib3.h"
|
||||
#include "pixdriver.h"
|
||||
|
||||
#define DISPLAY_VERSION 0x0200 /* 2.00 */
|
||||
|
||||
#define SRV_GETVERSION 0
|
||||
#define SRV_GET_CAPS 3
|
||||
|
||||
|
||||
#define BUFFER_SIZE(n) ((n)*sizeof(uint32_t))
|
||||
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
|
||||
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
|
||||
|
||||
struct bitmap
|
||||
{
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t pitch;
|
||||
void *buffer;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
static uint32_t fd;
|
||||
static struct pix_driver *driver;
|
||||
|
||||
|
||||
static bitmap_t *sw_create_bitmap(uint32_t width, uint32_t height)
|
||||
{
|
||||
bitmap_t *bitmap;
|
||||
|
||||
bitmap = malloc(sizeof(bitmap_t));
|
||||
if(bitmap == NULL)
|
||||
goto err_0;
|
||||
|
||||
bitmap->width = width;
|
||||
bitmap->height = height;
|
||||
|
||||
bitmap->pitch = ALIGN(width * 4, 16);
|
||||
bitmap->size = ALIGN(bitmap->pitch * height, 4096);
|
||||
|
||||
bitmap->buffer = user_alloc(bitmap->size);
|
||||
if (bitmap->buffer == NULL)
|
||||
goto err_1;
|
||||
|
||||
printf("create bitmap: %p %dx%d buffer: %p\n",
|
||||
bitmap, bitmap->width, bitmap->height, bitmap->buffer);
|
||||
|
||||
return bitmap;
|
||||
|
||||
err_1:
|
||||
free(bitmap);
|
||||
err_0:
|
||||
return NULL;
|
||||
};
|
||||
|
||||
static int sw_destroy_bitmap(bitmap_t * bitmap)
|
||||
{
|
||||
user_free(bitmap->buffer);
|
||||
free(bitmap);
|
||||
return 0;
|
||||
};
|
||||
|
||||
static void *sw_lock_bitmap(bitmap_t *bitmap, uint32_t *pitch)
|
||||
{
|
||||
*pitch = bitmap->pitch;
|
||||
|
||||
return bitmap->buffer;
|
||||
};
|
||||
|
||||
static int sw_resize_bitmap(bitmap_t * bitmap, uint32_t width, uint32_t height)
|
||||
{
|
||||
uint32_t size;
|
||||
uint32_t pitch;
|
||||
|
||||
pitch = ALIGN(width * 4, 16);
|
||||
size = ALIGN(pitch * height, 4096);
|
||||
|
||||
if (size > bitmap->size)
|
||||
{
|
||||
bitmap->buffer = user_realloc(bitmap->buffer, size); /* grow buffer */
|
||||
if (bitmap->buffer == NULL)
|
||||
return -1;
|
||||
|
||||
bitmap->size = size;
|
||||
}
|
||||
else if (size < bitmap->size)
|
||||
user_unmap(bitmap->buffer, size, bitmap->size - size); /* unmap unused pages */
|
||||
|
||||
bitmap->width = width;
|
||||
bitmap->height = height;
|
||||
bitmap->pitch = pitch;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static int sw_blit(bitmap_t * bitmap, int dst_x, int dst_y,
|
||||
uint32_t w, uint32_t h, int src_x, int src_y)
|
||||
{
|
||||
struct blit_call bc;
|
||||
int ret;
|
||||
|
||||
bc.dstx = dst_x;
|
||||
bc.dsty = dst_y;
|
||||
bc.w = w;
|
||||
bc.h = h;
|
||||
bc.srcx = src_x;
|
||||
bc.srcy = src_y;
|
||||
bc.srcw = bitmap->width;
|
||||
bc.srch = bitmap->height;
|
||||
bc.stride = bitmap->pitch;
|
||||
bc.bitmap = bitmap->buffer;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"int $0x40":"=a"(ret):"a"(73), "b"(0x00),
|
||||
"c"(&bc):"memory");
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
static int sw_create_client(int x, int y, uint32_t width, uint32_t height)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
static int sw_resize_client(int x, int y, uint32_t width, uint32_t height)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
bitmap_t *pxCreateBitmap(uint32_t width, uint32_t height)
|
||||
{
|
||||
return driver->create_bitmap(width, height);
|
||||
};
|
||||
|
||||
int pxDestroyBitmap(bitmap_t *bitmap)
|
||||
{
|
||||
return driver->destroy_bitmap(bitmap);
|
||||
};
|
||||
|
||||
void *pxLockBitmap(bitmap_t *bitmap, uint32_t *pitch)
|
||||
{
|
||||
return driver->lock_bitmap(bitmap, pitch);
|
||||
};
|
||||
|
||||
int pxResizeBitmap(bitmap_t *bitmap, uint32_t width, uint32_t height)
|
||||
{
|
||||
return driver->resize_bitmap(bitmap, width, height);
|
||||
};
|
||||
|
||||
int pxBlitBitmap(bitmap_t *bitmap, int dst_x, int dst_y,
|
||||
uint32_t w, uint32_t h, int src_x, int src_y)
|
||||
{
|
||||
return driver->blit_bitmap(bitmap, dst_x, dst_y,
|
||||
w, h, src_x, src_y);
|
||||
};
|
||||
|
||||
int pxCreateClient(int x, int y, uint32_t width, uint32_t height)
|
||||
{
|
||||
return driver->create_client(x, y, width, height);
|
||||
}
|
||||
|
||||
int pxResizeClient(int x, int y, uint32_t width, uint32_t height)
|
||||
{
|
||||
printf("resize client\n");
|
||||
return driver->resize_client(x, y, width, height);
|
||||
}
|
||||
|
||||
static struct pix_driver sw_driver =
|
||||
{
|
||||
0,
|
||||
sw_create_bitmap,
|
||||
sw_destroy_bitmap,
|
||||
sw_lock_bitmap,
|
||||
sw_resize_bitmap,
|
||||
sw_blit,
|
||||
sw_create_client,
|
||||
sw_resize_client,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
uint32_t pxInit(int hw)
|
||||
{
|
||||
void *lib;
|
||||
struct pix_driver *(*drventry)(uint32_t service);
|
||||
|
||||
uint32_t api_version;
|
||||
ioctl_t io;
|
||||
|
||||
driver = &sw_driver;
|
||||
|
||||
if(hw == 0)
|
||||
return 0;
|
||||
|
||||
if (fd != 0)
|
||||
return driver->driver_caps;
|
||||
|
||||
fd = get_service("DISPLAY");
|
||||
if (fd == 0)
|
||||
goto fail;
|
||||
|
||||
io.handle = fd;
|
||||
io.io_code = SRV_GETVERSION;
|
||||
io.input = NULL;
|
||||
io.inp_size = 0;
|
||||
io.output = &api_version;
|
||||
io.out_size = BUFFER_SIZE(1);
|
||||
|
||||
if (call_service(&io) != 0)
|
||||
goto fail;
|
||||
|
||||
if ((DISPLAY_VERSION > (api_version & 0xFFFF)) ||
|
||||
(DISPLAY_VERSION < (api_version >> 16)))
|
||||
goto fail;
|
||||
|
||||
lib = load_library("pixlib-gl.dll");
|
||||
if(lib == 0)
|
||||
goto fail;
|
||||
|
||||
drventry = get_proc_address(lib, "DrvInit");
|
||||
|
||||
if( drventry == NULL)
|
||||
goto fail;
|
||||
|
||||
driver = drventry(fd);
|
||||
if(driver == NULL)
|
||||
{
|
||||
driver = &sw_driver;
|
||||
goto fail;
|
||||
};
|
||||
|
||||
if (driver->driver_caps)
|
||||
printf("2D caps %s%s%s\n",
|
||||
(driver->driver_caps & HW_BIT_BLIT) != 0 ? "HW_BIT_BLIT " : "",
|
||||
(driver->driver_caps & HW_TEX_BLIT) != 0 ? "HW_TEX_BLIT " : "",
|
||||
(driver->driver_caps & HW_VID_BLIT) != 0 ? "HW_VID_BLIT " : "");
|
||||
|
||||
return driver->driver_caps;
|
||||
|
||||
fail:
|
||||
printf("Warning! Hardware initialization failed.\n"
|
||||
"fallback to software rendering.\n");
|
||||
fd = 0;
|
||||
return 0;
|
||||
};
|
||||
|
||||
void pxFini()
|
||||
{
|
||||
if (driver->fini)
|
||||
driver->fini();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
33
contrib/sdk/sources/pixlib-3/pixlib3.h
Normal file
33
contrib/sdk/sources/pixlib-3/pixlib3.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef __PIXLIB3_H__
|
||||
#define __PIXLIB3_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define HW_BIT_BLIT (1<<0) /* BGRX blitter */
|
||||
#define HW_TEX_BLIT (1<<1) /* stretch blit */
|
||||
#define HW_VID_BLIT (1<<2) /* planar and packed video */
|
||||
|
||||
|
||||
struct bitmap;
|
||||
typedef struct bitmap bitmap_t;
|
||||
|
||||
uint32_t pxInit(int hw);
|
||||
void pxFini();
|
||||
|
||||
bitmap_t *pxCreateBitmap(uint32_t width, uint32_t height);
|
||||
|
||||
int pxDestroyBitmap(bitmap_t *bitmap);
|
||||
|
||||
void *pxLockBitmap(bitmap_t *bitmap, uint32_t *pitch);
|
||||
|
||||
int pxResizeBitmap(bitmap_t *bitmap, uint32_t width, uint32_t height);
|
||||
|
||||
int pxBlitBitmap(bitmap_t *bitmap, int dst_x, int dst_y,
|
||||
uint32_t w, uint32_t h, int src_x, int src_y);
|
||||
|
||||
int pxCreateClient(int x, int y, uint32_t width, uint32_t height);
|
||||
|
||||
int pxResizeClient(int x, int y, uint32_t width, uint32_t height);
|
||||
|
||||
#endif
|
||||
|
735
contrib/sdk/sources/pixlib-3/pxgl.c
Normal file
735
contrib/sdk/sources/pixlib-3/pxgl.c
Normal file
@ -0,0 +1,735 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <drm/i915_drm.h>
|
||||
#include <kos32sys.h>
|
||||
#include "pixlib3.h"
|
||||
#include "pixdriver.h"
|
||||
#include "pxgl.h"
|
||||
|
||||
#define WIN_STATE_MINIMIZED 0x02
|
||||
#define WIN_STATE_ROLLED 0x04
|
||||
|
||||
static int drm_ioctl(int fd, unsigned long request, void *arg)
|
||||
{
|
||||
ioctl_t io;
|
||||
|
||||
io.handle = fd;
|
||||
io.io_code = request;
|
||||
io.input = arg;
|
||||
io.inp_size = 64;
|
||||
io.output = NULL;
|
||||
io.out_size = 0;
|
||||
|
||||
return call_service(&io);
|
||||
}
|
||||
|
||||
static EGLImageKHR px_create_image(struct render *px,void *name,GLuint tex, EGLint *attribs)
|
||||
{
|
||||
EGLImageKHR image;
|
||||
|
||||
image = eglCreateImageKHR(px->dpy, px->context,
|
||||
EGL_DRM_BUFFER_MESA, name, attribs);
|
||||
if(image == NULL)
|
||||
goto err_0;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
if(glGetError() != GL_NO_ERROR)
|
||||
goto err_1;
|
||||
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
|
||||
if(glGetError() != GL_NO_ERROR)
|
||||
goto err_1;
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||
|
||||
return image;
|
||||
|
||||
err_1:
|
||||
eglDestroyImageKHR(px->dpy, image);
|
||||
err_0:
|
||||
return NULL;
|
||||
};
|
||||
|
||||
static int update_fb(struct render *px, int name, int pitch)
|
||||
{
|
||||
GLenum status;
|
||||
EGLImageKHR screen;
|
||||
|
||||
EGLint attribs[] = {
|
||||
EGL_WIDTH, px->scr_width,
|
||||
EGL_HEIGHT, px->scr_height,
|
||||
EGL_DRM_BUFFER_STRIDE_MESA, pitch/4,
|
||||
EGL_DRM_BUFFER_FORMAT_MESA,
|
||||
EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
|
||||
EGL_DRM_BUFFER_USE_MESA,
|
||||
EGL_DRM_BUFFER_USE_SHARE_MESA |
|
||||
EGL_DRM_BUFFER_USE_SCANOUT_MESA,
|
||||
EGL_NONE
|
||||
};
|
||||
char *errmsg;
|
||||
|
||||
px->screen = px_create_image(px,(void*)name, px->texture[TEX_SCREEN], attribs);
|
||||
errmsg = "failed to create new screen image\n";
|
||||
if(px->screen == EGL_NO_IMAGE_KHR)
|
||||
goto err_0;
|
||||
|
||||
px->screen = screen;
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D, px->texture[TEX_SCREEN],0);
|
||||
|
||||
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
const char *str;
|
||||
switch (status)
|
||||
{
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||
str = "incomplete attachment";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
|
||||
str = "incomplete/missing attachment";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
|
||||
str = "incomplete draw buffer";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
|
||||
str = "incomplete read buffer";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED:
|
||||
str = "unsupported";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
|
||||
str = "incomplete multiple";
|
||||
break;
|
||||
default:
|
||||
str = "unknown error";
|
||||
break;
|
||||
}
|
||||
DBG("destination framebuffer incomplete: %s [%#x]\n", str, status);
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
DBG("framebuffer changed successfull\n");
|
||||
|
||||
glViewport(0, 0, px->scr_width, px->scr_height);
|
||||
|
||||
return 0;
|
||||
|
||||
err_0:
|
||||
DBG("%s %s\n", __FUNCTION__, errmsg);
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
static GLint create_shader(GLenum type, const char *source)
|
||||
{
|
||||
GLint ok;
|
||||
GLint shader;
|
||||
|
||||
shader = glCreateShader(type);
|
||||
if(shader == 0)
|
||||
goto err;
|
||||
|
||||
glShaderSource(shader, 1, (const GLchar **) &source, NULL);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
|
||||
if (!ok) {
|
||||
GLchar *info;
|
||||
GLint size;
|
||||
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
|
||||
info = malloc(size);
|
||||
|
||||
glGetShaderInfoLog(shader, size, NULL, info);
|
||||
DBG("Failed to compile %s: %s\n",
|
||||
type == GL_FRAGMENT_SHADER ? "FS" : "VS",info);
|
||||
DBG("Program source:\n%s", source);
|
||||
DBG("GLSL compile failure\n");
|
||||
free(info);
|
||||
glDeleteShader(shader);
|
||||
shader = 0;
|
||||
};
|
||||
|
||||
DBG("create shader %d\n", shader);
|
||||
err:
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
||||
static void *px_create_obj(struct render *px, size_t size,
|
||||
GLuint *handle, GLuint *name)
|
||||
{
|
||||
struct drm_i915_gem_create create;
|
||||
struct drm_i915_gem_mmap mmap_arg;
|
||||
struct drm_gem_close close;
|
||||
struct drm_gem_flink flink;
|
||||
|
||||
create.size = size;
|
||||
create.handle = 0;
|
||||
|
||||
if(drm_ioctl(px->fd, DRM_IOCTL_I915_GEM_CREATE, &create))
|
||||
goto err_0;
|
||||
|
||||
*handle = create.handle;
|
||||
flink.handle = create.handle;
|
||||
if (drm_ioctl(px->fd, DRM_IOCTL_GEM_FLINK, &flink))
|
||||
goto err_1;
|
||||
|
||||
*name = flink.name;
|
||||
|
||||
mmap_arg.handle = *handle;
|
||||
mmap_arg.offset = 0;
|
||||
mmap_arg.size = size;
|
||||
if (drm_ioctl(px->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg))
|
||||
{
|
||||
DBG("%s: failed to mmap bitmap handle=%d, %d bytes, into CPU domain\n",
|
||||
__FUNCTION__, *handle, size);
|
||||
goto err_1;
|
||||
};
|
||||
|
||||
return (void*)(uintptr_t)mmap_arg.addr_ptr;
|
||||
|
||||
err_1:
|
||||
close.handle = *handle;
|
||||
drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
|
||||
err_0:
|
||||
return NULL;
|
||||
};
|
||||
|
||||
|
||||
static int px_create_bitmap(struct render *px, struct bitmap *bitmap,
|
||||
size_t size, EGLint format)
|
||||
{
|
||||
struct drm_gem_close close;
|
||||
EGLint attribs[] = {
|
||||
EGL_WIDTH, bitmap->width,
|
||||
EGL_HEIGHT, bitmap->height,
|
||||
EGL_DRM_BUFFER_STRIDE_MESA, 0,
|
||||
EGL_DRM_BUFFER_FORMAT_MESA,
|
||||
format,
|
||||
EGL_DRM_BUFFER_USE_MESA,
|
||||
EGL_DRM_BUFFER_USE_SHARE_MESA,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
bitmap->buffer = px_create_obj(px, size, &bitmap->handle, &bitmap->name);
|
||||
if(bitmap->buffer == NULL)
|
||||
goto err_0;
|
||||
|
||||
switch(format)
|
||||
{
|
||||
case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
|
||||
attribs[5] = bitmap->pitch/4;
|
||||
break;
|
||||
case EGL_DRM_BUFFER_FORMAT_R8_MESA:
|
||||
attribs[5] = bitmap->pitch;
|
||||
break;
|
||||
default:
|
||||
DBG("%s invalid format %x\n",
|
||||
__FUNCTION__, format);
|
||||
goto err_1;
|
||||
}
|
||||
|
||||
bitmap->image = px_create_image(px,(void*)bitmap->name,
|
||||
bitmap->tex, attribs);
|
||||
if(bitmap->image == NULL)
|
||||
goto err_1;
|
||||
|
||||
DBG("create bitmap:%p %dx%d pitch:%d\n"
|
||||
"KHRimage:%p gl_tex:%d handle:%d name:%d\n"
|
||||
"mapped at %x\n",
|
||||
bitmap, bitmap->width, bitmap->height, bitmap->pitch,
|
||||
bitmap->image, bitmap->tex, bitmap->handle, bitmap->name,
|
||||
bitmap->buffer);
|
||||
|
||||
return 0;
|
||||
|
||||
err_1:
|
||||
user_free(bitmap->buffer);
|
||||
close.handle = bitmap->handle;
|
||||
drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
|
||||
err_0:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int create_mask(struct render *px)
|
||||
{
|
||||
struct drm_i915_mask_update update;
|
||||
int pitch;
|
||||
|
||||
pitch = (px->width+15) & ~15;
|
||||
|
||||
px->mask.width = px->width;
|
||||
px->mask.height = px->height;
|
||||
px->mask.pitch = pitch;
|
||||
px->mask.tex = px->texture[TEX_MASK];
|
||||
px->mask_size = pitch * px->height;
|
||||
|
||||
if(px_create_bitmap(px, &px->mask, px->mask_size,
|
||||
EGL_DRM_BUFFER_FORMAT_R8_MESA) == 0)
|
||||
{
|
||||
update.handle = px->mask.handle;
|
||||
update.dx = px->dx;
|
||||
update.dy = px->dy;
|
||||
update.width = px->width;
|
||||
update.height = px->height;
|
||||
update.bo_pitch = (px->width+15) & ~15;
|
||||
update.bo_map = (int)px->mask.buffer;
|
||||
update.forced = 1;
|
||||
drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update);
|
||||
return 0;
|
||||
};
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
static int update_mask(struct render *px)
|
||||
{
|
||||
struct drm_gem_close close;
|
||||
EGLint attribs[] = {
|
||||
EGL_WIDTH, 0,
|
||||
EGL_HEIGHT, 0,
|
||||
EGL_DRM_BUFFER_STRIDE_MESA, 0,
|
||||
EGL_DRM_BUFFER_FORMAT_MESA,
|
||||
EGL_DRM_BUFFER_FORMAT_R8_MESA,
|
||||
EGL_DRM_BUFFER_USE_MESA,
|
||||
EGL_DRM_BUFFER_USE_SHARE_MESA,
|
||||
EGL_NONE
|
||||
};
|
||||
unsigned int size, pitch;
|
||||
|
||||
eglDestroyImageKHR(px->dpy, px->mask.image);
|
||||
|
||||
pitch = (px->width+15) & ~15;
|
||||
size = pitch*px->height;
|
||||
|
||||
if(size > px->mask_size)
|
||||
{
|
||||
user_free(px->mask.buffer);
|
||||
close.handle = px->mask.handle;
|
||||
drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
|
||||
|
||||
px->mask_size = size;
|
||||
|
||||
px->mask.buffer = px_create_obj(px, px->mask_size,
|
||||
&px->mask.handle, &px->mask.name);
|
||||
if(px->mask.buffer == 0)
|
||||
goto err_0;
|
||||
};
|
||||
|
||||
attribs[1] = px->width;
|
||||
attribs[3] = px->height;
|
||||
attribs[5] = pitch;
|
||||
|
||||
px->mask.image = px_create_image(px,(void*)px->mask.name,
|
||||
px->mask.tex, attribs);
|
||||
if(px->mask.image == NULL)
|
||||
goto err_1;
|
||||
|
||||
DBG("create mask w:%d h:%d pitch:%d\n"
|
||||
"KHRimage:%p gl_tex:%d handle:%d name:%d\n"
|
||||
"mapped at %x\n",
|
||||
px->width, px->height,
|
||||
pitch, px->mask.image, px->texture[TEX_MASK],
|
||||
px->mask.handle, px->mask.name, px->mask.buffer);
|
||||
|
||||
return 0;
|
||||
|
||||
err_1:
|
||||
user_free(px->mask.buffer);
|
||||
close.handle = px->mask.handle;
|
||||
drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
|
||||
err_0:
|
||||
return -1;
|
||||
};
|
||||
|
||||
static struct render* create_render(EGLDisplay dpy, EGLContext context, int dx, int dy, int w, int h)
|
||||
{
|
||||
const char *vs_src =
|
||||
"attribute vec4 v_position;\n"
|
||||
"attribute vec4 v_texcoord0;\n"
|
||||
"varying vec2 source_texture;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = v_position;\n"
|
||||
" source_texture = v_texcoord0.xy;\n"
|
||||
"}\n";
|
||||
|
||||
const char *fs_i965 =
|
||||
"varying vec2 source_texture;\n"
|
||||
"uniform sampler2D sampler_src;\n"
|
||||
"uniform sampler2D sampler_mask;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" float ca = texture2D(sampler_mask, source_texture).r;\n"
|
||||
" gl_FragColor = vec4(texture2D(sampler_src, source_texture).rgb, ca);\n"
|
||||
"}\n";
|
||||
|
||||
struct drm_i915_fb_info fb;
|
||||
struct render *px;
|
||||
GLint vs_shader, fs_shader;
|
||||
int ret;
|
||||
|
||||
px = (struct render*)malloc(sizeof(struct render));
|
||||
if(px == NULL)
|
||||
goto err_0;
|
||||
|
||||
px->fd = get_service("DISPLAY");
|
||||
|
||||
__builtin_memset(&fb, 0, sizeof(fb));
|
||||
if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb))
|
||||
{ DBG("failed to get framebuffer info\n");
|
||||
goto err_1;
|
||||
};
|
||||
|
||||
px->dpy = dpy;
|
||||
px->context = context;
|
||||
px->dx = dx;
|
||||
px->dy = dy;
|
||||
px->width = w;
|
||||
px->height = h;
|
||||
px->scr_width = fb.width;
|
||||
px->scr_height = fb.height;
|
||||
|
||||
glGenTextures(2, px->texture);
|
||||
if(glGetError() != GL_NO_ERROR)
|
||||
goto err_1;
|
||||
|
||||
glGenFramebuffers(1, &px->framebuffer);
|
||||
if(glGetError() != GL_NO_ERROR)
|
||||
goto err_2;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, px->framebuffer);
|
||||
if(glGetError() != GL_NO_ERROR)
|
||||
goto err_3;
|
||||
|
||||
if(update_fb(px, fb.name, fb.pitch))
|
||||
goto err_4;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
if(create_mask(px))
|
||||
goto err_4;
|
||||
|
||||
px->blit_prog = glCreateProgram();
|
||||
if(px->blit_prog == 0)
|
||||
goto err_4;
|
||||
|
||||
vs_shader = create_shader(GL_VERTEX_SHADER, vs_src);
|
||||
if(vs_shader == 0)
|
||||
goto err_4;
|
||||
|
||||
fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_i965);
|
||||
if(fs_shader == 0)
|
||||
goto err_4;
|
||||
|
||||
glAttachShader(px->blit_prog, vs_shader);
|
||||
glAttachShader(px->blit_prog, fs_shader);
|
||||
glBindAttribLocation(px->blit_prog, 0, "v_position");
|
||||
glBindAttribLocation(px->blit_prog, 1, "v_texcoord0");
|
||||
|
||||
glLinkProgram(px->blit_prog);
|
||||
glGetProgramiv(px->blit_prog, GL_LINK_STATUS, &ret);
|
||||
if (!ret)
|
||||
{
|
||||
GLchar *info;
|
||||
GLint size;
|
||||
|
||||
glGetProgramiv(px->blit_prog, GL_INFO_LOG_LENGTH, &size);
|
||||
info = malloc(size);
|
||||
|
||||
glGetProgramInfoLog(px->blit_prog, size, NULL, info);
|
||||
DBG("Failed to link: %s\n", info);
|
||||
DBG("GLSL link failure\n");
|
||||
free(info);
|
||||
goto err_4;
|
||||
}
|
||||
|
||||
px->sampler = glGetUniformLocation(px->blit_prog,"sampler_src");
|
||||
px->sm_mask = glGetUniformLocation(px->blit_prog,"sampler_mask");
|
||||
|
||||
glUseProgram(px->blit_prog);
|
||||
glUniform1i(px->sampler, 0);
|
||||
glUniform1i(px->sm_mask, 1);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),px->vertices);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),px->tc_src);
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
px->tc_src[0] = 0.0;
|
||||
px->tc_src[1] = 0.0;
|
||||
px->tc_src[1*2] = 1.0;
|
||||
px->tc_src[1*2+1]= 0.0;
|
||||
px->tc_src[2*2] = 1.0;
|
||||
px->tc_src[2*2+1]= 1.0;
|
||||
px->tc_src[3*2] = 0.0;
|
||||
px->tc_src[3*2+1]= 1.0;
|
||||
|
||||
DBG("create render framebuffer:%p %dx%d pitch:%d name %d\n",
|
||||
px->screen,fb.width, fb.height, fb.pitch, fb.name);
|
||||
|
||||
return px;
|
||||
|
||||
err_4:
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
err_3:
|
||||
glDeleteFramebuffers(1, &px->framebuffer);
|
||||
err_2:
|
||||
glDeleteTextures(2, px->texture);
|
||||
err_1:
|
||||
free(px);
|
||||
err_0:
|
||||
return NULL;
|
||||
};
|
||||
|
||||
static struct render *px;
|
||||
|
||||
static bitmap_t *hw_create_bitmap(uint32_t width, uint32_t height)
|
||||
{
|
||||
struct bitmap *bitmap;
|
||||
|
||||
bitmap = malloc(sizeof(struct bitmap));
|
||||
if(bitmap == NULL)
|
||||
return NULL;
|
||||
|
||||
glGenTextures(1, &bitmap->tex);
|
||||
if(glGetError() != GL_NO_ERROR)
|
||||
goto err_0;
|
||||
|
||||
bitmap->width = width;
|
||||
bitmap->height = height;
|
||||
bitmap->pitch = (width*4 + 15) & ~15;
|
||||
|
||||
if(px_create_bitmap(px, bitmap, bitmap->pitch * bitmap->height,
|
||||
EGL_DRM_BUFFER_FORMAT_ARGB32_MESA) == 0)
|
||||
{
|
||||
return bitmap;
|
||||
};
|
||||
|
||||
glDeleteTextures(1, &bitmap->tex);
|
||||
err_0:
|
||||
free(bitmap);
|
||||
return NULL;
|
||||
};
|
||||
|
||||
static int hw_destroy_bitmap(bitmap_t * bitmap)
|
||||
{
|
||||
struct drm_gem_close close;
|
||||
|
||||
glDeleteTextures(1, &bitmap->tex);
|
||||
eglDestroyImageKHR(px->dpy, bitmap->image);
|
||||
user_free(bitmap->buffer);
|
||||
close.handle = bitmap->handle;
|
||||
drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
|
||||
free(bitmap);
|
||||
};
|
||||
|
||||
static void *hw_lock_bitmap(bitmap_t *bitmap, uint32_t *pitch)
|
||||
{
|
||||
*pitch = bitmap->pitch;
|
||||
|
||||
return bitmap->buffer;
|
||||
};
|
||||
|
||||
static int hw_resize_bitmap(bitmap_t * bitmap, uint32_t width, uint32_t height)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char proc_info[1024];
|
||||
|
||||
static int hw_blit(bitmap_t *bitmap, int dst_x, int dst_y,
|
||||
uint32_t w, uint32_t h, int src_x, int src_y)
|
||||
{
|
||||
struct drm_i915_mask_update update;
|
||||
struct drm_i915_fb_info fb;
|
||||
|
||||
uint32_t winx, winy, winw, winh;
|
||||
uint8_t state;
|
||||
float xscale, yscale;
|
||||
int r, b;
|
||||
float *vertices = px->vertices;
|
||||
|
||||
get_proc_info(proc_info);
|
||||
|
||||
state = *(uint8_t*)(proc_info+70);
|
||||
if(state & (WIN_STATE_MINIMIZED|WIN_STATE_ROLLED))
|
||||
return;
|
||||
|
||||
winx = *(uint32_t*)(proc_info+34);
|
||||
winy = *(uint32_t*)(proc_info+38);
|
||||
winw = *(uint32_t*)(proc_info+42)+1;
|
||||
winh = *(uint32_t*)(proc_info+46)+1;
|
||||
|
||||
__builtin_memset(&fb, 0, sizeof(fb));
|
||||
if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb))
|
||||
{
|
||||
DBG("failed to get framebuffer info\n");
|
||||
return;
|
||||
};
|
||||
|
||||
if( fb.width != px->scr_width ||
|
||||
fb.height != px->scr_height )
|
||||
{
|
||||
px->scr_width = fb.width;
|
||||
px->scr_height = fb.height;
|
||||
|
||||
eglDestroyImageKHR(px->dpy, px->screen);
|
||||
|
||||
if(update_fb(px, fb.name, fb.pitch))
|
||||
return;
|
||||
};
|
||||
|
||||
update.handle = px->mask.handle;
|
||||
update.dx = px->dx;
|
||||
update.dy = px->dy;
|
||||
update.width = px->width;
|
||||
update.height = px->height;
|
||||
update.bo_pitch = (px->width+15) & ~15;
|
||||
update.bo_map = (int)px->mask.buffer;
|
||||
|
||||
if(drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
xscale = 1.0/px->scr_width;
|
||||
yscale = 1.0/px->scr_height;
|
||||
|
||||
r = winx + px->dx + px->width;
|
||||
b = winy + px->dy + px->height;
|
||||
|
||||
float t0, t1, t2, t5;
|
||||
|
||||
// render->tc_src[1*2] = 1.0;
|
||||
// render->tc_src[2*2] = 1.0;
|
||||
// render->tc_src[2*2+1]= 1.0;
|
||||
// render->tc_src[3*2+1]= 1.0;
|
||||
|
||||
vertices[0] = t0 = 2*(winx+px->dx)*xscale - 1.0;
|
||||
vertices[1 * 2] = t2 = 2*r*xscale - 1.0;
|
||||
|
||||
vertices[2 * 2] = t2;
|
||||
vertices[3 * 2] = t0;
|
||||
|
||||
vertices[1] = t1 = 2*(winy+px->dy)*yscale - 1.0;
|
||||
vertices[2*2+1] = t5 = 2*b*yscale - 1.0;
|
||||
vertices[1*2+1] = t1;
|
||||
vertices[3*2+1] = t5;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, bitmap->tex);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, px->texture[TEX_MASK]);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
glFlush();
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
static int hw_create_client(int x, int y, uint32_t width, uint32_t height)
|
||||
{
|
||||
px = create_render(eglGetCurrentDisplay(), eglGetCurrentContext(), x, y, width, height);
|
||||
|
||||
return !px;
|
||||
};
|
||||
|
||||
static int hw_resize_client(int x, int y, uint32_t width, uint32_t height)
|
||||
{
|
||||
if( x != px->dx ||
|
||||
y != px->dy ||
|
||||
width != px->width ||
|
||||
height != px->height )
|
||||
{
|
||||
struct drm_i915_mask_update update;
|
||||
|
||||
px->dx = x;
|
||||
px->dy = y;
|
||||
px->width = width;
|
||||
px->height = height;
|
||||
update_mask(px);
|
||||
|
||||
update.handle = px->mask.handle;
|
||||
update.dx = px->dx;
|
||||
update.dy = px->dy;
|
||||
update.width = px->width;
|
||||
update.height = px->height;
|
||||
update.bo_pitch = (px->width+15) & ~15;
|
||||
update.bo_map = (int)px->mask.buffer;
|
||||
update.forced = 1;
|
||||
|
||||
drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update);
|
||||
};
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static void hw_fini(void)
|
||||
{
|
||||
struct drm_gem_close close;
|
||||
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
|
||||
eglDestroyImageKHR(px->dpy, px->mask.image);
|
||||
user_free(px->mask.buffer);
|
||||
close.handle = px->mask.handle;
|
||||
drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &px->framebuffer);
|
||||
eglDestroyImageKHR(px->dpy, px->screen);
|
||||
glDeleteTextures(2, px->texture);
|
||||
egl_destroy(px->dpy, px->context);
|
||||
free(px);
|
||||
};
|
||||
|
||||
static struct pix_driver gl_driver =
|
||||
{
|
||||
HW_TEX_BLIT,
|
||||
hw_create_bitmap,
|
||||
hw_destroy_bitmap,
|
||||
hw_lock_bitmap,
|
||||
hw_resize_bitmap,
|
||||
hw_blit,
|
||||
hw_create_client,
|
||||
hw_resize_client,
|
||||
hw_fini
|
||||
};
|
||||
|
||||
struct pix_driver *DrvInit(uint32_t service)
|
||||
{
|
||||
EGLDisplay dpy;
|
||||
EGLConfig config;
|
||||
EGLContext context;
|
||||
int ret;
|
||||
|
||||
ret = egl_initialize(&dpy, &config, &context);
|
||||
if( ret )
|
||||
return NULL;
|
||||
|
||||
return &gl_driver;
|
||||
|
||||
err_0:
|
||||
egl_destroy(dpy, context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
67
contrib/sdk/sources/pixlib-3/pxgl.h
Normal file
67
contrib/sdk/sources/pixlib-3/pxgl.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef __GL_RENDER_H__
|
||||
#define __GL_RENDER_H__
|
||||
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#include "EGL/egl.h"
|
||||
#include "EGL/eglext.h"
|
||||
#include "GL/gl.h"
|
||||
|
||||
struct bitmap
|
||||
{
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t pitch;
|
||||
void *buffer;
|
||||
GLuint tex;
|
||||
GLuint handle;
|
||||
GLuint name;
|
||||
EGLImageKHR image;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TEX_SCREEN = 0,
|
||||
TEX_MASK = 1
|
||||
};
|
||||
|
||||
struct render
|
||||
{
|
||||
int fd;
|
||||
EGLDisplay dpy;
|
||||
EGLContext context;
|
||||
EGLint dx;
|
||||
EGLint dy;
|
||||
EGLint width;
|
||||
EGLint height;
|
||||
EGLint scr_width;
|
||||
EGLint scr_height;
|
||||
GLuint texture[2];
|
||||
GLuint framebuffer;
|
||||
EGLImageKHR screen;
|
||||
struct bitmap mask;
|
||||
|
||||
int mask_size;
|
||||
|
||||
GLuint blit_prog;
|
||||
GLint sampler, sm_mask;
|
||||
float vertices[8],tc_src[8];
|
||||
};
|
||||
|
||||
int egl_initialize(EGLDisplay *dpy, EGLConfig *config, EGLContext *context);
|
||||
void egl_destroy(EGLDisplay dpy, EGLContext context);
|
||||
|
||||
#define ENTER() printf("enter %s\n",__FUNCTION__)
|
||||
#define LEAVE() printf("leave %s\n",__FUNCTION__)
|
||||
#define FAIL() printf("fail %s\n",__FUNCTION__)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(...) do { \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define DBG(...)
|
||||
#endif
|
||||
|
||||
#endif /* __GL_RENDER_H__ */
|
Loading…
Reference in New Issue
Block a user