SVN revision: 31359devs/devilhorns/wayland_egl
parent
29a2309415
commit
8474937ef3
12 changed files with 1136 additions and 2 deletions
@ -0,0 +1,3 @@ |
||||
Name: evas-direct3d |
||||
Description: Evas Direct3D engine |
||||
Version: @VERSION@ |
@ -0,0 +1,30 @@ |
||||
#ifndef __EVAS_ENGINE_DIRECT3D_H__ |
||||
#define __EVAS_ENGINE_DIRECT3D_H__ |
||||
|
||||
|
||||
#include <windows.h> |
||||
#include <d3d9.h> |
||||
#include <d3dx9.h> |
||||
|
||||
typedef struct _Evas_Engine_Info_Direct3D Evas_Engine_Info_Direct3D; |
||||
|
||||
struct _Evas_Engine_Info_Direct3D |
||||
{ |
||||
/* PRIVATE - don't mess with this baby or evas will poke its tongue out */ |
||||
/* at you and make nasty noises */ |
||||
Evas_Engine_Info magic; |
||||
|
||||
struct { |
||||
HWND window; |
||||
LPDIRECT3D9 object; /* Direct3D object */ |
||||
LPDIRECT3DDEVICE9 device; /* Direct3D device */ |
||||
LPD3DXSPRITE sprite; /* Direct3D sprite */ |
||||
LPDIRECT3DTEXTURE9 texture; /* Direct3D texture */ |
||||
|
||||
int depth; |
||||
int rotation; |
||||
} info; |
||||
}; |
||||
|
||||
|
||||
#endif /* __EVAS_ENGINE_DIRECT3D_H__ */ |
@ -0,0 +1,33 @@ |
||||
AUTOMAKE_OPTIONS = 1.4 foreign
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
INCLUDES = -I. -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/lib/include -I$(top_srcdir)/src/modules/engines @FREETYPE_CFLAGS@
|
||||
|
||||
if BUILD_ENGINE_DIRECT3D |
||||
|
||||
pkgdir = $(libdir)/evas/modules/engines/direct3d/$(MODULE_ARCH)
|
||||
|
||||
pkg_LTLIBRARIES = module.la
|
||||
module_la_SOURCES = \
|
||||
evas_engine.h \ |
||||
evas_engine.c \ |
||||
evas_outbuf.c \ |
||||
evas_direct3d_buffer.c \ |
||||
evas_direct3d_main.cpp |
||||
|
||||
module_la_LIBADD = $(top_builddir)/src/lib/libevas.la @direct3d_libs@
|
||||
module_la_LDFLAGS = @create_shared_lib@ -module -avoid-version -L$(top_builddir)/src/lib -L$(top_builddir)/src/lib/.libs
|
||||
module_la_DEPENDENCIES = $(top_builddir)/config.h
|
||||
|
||||
include_HEADERS = Evas_Engine_Direct3d.h
|
||||
|
||||
endif |
||||
|
||||
EXTRA_DIST = \
|
||||
evas_engine.h \ |
||||
evas_engine.c \ |
||||
evas_outbuf.c \ |
||||
evas_direct3d_buffer.c \ |
||||
evas_direct3d_main.cpp \ |
||||
Evas_Engine_Direct3d.h |
@ -0,0 +1,88 @@ |
||||
#include <string.h> |
||||
|
||||
#include "evas_engine.h" |
||||
|
||||
|
||||
Direct3D_Output_Buffer * |
||||
evas_direct3d_output_buffer_new(int depth, |
||||
int width, |
||||
int height, |
||||
void *data) |
||||
{ |
||||
Direct3D_Output_Buffer *d3dob; |
||||
|
||||
d3dob = calloc(1, sizeof(Direct3D_Output_Buffer)); |
||||
if (!d3dob) return NULL; |
||||
|
||||
d3dob->image = data; |
||||
d3dob->depth = depth; |
||||
d3dob->width = width; |
||||
d3dob->height = height; |
||||
d3dob->pitch = width * (depth >> 3); |
||||
|
||||
if (!d3dob->image) |
||||
{ |
||||
d3dob->image = malloc(d3dob->pitch * height); |
||||
if (!d3dob->image) |
||||
{ |
||||
free(d3dob); |
||||
return NULL; |
||||
} |
||||
} |
||||
|
||||
return d3dob; |
||||
} |
||||
|
||||
void |
||||
evas_direct3d_output_buffer_free(Direct3D_Output_Buffer *d3dob) |
||||
{ |
||||
if (d3dob->image) free(d3dob->image); |
||||
free(d3dob); |
||||
} |
||||
|
||||
void |
||||
evas_direct3d_output_buffer_paste(Direct3D_Output_Buffer *d3dob, |
||||
DATA8 *d3d_data, |
||||
int d3d_width, |
||||
int d3d_height, |
||||
int d3d_pitch, |
||||
int x, |
||||
int y) |
||||
{ |
||||
DATA8 *evas_data; |
||||
int width; |
||||
int height; |
||||
int pitch; |
||||
int j; |
||||
|
||||
if ((x >= d3d_width) || (y >= d3d_height)) |
||||
return; |
||||
|
||||
/* compute the size of the data to copy on the back surface */ |
||||
width = ((x + d3dob->width) > d3d_width) |
||||
? d3d_width - x |
||||
: d3dob->width; |
||||
height = ((y + d3dob->height) > d3d_height) |
||||
? d3d_height - y |
||||
: d3dob->height; |
||||
pitch = width * (d3dob->depth >> 3); |
||||
|
||||
d3d_data += y * d3d_pitch + x * (d3dob->depth >> 3); |
||||
evas_data = (unsigned char *)d3dob->image; |
||||
for (j = 0; j < height; j++, evas_data += d3dob->pitch, d3d_data += d3d_pitch) |
||||
memcpy(d3d_data, evas_data, pitch); |
||||
} |
||||
|
||||
DATA8 * |
||||
evas_direct3d_output_buffer_data(Direct3D_Output_Buffer *d3dob, |
||||
int *bytes_per_line_ret) |
||||
{ |
||||
if (bytes_per_line_ret) *bytes_per_line_ret = d3dob->pitch; |
||||
return d3dob->image; |
||||
} |
||||
|
||||
int |
||||
evas_direct3d_output_buffer_depth(Direct3D_Output_Buffer *d3dob) |
||||
{ |
||||
return d3dob->depth; |
||||
} |
@ -0,0 +1,84 @@ |
||||
#include "evas_engine.h" |
||||
|
||||
|
||||
extern "C" { |
||||
|
||||
int |
||||
evas_direct3d_masks_get(Outbuf *buf) |
||||
{ |
||||
D3DSURFACE_DESC sd; |
||||
|
||||
if (FAILED(buf->priv.d3d.texture->GetLevelDesc(0, &sd))) |
||||
return 0; |
||||
|
||||
switch (sd.Format) |
||||
{ |
||||
case D3DFMT_A8R8G8B8: |
||||
case D3DFMT_X8R8G8B8: |
||||
buf->priv.mask.r = 0x00ff0000; |
||||
buf->priv.mask.g = 0x0000ff00; |
||||
buf->priv.mask.b = 0x000000ff; |
||||
break; |
||||
case D3DFMT_R5G6B5: |
||||
buf->priv.mask.r = 0xf800; |
||||
buf->priv.mask.g = 0x07e0; |
||||
buf->priv.mask.b = 0x001f; |
||||
break; |
||||
default: |
||||
return 0; |
||||
} |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
void * |
||||
evas_direct3d_lock(Outbuf *buf, int *d3d_width, int *d3d_height, int *d3d_pitch) |
||||
{ |
||||
D3DSURFACE_DESC sd; |
||||
D3DLOCKED_RECT d3d_rect; |
||||
|
||||
/* is that call needed / overkill ? */ |
||||
if (FAILED(buf->priv.d3d.texture->GetLevelDesc(0, &sd))) |
||||
return NULL; |
||||
|
||||
if (FAILED(buf->priv.d3d.device->BeginScene())) |
||||
return NULL; |
||||
if (FAILED(buf->priv.d3d.sprite->Begin(D3DXSPRITE_DO_NOT_ADDREF_TEXTURE))) |
||||
{ |
||||
buf->priv.d3d.device->EndScene(); |
||||
return NULL; |
||||
} |
||||
if (FAILED(buf->priv.d3d.texture->LockRect(0, &d3d_rect, NULL, D3DLOCK_DISCARD))) |
||||
{ |
||||
buf->priv.d3d.sprite->End(); |
||||
buf->priv.d3d.device->EndScene(); |
||||
return NULL; |
||||
} |
||||
|
||||
*d3d_width = sd.Width; |
||||
*d3d_height = sd.Height; |
||||
*d3d_pitch = d3d_rect.Pitch; |
||||
|
||||
return d3d_rect.pBits; |
||||
} |
||||
|
||||
void |
||||
evas_direct3d_unlock(Outbuf *buf) |
||||
{ |
||||
if (FAILED(buf->priv.d3d.texture->UnlockRect(0))) |
||||
return; |
||||
|
||||
if (FAILED(buf->priv.d3d.sprite->Draw(buf->priv.d3d.texture, |
||||
NULL, NULL, NULL, |
||||
D3DCOLOR_ARGB (255, 255, 255, 255)))) |
||||
return; |
||||
if (FAILED(buf->priv.d3d.sprite->End())) |
||||
return; |
||||
|
||||
if (FAILED(buf->priv.d3d.device->EndScene())) |
||||
return; |
||||
if (FAILED(buf->priv.d3d.device->Present(NULL, NULL, NULL, NULL))) |
||||
return; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,369 @@ |
||||
#include "evas_engine.h" |
||||
#include "evas_private.h" |
||||
#include "Evas_Engine_Direct3D.h" |
||||
|
||||
/* engine struct data */ |
||||
typedef struct _Render_Engine Render_Engine; |
||||
|
||||
struct _Render_Engine |
||||
{ |
||||
Tilebuf *tb; |
||||
Outbuf *ob; |
||||
Tilebuf_Rect *rects; |
||||
Evas_Object_List *cur_rect; |
||||
int end : 1; |
||||
}; |
||||
|
||||
|
||||
/* function tables - filled in later (func and parent func) */ |
||||
static Evas_Func func, pfunc; |
||||
|
||||
/* prototypes we will use here */ |
||||
static void *_output_setup(int width, |
||||
int height, |
||||
int rotation, |
||||
HWND window, |
||||
LPDIRECT3D9 object, |
||||
LPDIRECT3DDEVICE9 device, |
||||
LPD3DXSPRITE sprite, |
||||
LPDIRECT3DTEXTURE9 texture, |
||||
int w_depth); |
||||
|
||||
static void *eng_info(Evas *e); |
||||
static void eng_info_free(Evas *e, |
||||
void *info); |
||||
static void eng_setup(Evas *e, |
||||
void *info); |
||||
static void eng_output_free(void *data); |
||||
static void eng_output_resize(void *data, |
||||
int width, |
||||
int height); |
||||
static void eng_output_tile_size_set(void *data, |
||||
int width, |
||||
int height); |
||||
static void eng_output_redraws_rect_add(void *data, |
||||
int x, |
||||
int y, |
||||
int width, |
||||
int height); |
||||
static void eng_output_redraws_rect_del(void *data, |
||||
int x, |
||||
int y, |
||||
int width, |
||||
int height); |
||||
static void eng_output_redraws_clear(void *data); |
||||
|
||||
/* internal engine routines */ |
||||
static void * |
||||
_output_setup(int width, |
||||
int height, |
||||
int rotation, |
||||
HWND window, |
||||
LPDIRECT3D9 object, |
||||
LPDIRECT3DDEVICE9 device, |
||||
LPD3DXSPRITE sprite, |
||||
LPDIRECT3DTEXTURE9 texture, |
||||
int w_depth) |
||||
{ |
||||
Render_Engine *re; |
||||
|
||||
re = (Render_Engine *)calloc(1, sizeof(Render_Engine)); |
||||
if (!re) return NULL; |
||||
|
||||
/* if we haven't initialized - init (automatic abort if already done) */ |
||||
evas_common_cpu_init(); |
||||
|
||||
evas_common_blend_init(); |
||||
evas_common_image_init(); |
||||
evas_common_convert_init(); |
||||
evas_common_scale_init(); |
||||
evas_common_rectangle_init(); |
||||
evas_common_gradient_init(); |
||||
evas_common_polygon_init(); |
||||
evas_common_line_init(); |
||||
evas_common_font_init(); |
||||
evas_common_draw_init(); |
||||
evas_common_tilebuf_init(); |
||||
|
||||
evas_direct3d_outbuf_init(); |
||||
|
||||
/* get any stored performance metrics from device */ |
||||
re->ob = evas_direct3d_outbuf_setup_d3d(width, height, rotation, OUTBUF_DEPTH_INHERIT, window, object, device, sprite, texture, w_depth); |
||||
if (!re->ob) |
||||
{ |
||||
free(re); |
||||
return NULL; |
||||
} |
||||
|
||||
re->tb = evas_common_tilebuf_new(width, height); |
||||
if (!re->tb) |
||||
{ |
||||
evas_direct3d_outbuf_free(re->ob); |
||||
free(re); |
||||
return NULL; |
||||
} |
||||
|
||||
/* FIXME: that comment :) */ |
||||
/* in preliminary tests 16x16 gave highest framerates */ |
||||
evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); |
||||
|
||||
return re; |
||||
} |
||||
|
||||
/* engine api this module provides */ |
||||
static void * |
||||
eng_info(Evas *e) |
||||
{ |
||||
Evas_Engine_Info_Direct3D *info; |
||||
|
||||
info = (Evas_Engine_Info_Direct3D *)calloc(1, sizeof(Evas_Engine_Info_Direct3D)); |
||||
if (!info) return NULL; |
||||
info->magic.magic = rand(); |
||||
return info; |
||||
e = NULL; |
||||
} |
||||
|
||||
static void |
||||
eng_info_free(Evas *e, |
||||
void *info) |
||||
{ |
||||
Evas_Engine_Info_Direct3D *in; |
||||
|
||||
in = (Evas_Engine_Info_Direct3D *)info; |
||||
free(in); |
||||
} |
||||
|
||||
static void |
||||
eng_setup(Evas *e, |
||||
void *info) |
||||
{ |
||||
Render_Engine *re; |
||||
Evas_Engine_Info_Direct3D *in; |
||||
|
||||
in = (Evas_Engine_Info_Direct3D *)info; |
||||
if (!e->engine.data.output) |
||||
e->engine.data.output = |
||||
_output_setup(e->output.w, |
||||
e->output.h, |
||||
in->info.rotation, |
||||
in->info.window, |
||||
in->info.object, |
||||
in->info.device, |
||||
in->info.sprite, |
||||
in->info.texture, |
||||
in->info.depth); |
||||
if (!e->engine.data.output) return; |
||||
if (!e->engine.data.context) |
||||
e->engine.data.context = |
||||
e->engine.func->context_new(e->engine.data.output); |
||||
|
||||
re = (Render_Engine *)e->engine.data.output; |
||||
} |
||||
|
||||
static void |
||||
eng_output_free(void *data) |
||||
{ |
||||
Render_Engine *re; |
||||
|
||||
re = (Render_Engine *)data; |
||||
evas_direct3d_outbuf_free(re->ob); |
||||
evas_common_tilebuf_free(re->tb); |
||||
if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); |
||||
free(re); |
||||
|
||||
evas_common_font_shutdown(); |
||||
evas_common_image_shutdown(); |
||||
} |
||||
|
||||
static void |
||||
eng_output_resize(void *data, |
||||
int width, |
||||
int height) |
||||
{ |
||||
Render_Engine *re; |
||||
|
||||
re = (Render_Engine *)data; |
||||
evas_direct3d_outbuf_reconfigure(re->ob, |
||||
width, |
||||
height, |
||||
evas_direct3d_outbuf_rot_get(re->ob), |
||||
OUTBUF_DEPTH_INHERIT); |
||||
evas_common_tilebuf_free(re->tb); |
||||
re->tb = evas_common_tilebuf_new(width, height); |
||||
if (re->tb) |
||||
evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); |
||||
} |
||||
|
||||
static void |
||||
eng_output_tile_size_set(void *data, |
||||
int width, |
||||
int height) |
||||
{ |
||||
Render_Engine *re; |
||||
|
||||
re = (Render_Engine *)data; |
||||
evas_common_tilebuf_set_tile_size(re->tb, width, height); |
||||
} |
||||
|
||||
static void |
||||
eng_output_redraws_rect_add(void *data, |
||||
int x, |
||||
int y, |
||||
int width, |
||||
int height) |
||||
{ |
||||
Render_Engine *re; |
||||
|
||||
re = (Render_Engine *)data; |
||||
evas_common_tilebuf_add_redraw(re->tb, x, y, width, height); |
||||
} |
||||
|
||||
static void |
||||
eng_output_redraws_rect_del(void *data, |
||||
int x, |
||||
int y, |
||||
int width, |
||||
int height) |
||||
{ |
||||
Render_Engine *re; |
||||
|
||||
re = (Render_Engine *)data; |
||||
evas_common_tilebuf_del_redraw(re->tb, x, y, width, height); |
||||
} |
||||
|
||||
static void |
||||
eng_output_redraws_clear(void *data) |
||||
{ |
||||
Render_Engine *re; |
||||
|
||||
re = (Render_Engine *)data; |
||||
evas_common_tilebuf_clear(re->tb); |
||||
} |
||||
|
||||
static void * |
||||
eng_output_redraws_next_update_get(void *data, |
||||
int *x, |
||||
int *y, |
||||
int *w, |
||||
int *h, |
||||
int *cx, |
||||
int *cy, |
||||
int *cw, |
||||
int *ch) |
||||
{ |
||||
Render_Engine *re; |
||||
RGBA_Image *surface; |
||||
Tilebuf_Rect *rect; |
||||
int ux; |
||||
int uy; |
||||
int uw; |
||||
int uh; |
||||
|
||||
re = (Render_Engine *)data; |
||||
if (re->end) |
||||
{ |
||||
re->end = 0; |
||||
return NULL; |
||||
} |
||||
if (!re->rects) |
||||
{ |
||||
re->rects = evas_common_tilebuf_get_render_rects(re->tb); |
||||
re->cur_rect = (Evas_Object_List *)re->rects; |
||||
} |
||||
if (!re->cur_rect) return NULL; |
||||
rect = (Tilebuf_Rect *)re->cur_rect; |
||||
ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h; |
||||
re->cur_rect = re->cur_rect->next; |
||||
if (!re->cur_rect) |
||||
{ |
||||
evas_common_tilebuf_free_render_rects(re->rects); |
||||
re->rects = NULL; |
||||
re->end = 1; |
||||
} |
||||
|
||||
surface = evas_direct3d_outbuf_new_region_for_update(re->ob, |
||||
ux, uy, |
||||
uw, uh, |
||||
cx, cy, |
||||
cw, ch); |
||||
*x = ux; *y = uy; *w = uw; *h = uh; |
||||
|
||||
return surface; |
||||
} |
||||
|
||||
static void |
||||
eng_output_redraws_next_update_push(void *data, |
||||
void *surface, |
||||
int x, |
||||
int y, |
||||
int w, |
||||
int h) |
||||
{ |
||||
Render_Engine *re; |
||||
|
||||
re = (Render_Engine *)data; |
||||
evas_common_pipe_begin((RGBA_Image *)surface); |
||||
evas_common_pipe_flush((RGBA_Image *)surface); |
||||
evas_direct3d_outbuf_push_updated_region(re->ob, (RGBA_Image *)surface, x, y, w, h); |
||||
evas_direct3d_outbuf_free_region_for_update(re->ob, (RGBA_Image *)surface); |
||||
evas_common_cpu_end_opt(); |
||||
} |
||||
|
||||
static void |
||||
eng_output_flush(void *data) |
||||
{ |
||||
Render_Engine *re; |
||||
|
||||
re = (Render_Engine *)data; |
||||
evas_direct3d_outbuf_flush(re->ob); |
||||
} |
||||
|
||||
static void |
||||
eng_output_idle_flush(void *data) |
||||
{ |
||||
Render_Engine *re; |
||||
|
||||
re = (Render_Engine *)data; |
||||
} |
||||
|
||||
/* module advertising code */ |
||||
EAPI int |
||||
module_open(Evas_Module *em) |
||||
{ |
||||
if (!em) return 0; |
||||
/* get whatever engine module we inherit from */ |
||||
if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0; |
||||
/* store it for later use */ |
||||
func = pfunc; |
||||
/* now to override methods */ |
||||
#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_) |
||||
ORD(info); |
||||
ORD(info_free); |
||||
ORD(setup); |
||||
ORD(output_free); |
||||
ORD(output_resize); |
||||
ORD(output_tile_size_set); |
||||
ORD(output_redraws_rect_add); |
||||
ORD(output_redraws_rect_del); |
||||
ORD(output_redraws_clear); |
||||
ORD(output_redraws_next_update_get); |
||||
ORD(output_redraws_next_update_push); |
||||
ORD(output_flush); |
||||
ORD(output_idle_flush); |
||||
/* now advertise out own api */ |
||||
em->functions = (void *)(&func); |
||||
return 1; |
||||
} |
||||
|
||||
EAPI void |
||||
module_close(void) |
||||
{ |
||||
} |
||||
|
||||
EAPI Evas_Module_Api evas_modapi = |
||||
{ |
||||
EVAS_MODULE_API_VERSION, |
||||
EVAS_MODULE_TYPE_ENGINE, |
||||
"direct3d", |
||||
"none" |
||||
}; |
@ -0,0 +1,141 @@ |
||||
#ifndef __EVAS_ENGINE_H__ |
||||
#define __EVAS_ENGINE_H__ |
||||
|
||||
|
||||
#include <windows.h> |
||||
#include <d3d9.h> |
||||
#include <d3dx9.h> |
||||
|
||||
#include "evas_common.h" |
||||
|
||||
|
||||
typedef struct _Outbuf Outbuf; |
||||
typedef struct _Direct3D_Output_Buffer Direct3D_Output_Buffer; |
||||
|
||||
|
||||
enum _Outbuf_Depth |
||||
{ |
||||
OUTBUF_DEPTH_NONE, |
||||
OUTBUF_DEPTH_INHERIT, |
||||
OUTBUF_DEPTH_RGB_16BPP_565_565_DITHERED, |
||||
OUTBUF_DEPTH_RGB_16BPP_555_555_DITHERED, |
||||
OUTBUF_DEPTH_RGB_16BPP_444_444_DITHERED, |
||||
OUTBUF_DEPTH_RGB_16BPP_565_444_DITHERED, |
||||
OUTBUF_DEPTH_RGB_32BPP_888_8888, |
||||
OUTBUF_DEPTH_LAST |
||||
}; |
||||
typedef enum _Outbuf_Depth Outbuf_Depth; |
||||
|
||||
|
||||
struct _Outbuf |
||||
{ |
||||
int width; |
||||
int height; |
||||
int rot; |
||||
Outbuf_Depth depth; |
||||
|
||||
struct { |
||||
struct { |
||||
HWND window; |
||||
LPDIRECT3D9 object; |
||||
LPDIRECT3DDEVICE9 device; |
||||
LPD3DXSPRITE sprite; |
||||
LPDIRECT3DTEXTURE9 texture; |
||||
int depth; |
||||
} d3d; |
||||
struct { |
||||
DATA32 r, g, b; |
||||
} mask; |
||||
|
||||
/* a list of pending regions to write to the target */ |
||||
Evas_List *pending_writes; |
||||
} priv; |
||||
}; |
||||
|
||||
struct _Direct3D_Output_Buffer |
||||
{ |
||||
void *image; |
||||
int x; |
||||
int y; |
||||
int width; |
||||
int height; |
||||
int depth; |
||||
int pitch; |
||||
}; |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
|
||||
/* Outbuf functions */ |
||||
void evas_direct3d_outbuf_init(void); |
||||
void evas_direct3d_outbuf_free(Outbuf *buf); |
||||
Outbuf *evas_direct3d_outbuf_setup_d3d(int width, |
||||
int height, |
||||
int rotation, |
||||
Outbuf_Depth depth, |
||||
HWND window, |
||||
LPDIRECT3D9 object, |
||||
LPDIRECT3DDEVICE9 device, |
||||
LPD3DXSPRITE sprite, |
||||
LPDIRECT3DTEXTURE9 texture, |
||||
int w_depth); |
||||
RGBA_Image *evas_direct3d_outbuf_new_region_for_update(Outbuf *buf, |
||||
int x, |
||||
int y, |
||||
int width, |
||||
int height, |
||||
int *cx, |
||||
int *cy, |
||||
int *cw, |
||||
int *ch); |
||||
void evas_direct3d_outbuf_free_region_for_update(Outbuf *buf, |
||||
RGBA_Image *update); |
||||
void evas_direct3d_outbuf_flush(Outbuf *buf); |
||||
void evas_direct3d_outbuf_push_updated_region(Outbuf *buf, |
||||
RGBA_Image *update, |
||||
int x, |
||||
int y, |
||||
int width, |
||||
int height); |
||||
void evas_direct3d_outbuf_reconfigure(Outbuf *buf, |
||||
int width, |
||||
int height, |
||||
int rotation, |
||||
Outbuf_Depth depth); |
||||
int evas_direct3d_outbuf_width_get(Outbuf *buf); |
||||
int evas_direct3d_outbuf_height_get(Outbuf *buf); |
||||
Outbuf_Depth evas_direct3d_outbuf_depth_get(Outbuf *buf); |
||||
int evas_direct3d_outbuf_rot_get(Outbuf *buf); |
||||
|
||||
/* Output Buffer functions */ |
||||
Direct3D_Output_Buffer *evas_direct3d_output_buffer_new(int depth, |
||||
int width, |
||||
int height, |
||||
void *data); |
||||
void evas_direct3d_output_buffer_free(Direct3D_Output_Buffer *d3dob); |
||||
void evas_direct3d_output_buffer_paste(Direct3D_Output_Buffer *d3dob, |
||||
DATA8 *d3d_data, |
||||
int d3d_width, |
||||
int d3d_height, |
||||
int d3d_pitch, |
||||
int x, |
||||
int y); |
||||
DATA8 *evas_direct3d_output_buffer_data(Direct3D_Output_Buffer *d3dob, |
||||
int *bytes_per_line_ret); |
||||
int evas_direct3d_output_buffer_depth(Direct3D_Output_Buffer *d3dob); |
||||
|
||||
|
||||
int evas_direct3d_masks_get(Outbuf *buf); |
||||
void *evas_direct3d_lock(Outbuf *buf, int *d3d_width, int *d3d_height, int *d3d_pitch); |
||||
void evas_direct3d_unlock(Outbuf *buf); |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
|
||||
#endif /* __EVAS_ENGINE_H__ */ |
@ -0,0 +1,335 @@ |
||||
#include "evas_engine.h" |
||||
|
||||
|
||||
void |
||||
evas_direct3d_outbuf_init(void) |
||||
{ |
||||
} |
||||
|
||||
void |
||||
evas_direct3d_outbuf_free(Outbuf *buf) |
||||
{ |
||||
free(buf); |
||||
} |
||||
|
||||
Outbuf * |
||||
evas_direct3d_outbuf_setup_d3d(int width, |
||||
int height, |
||||
int rotation, |
||||
Outbuf_Depth depth, |
||||
HWND window, |
||||
LPDIRECT3D9 object, |
||||
LPDIRECT3DDEVICE9 device, |
||||
LPD3DXSPRITE sprite, |
||||
LPDIRECT3DTEXTURE9 texture, |
||||
int w_depth) |
||||
{ |
||||
Outbuf *buf; |
||||
|
||||
buf = (Outbuf *)calloc(1, sizeof(Outbuf)); |
||||
if (!buf) |
||||
return NULL; |
||||
|
||||
buf->width = width; |
||||
buf->height = height; |
||||
buf->depth = depth; |
||||
buf->rot = rotation; |
||||
|
||||
buf->priv.d3d.window = window; |
||||
buf->priv.d3d.object = object; |
||||
buf->priv.d3d.device = device; |
||||
buf->priv.d3d.sprite = sprite; |
||||
buf->priv.d3d.texture = texture; |
||||
buf->priv.d3d.depth = w_depth; |
||||
|
||||
{ |
||||
Gfx_Func_Convert conv_func; |
||||
Direct3D_Output_Buffer *d3dob; |
||||
|
||||
d3dob = evas_direct3d_output_buffer_new(buf->priv.d3d.depth, 1, 1, NULL); |
||||
|
||||
conv_func = NULL; |
||||
if (d3dob) |
||||
{ |
||||
if (evas_direct3d_masks_get(buf)) |
||||
{ |
||||
if ((rotation == 0) || (rotation == 180)) |
||||
conv_func = evas_common_convert_func_get(0, |
||||
width, |
||||
height, |
||||
evas_direct3d_output_buffer_depth (d3dob), |
||||
buf->priv.mask.r, |
||||
buf->priv.mask.g, |
||||
buf->priv.mask.b, |
||||
PAL_MODE_NONE, |
||||
rotation); |
||||
else if ((rotation == 90) || (rotation == 270)) |
||||
conv_func = evas_common_convert_func_get(0, |
||||
height, |
||||
width, |
||||
evas_direct3d_output_buffer_depth (d3dob), |
||||
buf->priv.mask.r, |
||||
buf->priv.mask.g, |
||||
buf->priv.mask.b, |
||||
PAL_MODE_NONE, |
||||
rotation); |
||||
} |
||||
evas_direct3d_output_buffer_free(d3dob); |
||||
if (!conv_func) |
||||
{ |
||||
printf(".[ Evas Error ].\n" |
||||
" {\n" |
||||
" At depth %i:\n" |
||||
" RGB format mask: %08x, %08x, %08x\n" |
||||
" Not supported by and compiled in converters!\n" |
||||
" }\n", |
||||
buf->priv.d3d.depth, |
||||
buf->priv.mask.r, |
||||
buf->priv.mask.g, |
||||
buf->priv.mask.b); |
||||
} |
||||
} |
||||
} |
||||
|
||||
return buf; |
||||
} |
||||
|
||||
RGBA_Image * |
||||
evas_direct3d_outbuf_new_region_for_update(Outbuf *buf, |
||||
int x, |
||||
int y, |
||||
int width, |
||||
int height, |
||||
int *cx, |
||||
int *cy, |
||||
int *cw, |
||||
int *ch) |
||||
{ |
||||
RGBA_Image *im; |
||||
Direct3D_Output_Buffer *d3dob = NULL; |
||||
int bpl = 0; |
||||
|
||||
*cx = 0; |
||||
*cy = 0; |
||||
*cw = width; |
||||
*ch = height; |
||||
|
||||
if ((buf->rot == 0) && |
||||
(buf->priv.mask.r == 0xff0000) && |
||||
(buf->priv.mask.g == 0x00ff00) && |
||||
(buf->priv.mask.b == 0x0000ff)) |
||||
{ |
||||
im = evas_cache_image_empty(evas_common_image_cache_get()); |
||||
im->image->w = width; |
||||
im->image->h = height; |
||||
im->image->data = NULL; |
||||
im->image->no_free = 1; |
||||
d3dob = evas_direct3d_output_buffer_new(buf->priv.d3d.depth, |
||||
width, |
||||
height, |
||||
NULL); |
||||
im->extended_info = d3dob; |
||||
im->image->data = (DATA32 *)evas_direct3d_output_buffer_data(d3dob, &bpl); |
||||
} |
||||
else |
||||
{ |
||||
im = evas_cache_image_empty(evas_common_image_cache_get()); |
||||
im->image->w = width; |
||||
im->image->h = height; |
||||
evas_common_image_surface_alloc(im->image); |
||||
im->extended_info = d3dob; |
||||
if ((buf->rot == 0) || (buf->rot == 180)) |
||||
d3dob = evas_direct3d_output_buffer_new(buf->priv.d3d.depth, |
||||
width, |
||||
height, |
||||
NULL); |
||||
else if ((buf->rot == 90) || (buf->rot == 270)) |
||||
d3dob = evas_direct3d_output_buffer_new(buf->priv.d3d.depth, |
||||
width, |
||||
height, |
||||
NULL); |
||||
im->extended_info = d3dob; |
||||
} |
||||
|
||||
buf->priv.pending_writes = evas_list_append(buf->priv.pending_writes, im); |
||||
|
||||
return im; |
||||
} |
||||
|
||||
void |
||||
evas_direct3d_outbuf_free_region_for_update(Outbuf *buf, |
||||
RGBA_Image *update) |
||||
{ |
||||
/* no need to do anything - they are cleaned up on flush */ |
||||
} |
||||
|
||||
void |
||||
evas_direct3d_outbuf_flush(Outbuf *buf) |
||||
{ |
||||
Evas_List *l; |
||||
void *d3d_data; |
||||
int d3d_width; |
||||
int d3d_height; |
||||
int d3d_pitch; |
||||
|
||||
/* lock the texture */ |
||||
if (!(d3d_data = evas_direct3d_lock(buf, |
||||
&d3d_width, &d3d_height, &d3d_pitch))) |
||||
goto free_images; |
||||
|
||||
/* copy safely the images that need to be drawn onto the back surface */ |
||||
for (l = buf->priv.pending_writes; l; l = l->next) |
||||
{ |
||||
RGBA_Image *im; |
||||
Direct3D_Output_Buffer *d3dob; |
||||
|
||||
im = l->data; |
||||
d3dob = im->extended_info; |
||||
/* paste now */ |
||||
evas_direct3d_output_buffer_paste(d3dob, |
||||
d3d_data, |
||||
d3d_width, |
||||
d3d_height, |
||||
d3d_pitch, |
||||
d3dob->x, |
||||
d3dob->y); |
||||
} |
||||
|
||||
/* unlock the texture */ |
||||
evas_direct3d_unlock(buf); |
||||
|
||||
free_images: |
||||
while (buf->priv.pending_writes) |
||||
{ |
||||
RGBA_Image *im; |
||||
Direct3D_Output_Buffer *d3dob; |
||||
|
||||
im = buf->priv.pending_writes->data; |
||||
buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes, |
||||
buf->priv.pending_writes); |
||||
d3dob = im->extended_info; |
||||
evas_cache_image_drop(im); |
||||
if (d3dob) evas_direct3d_output_buffer_free(d3dob); |
||||
} |
||||
evas_common_cpu_end_opt(); |
||||
} |
||||
|
||||
void |
||||
evas_direct3d_outbuf_push_updated_region(Outbuf *buf, |
||||
RGBA_Image *update, |
||||
int x, |
||||
int y, |
||||
int width, |
||||
int height) |
||||
{ |
||||
Gfx_Func_Convert conv_func; |
||||
Direct3D_Output_Buffer *d3dob; |
||||
DATA32 *src_data; |
||||
void *data; |
||||
int bpl = 0; |
||||
|
||||
conv_func = NULL; |
||||
d3dob = update->extended_info; |
||||
|
||||
if ((buf->rot == 0) || (buf->rot == 180)) |
||||
conv_func = evas_common_convert_func_get(NULL, |
||||
width, |
||||
height, |
||||
evas_direct3d_output_buffer_depth(d3dob), |
||||
buf->priv.mask.r, |
||||
buf->priv.mask.g, |
||||
buf->priv.mask.b, |
||||
PAL_MODE_NONE, |
||||
buf->rot); |
||||
else if ((buf->rot == 90) || (buf->rot == 270)) |
||||
conv_func = evas_common_convert_func_get(NULL, |
||||
height, |
||||
width, |
||||
evas_direct3d_output_buffer_depth(d3dob), |
||||
buf->priv.mask.r, |
||||
buf->priv.mask.g, |
||||
buf->priv.mask.b, |
||||
PAL_MODE_NONE, |
||||
buf->rot); |
||||
|
||||
if (!conv_func) return; |
||||
|
||||
data = evas_direct3d_output_buffer_data(d3dob, &bpl); |
||||
src_data = update->image->data; |
||||
if (buf->rot == 0) |
||||
{ |
||||
d3dob->x = x; |
||||
d3dob->y = y; |
||||
} |
||||
else if (buf->rot == 90) |
||||
{ |
||||
d3dob->x = y; |
||||
d3dob->y = buf->width - x - width; |
||||
} |
||||
else if (buf->rot == 180) |
||||
{ |
||||
d3dob->x = buf->width - x - width; |
||||
d3dob->y = buf->height - y - height; |
||||
} |
||||
else if (buf->rot == 270) |
||||
{ |
||||
d3dob->x = buf->height - y - height; |
||||
d3dob->y = x; |
||||
} |
||||
if ((buf->rot == 0) || (buf->rot == 180)) |
||||
{ |
||||
d3dob->width = width; |
||||
d3dob->height = height; |
||||
} |
||||
else if ((buf->rot == 90) || (buf->rot == 270)) |
||||
{ |
||||
d3dob->width = height; |
||||
d3dob->height = width; |
||||
} |
||||
|
||||
if (data != src_data) |
||||
conv_func(src_data, data, |
||||
0, |
||||
bpl / |
||||
((evas_direct3d_output_buffer_depth(d3dob))) - d3dob->width, |
||||
d3dob->width, d3dob->height, x, y, NULL); |
||||
} |
||||
|
||||
void |
||||
evas_direct3d_outbuf_reconfigure(Outbuf *buf, |
||||
int width, |
||||
int height, |
||||
int rotation, |
||||
Outbuf_Depth depth) |
||||
{ |
||||
if ((width == buf->width) && (height == buf->height) && |
||||
(rotation == buf->rot) && (depth == buf->depth)) |
||||
return; |
||||
buf->width = width; |
||||
buf->height = height; |
||||
buf->rot = rotation; |
||||
} |
||||
|
||||
int |
||||
evas_direct3d_outbuf_width_get(Outbuf *buf) |
||||
{ |
||||
return buf->width; |
||||
} |
||||
|
||||
int |
||||
evas_direct3d_outbuf_height_get(Outbuf *buf) |
||||
{ |
||||
return buf->height; |
||||
} |
||||
|
||||
Outbuf_Depth |
||||
evas_direct3d_outbuf_depth_get(Outbuf *buf) |
||||
{ |
||||
return buf->depth; |
||||
} |
||||
|
||||
int |
||||
evas_direct3d_outbuf_rot_get(Outbuf *buf) |
||||
{ |
||||
return buf->rot; |
||||
} |
Loading…
Reference in new issue