mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 22:00:13 +01:00
st/vega: Remove.
OpenVG API seems to have dwindled away. The code would still be interesting if we wanted to implement NV_path_rendering but given the trend of the next gen graphics APIs, it seems unlikely that this becomes ARB or core. v2: Remove a few "openvg" references left, per Emil Velikov. Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com> v3: Update release notes.
This commit is contained in:
parent
5564c361b5
commit
3acd7a34ab
81 changed files with 3 additions and 22104 deletions
31
configure.ac
31
configure.ac
|
|
@ -692,11 +692,6 @@ AC_ARG_ENABLE([gles2],
|
||||||
[enable support for OpenGL ES 2.x API @<:@default=disabled@:>@])],
|
[enable support for OpenGL ES 2.x API @<:@default=disabled@:>@])],
|
||||||
[enable_gles2="$enableval"],
|
[enable_gles2="$enableval"],
|
||||||
[enable_gles2=no])
|
[enable_gles2=no])
|
||||||
AC_ARG_ENABLE([openvg],
|
|
||||||
[AS_HELP_STRING([--enable-openvg],
|
|
||||||
[enable support for OpenVG API @<:@default=disabled@:>@])],
|
|
||||||
[enable_openvg="$enableval"],
|
|
||||||
[enable_openvg=no])
|
|
||||||
|
|
||||||
AC_ARG_ENABLE([dri],
|
AC_ARG_ENABLE([dri],
|
||||||
[AS_HELP_STRING([--enable-dri],
|
[AS_HELP_STRING([--enable-dri],
|
||||||
|
|
@ -827,7 +822,6 @@ if test "x$enable_opengl" = xno -a \
|
||||||
"x$enable_gles1" = xno -a \
|
"x$enable_gles1" = xno -a \
|
||||||
"x$enable_gles2" = xno -a \
|
"x$enable_gles2" = xno -a \
|
||||||
"x$enable_nine" = xno -a \
|
"x$enable_nine" = xno -a \
|
||||||
"x$enable_openvg" = xno -a \
|
|
||||||
"x$enable_xa" = xno -a \
|
"x$enable_xa" = xno -a \
|
||||||
"x$enable_xvmc" = xno -a \
|
"x$enable_xvmc" = xno -a \
|
||||||
"x$enable_vdpau" = xno -a \
|
"x$enable_vdpau" = xno -a \
|
||||||
|
|
@ -1547,29 +1541,6 @@ if test "x$enable_xa" = xyes; then
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL(HAVE_ST_XA, test "x$enable_xa" = xyes)
|
AM_CONDITIONAL(HAVE_ST_XA, test "x$enable_xa" = xyes)
|
||||||
|
|
||||||
dnl
|
|
||||||
dnl OpenVG configuration
|
|
||||||
dnl
|
|
||||||
VG_LIB_DEPS=""
|
|
||||||
|
|
||||||
if test "x$enable_openvg" = xyes; then
|
|
||||||
if test "x$enable_egl" = xno; then
|
|
||||||
AC_MSG_ERROR([cannot enable OpenVG without EGL])
|
|
||||||
fi
|
|
||||||
if test -z "$with_gallium_drivers"; then
|
|
||||||
AC_MSG_ERROR([cannot enable OpenVG without Gallium])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_MSG_ERROR([Cannot enable OpenVG, because egl_gallium has been removed and
|
|
||||||
OpenVG has not been integrated into standard libEGL yet])
|
|
||||||
|
|
||||||
EGL_CLIENT_APIS="$EGL_CLIENT_APIS "'$(VG_LIB)'
|
|
||||||
VG_LIB_DEPS="$VG_LIB_DEPS $SELINUX_LIBS $PTHREAD_LIBS"
|
|
||||||
VG_PC_LIB_PRIV="-lm $CLOCK_LIB $PTHREAD_LIBS $DLOPEN_LIBS"
|
|
||||||
AC_SUBST([VG_PC_LIB_PRIV])
|
|
||||||
fi
|
|
||||||
AM_CONDITIONAL(HAVE_OPENVG, test "x$enable_openvg" = xyes)
|
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl Gallium G3DVL configuration
|
dnl Gallium G3DVL configuration
|
||||||
dnl
|
dnl
|
||||||
|
|
@ -2400,7 +2371,6 @@ AC_CONFIG_FILES([Makefile
|
||||||
src/gallium/state_trackers/osmesa/Makefile
|
src/gallium/state_trackers/osmesa/Makefile
|
||||||
src/gallium/state_trackers/va/Makefile
|
src/gallium/state_trackers/va/Makefile
|
||||||
src/gallium/state_trackers/vdpau/Makefile
|
src/gallium/state_trackers/vdpau/Makefile
|
||||||
src/gallium/state_trackers/vega/Makefile
|
|
||||||
src/gallium/state_trackers/xa/Makefile
|
src/gallium/state_trackers/xa/Makefile
|
||||||
src/gallium/state_trackers/xvmc/Makefile
|
src/gallium/state_trackers/xvmc/Makefile
|
||||||
src/gallium/targets/d3dadapter9/Makefile
|
src/gallium/targets/d3dadapter9/Makefile
|
||||||
|
|
@ -2478,7 +2448,6 @@ echo " includedir: $includedir"
|
||||||
dnl API info
|
dnl API info
|
||||||
echo ""
|
echo ""
|
||||||
echo " OpenGL: $enable_opengl (ES1: $enable_gles1 ES2: $enable_gles2)"
|
echo " OpenGL: $enable_opengl (ES1: $enable_gles1 ES2: $enable_gles2)"
|
||||||
echo " OpenVG: $enable_openvg"
|
|
||||||
|
|
||||||
dnl Driver info
|
dnl Driver info
|
||||||
echo ""
|
echo ""
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@
|
||||||
<li><a href="shading.html" target="_parent">Shading Language</a>
|
<li><a href="shading.html" target="_parent">Shading Language</a>
|
||||||
<li><a href="egl.html" target="_parent">EGL</a>
|
<li><a href="egl.html" target="_parent">EGL</a>
|
||||||
<li><a href="opengles.html" target="_parent">OpenGL ES</a>
|
<li><a href="opengles.html" target="_parent">OpenGL ES</a>
|
||||||
<li><a href="openvg.html" target="_parent">OpenVG / Vega</a>
|
|
||||||
<li><a href="envvars.html" target="_parent">Environment Variables</a>
|
<li><a href="envvars.html" target="_parent">Environment Variables</a>
|
||||||
<li><a href="osmesa.html" target="_parent">Off-Screen Rendering</a>
|
<li><a href="osmesa.html" target="_parent">Off-Screen Rendering</a>
|
||||||
<li><a href="debugging.html" target="_parent">Debugging Tips</a>
|
<li><a href="debugging.html" target="_parent">Debugging Tips</a>
|
||||||
|
|
|
||||||
|
|
@ -112,13 +112,6 @@ is required if applications mix OpenGL and OpenGL ES.</p>
|
||||||
|
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt><code>--enable-openvg</code></dt>
|
|
||||||
<dd>
|
|
||||||
|
|
||||||
<p>OpenVG must be explicitly enabled by this option.</p>
|
|
||||||
|
|
||||||
</dd>
|
|
||||||
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<h2>Use EGL</h2>
|
<h2>Use EGL</h2>
|
||||||
|
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
|
||||||
<title>OpenVG State Tracker</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="mesa.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="header">
|
|
||||||
<h1>The Mesa 3D Graphics Library</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<iframe src="contents.html"></iframe>
|
|
||||||
<div class="content">
|
|
||||||
|
|
||||||
<h1>OpenVG State Tracker</h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The current version of the OpenVG state tracker implements OpenVG 1.1.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
More information about OpenVG can be found at
|
|
||||||
<a href="http://www.khronos.org/openvg/">
|
|
||||||
http://www.khronos.org/openvg/</a> .
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The OpenVG state tracker depends on the Gallium architecture and a working EGL implementation.
|
|
||||||
Please refer to <a href="egl.html">Mesa EGL</a> for more information about EGL.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2>Building the library</h2>
|
|
||||||
<ol>
|
|
||||||
<li>Run <code>configure</code> with <code>--enable-openvg</code> and
|
|
||||||
<code>--enable-gallium-egl</code>. If you do not need OpenGL, you can add
|
|
||||||
<code>--disable-opengl</code> to save the compilation time.</li>
|
|
||||||
|
|
||||||
<li>Build and install Mesa as usual.</li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<h3>Sample build</h3>
|
|
||||||
A sample build looks as follows:
|
|
||||||
<pre>
|
|
||||||
$ ./configure --disable-opengl --enable-openvg --enable-gallium-egl
|
|
||||||
$ make
|
|
||||||
$ make install
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>It will install <code>libOpenVG.so</code>, <code>libEGL.so</code>, and one
|
|
||||||
or more EGL drivers.</p>
|
|
||||||
|
|
||||||
<h2>OpenVG Demos</h2>
|
|
||||||
|
|
||||||
<p>OpenVG demos can be found in mesa/demos repository.</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -61,6 +61,7 @@ TBD.
|
||||||
<ul>
|
<ul>
|
||||||
<li>Removed classic Windows software rasterizer.</li>
|
<li>Removed classic Windows software rasterizer.</li>
|
||||||
<li>Removed egl_gallium EGL driver.</li>
|
<li>Removed egl_gallium EGL driver.</li>
|
||||||
|
<li>Removed OpenVG support.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ c49c19c2bbef4f3b7f1389974dff25f4 MesaGLUT-7.6.zip
|
||||||
|
|
||||||
<h2>New features</h2>
|
<h2>New features</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="../openvg.html">OpenVG</a> front-end (state tracker for Gallium).
|
<li>OpenVG front-end (state tracker for Gallium).
|
||||||
This was written by Zack Rusin at Tungsten Graphics.
|
This was written by Zack Rusin at Tungsten Graphics.
|
||||||
<li>GL_ARB_vertex_array_object and GL_APPLE_vertex_array_object extensions
|
<li>GL_ARB_vertex_array_object and GL_APPLE_vertex_array_object extensions
|
||||||
(supported in Gallium drivers, Intel DRI drivers, and software drivers)</li>
|
(supported in Gallium drivers, Intel DRI drivers, and software drivers)</li>
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,6 @@ each directory.
|
||||||
<li><b>dri</b> - Meta state tracker for DRI drivers
|
<li><b>dri</b> - Meta state tracker for DRI drivers
|
||||||
<li><b>glx</b> - Meta state tracker for GLX
|
<li><b>glx</b> - Meta state tracker for GLX
|
||||||
<li><b>vdpau</b> - VDPAU state tracker
|
<li><b>vdpau</b> - VDPAU state tracker
|
||||||
<li><b>vega</b> - OpenVG 1.x state tracker
|
|
||||||
<li><b>wgl</b> -
|
<li><b>wgl</b> -
|
||||||
<li><b>xorg</b> - Meta state tracker for Xorg video drivers
|
<li><b>xorg</b> - Meta state tracker for Xorg video drivers
|
||||||
<li><b>xvmc</b> - XvMC state tracker
|
<li><b>xvmc</b> - XvMC state tracker
|
||||||
|
|
|
||||||
|
|
@ -1,746 +0,0 @@
|
||||||
/* $Revision: 9203 $ on $Date:: 2009-10-07 02:21:52 -0700 #$ */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* OpenVG 1.1 Reference Implementation
|
|
||||||
* -------------------------------------
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008 The Khronos Group Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and /or associated documentation files
|
|
||||||
* (the "Materials "), to deal in the Materials without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Materials,
|
|
||||||
* and to permit persons to whom the Materials are furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Materials.
|
|
||||||
*
|
|
||||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
|
|
||||||
* THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
*
|
|
||||||
*//**
|
|
||||||
* \file
|
|
||||||
* \brief OpenVG 1.1 API.
|
|
||||||
*//*-------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef _OPENVG_H
|
|
||||||
#define _OPENVG_H
|
|
||||||
|
|
||||||
#include <VG/vgplatform.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define OPENVG_VERSION_1_0 1
|
|
||||||
#define OPENVG_VERSION_1_0_1 1
|
|
||||||
#define OPENVG_VERSION_1_1 2
|
|
||||||
|
|
||||||
#ifndef VG_MAXSHORT
|
|
||||||
#define VG_MAXSHORT 0x7FFF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VG_MAXINT
|
|
||||||
#define VG_MAXINT 0x7FFFFFFF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VG_MAX_ENUM
|
|
||||||
#define VG_MAX_ENUM 0x7FFFFFFF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef VGuint VGHandle;
|
|
||||||
|
|
||||||
typedef VGHandle VGPath;
|
|
||||||
typedef VGHandle VGImage;
|
|
||||||
typedef VGHandle VGMaskLayer;
|
|
||||||
typedef VGHandle VGFont;
|
|
||||||
typedef VGHandle VGPaint;
|
|
||||||
|
|
||||||
#define VG_INVALID_HANDLE ((VGHandle)0)
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_FALSE = 0,
|
|
||||||
VG_TRUE = 1,
|
|
||||||
|
|
||||||
VG_BOOLEAN_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGboolean;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_NO_ERROR = 0,
|
|
||||||
VG_BAD_HANDLE_ERROR = 0x1000,
|
|
||||||
VG_ILLEGAL_ARGUMENT_ERROR = 0x1001,
|
|
||||||
VG_OUT_OF_MEMORY_ERROR = 0x1002,
|
|
||||||
VG_PATH_CAPABILITY_ERROR = 0x1003,
|
|
||||||
VG_UNSUPPORTED_IMAGE_FORMAT_ERROR = 0x1004,
|
|
||||||
VG_UNSUPPORTED_PATH_FORMAT_ERROR = 0x1005,
|
|
||||||
VG_IMAGE_IN_USE_ERROR = 0x1006,
|
|
||||||
VG_NO_CONTEXT_ERROR = 0x1007,
|
|
||||||
|
|
||||||
VG_ERROR_CODE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGErrorCode;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
/* Mode settings */
|
|
||||||
VG_MATRIX_MODE = 0x1100,
|
|
||||||
VG_FILL_RULE = 0x1101,
|
|
||||||
VG_IMAGE_QUALITY = 0x1102,
|
|
||||||
VG_RENDERING_QUALITY = 0x1103,
|
|
||||||
VG_BLEND_MODE = 0x1104,
|
|
||||||
VG_IMAGE_MODE = 0x1105,
|
|
||||||
|
|
||||||
/* Scissoring rectangles */
|
|
||||||
VG_SCISSOR_RECTS = 0x1106,
|
|
||||||
|
|
||||||
/* Color Transformation */
|
|
||||||
VG_COLOR_TRANSFORM = 0x1170,
|
|
||||||
VG_COLOR_TRANSFORM_VALUES = 0x1171,
|
|
||||||
|
|
||||||
/* Stroke parameters */
|
|
||||||
VG_STROKE_LINE_WIDTH = 0x1110,
|
|
||||||
VG_STROKE_CAP_STYLE = 0x1111,
|
|
||||||
VG_STROKE_JOIN_STYLE = 0x1112,
|
|
||||||
VG_STROKE_MITER_LIMIT = 0x1113,
|
|
||||||
VG_STROKE_DASH_PATTERN = 0x1114,
|
|
||||||
VG_STROKE_DASH_PHASE = 0x1115,
|
|
||||||
VG_STROKE_DASH_PHASE_RESET = 0x1116,
|
|
||||||
|
|
||||||
/* Edge fill color for VG_TILE_FILL tiling mode */
|
|
||||||
VG_TILE_FILL_COLOR = 0x1120,
|
|
||||||
|
|
||||||
/* Color for vgClear */
|
|
||||||
VG_CLEAR_COLOR = 0x1121,
|
|
||||||
|
|
||||||
/* Glyph origin */
|
|
||||||
VG_GLYPH_ORIGIN = 0x1122,
|
|
||||||
|
|
||||||
/* Enable/disable alpha masking and scissoring */
|
|
||||||
VG_MASKING = 0x1130,
|
|
||||||
VG_SCISSORING = 0x1131,
|
|
||||||
|
|
||||||
/* Pixel layout information */
|
|
||||||
VG_PIXEL_LAYOUT = 0x1140,
|
|
||||||
VG_SCREEN_LAYOUT = 0x1141,
|
|
||||||
|
|
||||||
/* Source format selection for image filters */
|
|
||||||
VG_FILTER_FORMAT_LINEAR = 0x1150,
|
|
||||||
VG_FILTER_FORMAT_PREMULTIPLIED = 0x1151,
|
|
||||||
|
|
||||||
/* Destination write enable mask for image filters */
|
|
||||||
VG_FILTER_CHANNEL_MASK = 0x1152,
|
|
||||||
|
|
||||||
/* Implementation limits (read-only) */
|
|
||||||
VG_MAX_SCISSOR_RECTS = 0x1160,
|
|
||||||
VG_MAX_DASH_COUNT = 0x1161,
|
|
||||||
VG_MAX_KERNEL_SIZE = 0x1162,
|
|
||||||
VG_MAX_SEPARABLE_KERNEL_SIZE = 0x1163,
|
|
||||||
VG_MAX_COLOR_RAMP_STOPS = 0x1164,
|
|
||||||
VG_MAX_IMAGE_WIDTH = 0x1165,
|
|
||||||
VG_MAX_IMAGE_HEIGHT = 0x1166,
|
|
||||||
VG_MAX_IMAGE_PIXELS = 0x1167,
|
|
||||||
VG_MAX_IMAGE_BYTES = 0x1168,
|
|
||||||
VG_MAX_FLOAT = 0x1169,
|
|
||||||
VG_MAX_GAUSSIAN_STD_DEVIATION = 0x116A,
|
|
||||||
|
|
||||||
VG_PARAM_TYPE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGParamType;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_RENDERING_QUALITY_NONANTIALIASED = 0x1200,
|
|
||||||
VG_RENDERING_QUALITY_FASTER = 0x1201,
|
|
||||||
VG_RENDERING_QUALITY_BETTER = 0x1202, /* Default */
|
|
||||||
|
|
||||||
VG_RENDERING_QUALITY_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGRenderingQuality;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_PIXEL_LAYOUT_UNKNOWN = 0x1300,
|
|
||||||
VG_PIXEL_LAYOUT_RGB_VERTICAL = 0x1301,
|
|
||||||
VG_PIXEL_LAYOUT_BGR_VERTICAL = 0x1302,
|
|
||||||
VG_PIXEL_LAYOUT_RGB_HORIZONTAL = 0x1303,
|
|
||||||
VG_PIXEL_LAYOUT_BGR_HORIZONTAL = 0x1304,
|
|
||||||
|
|
||||||
VG_PIXEL_LAYOUT_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPixelLayout;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_MATRIX_PATH_USER_TO_SURFACE = 0x1400,
|
|
||||||
VG_MATRIX_IMAGE_USER_TO_SURFACE = 0x1401,
|
|
||||||
VG_MATRIX_FILL_PAINT_TO_USER = 0x1402,
|
|
||||||
VG_MATRIX_STROKE_PAINT_TO_USER = 0x1403,
|
|
||||||
VG_MATRIX_GLYPH_USER_TO_SURFACE = 0x1404,
|
|
||||||
|
|
||||||
VG_MATRIX_MODE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGMatrixMode;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_CLEAR_MASK = 0x1500,
|
|
||||||
VG_FILL_MASK = 0x1501,
|
|
||||||
VG_SET_MASK = 0x1502,
|
|
||||||
VG_UNION_MASK = 0x1503,
|
|
||||||
VG_INTERSECT_MASK = 0x1504,
|
|
||||||
VG_SUBTRACT_MASK = 0x1505,
|
|
||||||
|
|
||||||
VG_MASK_OPERATION_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGMaskOperation;
|
|
||||||
|
|
||||||
#define VG_PATH_FORMAT_STANDARD 0
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_PATH_DATATYPE_S_8 = 0,
|
|
||||||
VG_PATH_DATATYPE_S_16 = 1,
|
|
||||||
VG_PATH_DATATYPE_S_32 = 2,
|
|
||||||
VG_PATH_DATATYPE_F = 3,
|
|
||||||
|
|
||||||
VG_PATH_DATATYPE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPathDatatype;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_ABSOLUTE = 0,
|
|
||||||
VG_RELATIVE = 1,
|
|
||||||
|
|
||||||
VG_PATH_ABS_REL_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPathAbsRel;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_CLOSE_PATH = ( 0 << 1),
|
|
||||||
VG_MOVE_TO = ( 1 << 1),
|
|
||||||
VG_LINE_TO = ( 2 << 1),
|
|
||||||
VG_HLINE_TO = ( 3 << 1),
|
|
||||||
VG_VLINE_TO = ( 4 << 1),
|
|
||||||
VG_QUAD_TO = ( 5 << 1),
|
|
||||||
VG_CUBIC_TO = ( 6 << 1),
|
|
||||||
VG_SQUAD_TO = ( 7 << 1),
|
|
||||||
VG_SCUBIC_TO = ( 8 << 1),
|
|
||||||
VG_SCCWARC_TO = ( 9 << 1),
|
|
||||||
VG_SCWARC_TO = (10 << 1),
|
|
||||||
VG_LCCWARC_TO = (11 << 1),
|
|
||||||
VG_LCWARC_TO = (12 << 1),
|
|
||||||
|
|
||||||
VG_PATH_SEGMENT_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPathSegment;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_MOVE_TO_ABS = VG_MOVE_TO | VG_ABSOLUTE,
|
|
||||||
VG_MOVE_TO_REL = VG_MOVE_TO | VG_RELATIVE,
|
|
||||||
VG_LINE_TO_ABS = VG_LINE_TO | VG_ABSOLUTE,
|
|
||||||
VG_LINE_TO_REL = VG_LINE_TO | VG_RELATIVE,
|
|
||||||
VG_HLINE_TO_ABS = VG_HLINE_TO | VG_ABSOLUTE,
|
|
||||||
VG_HLINE_TO_REL = VG_HLINE_TO | VG_RELATIVE,
|
|
||||||
VG_VLINE_TO_ABS = VG_VLINE_TO | VG_ABSOLUTE,
|
|
||||||
VG_VLINE_TO_REL = VG_VLINE_TO | VG_RELATIVE,
|
|
||||||
VG_QUAD_TO_ABS = VG_QUAD_TO | VG_ABSOLUTE,
|
|
||||||
VG_QUAD_TO_REL = VG_QUAD_TO | VG_RELATIVE,
|
|
||||||
VG_CUBIC_TO_ABS = VG_CUBIC_TO | VG_ABSOLUTE,
|
|
||||||
VG_CUBIC_TO_REL = VG_CUBIC_TO | VG_RELATIVE,
|
|
||||||
VG_SQUAD_TO_ABS = VG_SQUAD_TO | VG_ABSOLUTE,
|
|
||||||
VG_SQUAD_TO_REL = VG_SQUAD_TO | VG_RELATIVE,
|
|
||||||
VG_SCUBIC_TO_ABS = VG_SCUBIC_TO | VG_ABSOLUTE,
|
|
||||||
VG_SCUBIC_TO_REL = VG_SCUBIC_TO | VG_RELATIVE,
|
|
||||||
VG_SCCWARC_TO_ABS = VG_SCCWARC_TO | VG_ABSOLUTE,
|
|
||||||
VG_SCCWARC_TO_REL = VG_SCCWARC_TO | VG_RELATIVE,
|
|
||||||
VG_SCWARC_TO_ABS = VG_SCWARC_TO | VG_ABSOLUTE,
|
|
||||||
VG_SCWARC_TO_REL = VG_SCWARC_TO | VG_RELATIVE,
|
|
||||||
VG_LCCWARC_TO_ABS = VG_LCCWARC_TO | VG_ABSOLUTE,
|
|
||||||
VG_LCCWARC_TO_REL = VG_LCCWARC_TO | VG_RELATIVE,
|
|
||||||
VG_LCWARC_TO_ABS = VG_LCWARC_TO | VG_ABSOLUTE,
|
|
||||||
VG_LCWARC_TO_REL = VG_LCWARC_TO | VG_RELATIVE,
|
|
||||||
|
|
||||||
VG_PATH_COMMAND_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPathCommand;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_PATH_CAPABILITY_APPEND_FROM = (1 << 0),
|
|
||||||
VG_PATH_CAPABILITY_APPEND_TO = (1 << 1),
|
|
||||||
VG_PATH_CAPABILITY_MODIFY = (1 << 2),
|
|
||||||
VG_PATH_CAPABILITY_TRANSFORM_FROM = (1 << 3),
|
|
||||||
VG_PATH_CAPABILITY_TRANSFORM_TO = (1 << 4),
|
|
||||||
VG_PATH_CAPABILITY_INTERPOLATE_FROM = (1 << 5),
|
|
||||||
VG_PATH_CAPABILITY_INTERPOLATE_TO = (1 << 6),
|
|
||||||
VG_PATH_CAPABILITY_PATH_LENGTH = (1 << 7),
|
|
||||||
VG_PATH_CAPABILITY_POINT_ALONG_PATH = (1 << 8),
|
|
||||||
VG_PATH_CAPABILITY_TANGENT_ALONG_PATH = (1 << 9),
|
|
||||||
VG_PATH_CAPABILITY_PATH_BOUNDS = (1 << 10),
|
|
||||||
VG_PATH_CAPABILITY_PATH_TRANSFORMED_BOUNDS = (1 << 11),
|
|
||||||
VG_PATH_CAPABILITY_ALL = (1 << 12) - 1,
|
|
||||||
|
|
||||||
VG_PATH_CAPABILITIES_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPathCapabilities;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_PATH_FORMAT = 0x1600,
|
|
||||||
VG_PATH_DATATYPE = 0x1601,
|
|
||||||
VG_PATH_SCALE = 0x1602,
|
|
||||||
VG_PATH_BIAS = 0x1603,
|
|
||||||
VG_PATH_NUM_SEGMENTS = 0x1604,
|
|
||||||
VG_PATH_NUM_COORDS = 0x1605,
|
|
||||||
|
|
||||||
VG_PATH_PARAM_TYPE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPathParamType;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_CAP_BUTT = 0x1700,
|
|
||||||
VG_CAP_ROUND = 0x1701,
|
|
||||||
VG_CAP_SQUARE = 0x1702,
|
|
||||||
|
|
||||||
VG_CAP_STYLE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGCapStyle;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_JOIN_MITER = 0x1800,
|
|
||||||
VG_JOIN_ROUND = 0x1801,
|
|
||||||
VG_JOIN_BEVEL = 0x1802,
|
|
||||||
|
|
||||||
VG_JOIN_STYLE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGJoinStyle;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_EVEN_ODD = 0x1900,
|
|
||||||
VG_NON_ZERO = 0x1901,
|
|
||||||
|
|
||||||
VG_FILL_RULE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGFillRule;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_STROKE_PATH = (1 << 0),
|
|
||||||
VG_FILL_PATH = (1 << 1),
|
|
||||||
|
|
||||||
VG_PAINT_MODE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPaintMode;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
/* Color paint parameters */
|
|
||||||
VG_PAINT_TYPE = 0x1A00,
|
|
||||||
VG_PAINT_COLOR = 0x1A01,
|
|
||||||
VG_PAINT_COLOR_RAMP_SPREAD_MODE = 0x1A02,
|
|
||||||
VG_PAINT_COLOR_RAMP_PREMULTIPLIED = 0x1A07,
|
|
||||||
VG_PAINT_COLOR_RAMP_STOPS = 0x1A03,
|
|
||||||
|
|
||||||
/* Linear gradient paint parameters */
|
|
||||||
VG_PAINT_LINEAR_GRADIENT = 0x1A04,
|
|
||||||
|
|
||||||
/* Radial gradient paint parameters */
|
|
||||||
VG_PAINT_RADIAL_GRADIENT = 0x1A05,
|
|
||||||
|
|
||||||
/* Pattern paint parameters */
|
|
||||||
VG_PAINT_PATTERN_TILING_MODE = 0x1A06,
|
|
||||||
|
|
||||||
VG_PAINT_PARAM_TYPE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPaintParamType;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_PAINT_TYPE_COLOR = 0x1B00,
|
|
||||||
VG_PAINT_TYPE_LINEAR_GRADIENT = 0x1B01,
|
|
||||||
VG_PAINT_TYPE_RADIAL_GRADIENT = 0x1B02,
|
|
||||||
VG_PAINT_TYPE_PATTERN = 0x1B03,
|
|
||||||
|
|
||||||
VG_PAINT_TYPE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPaintType;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_COLOR_RAMP_SPREAD_PAD = 0x1C00,
|
|
||||||
VG_COLOR_RAMP_SPREAD_REPEAT = 0x1C01,
|
|
||||||
VG_COLOR_RAMP_SPREAD_REFLECT = 0x1C02,
|
|
||||||
|
|
||||||
VG_COLOR_RAMP_SPREAD_MODE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGColorRampSpreadMode;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_TILE_FILL = 0x1D00,
|
|
||||||
VG_TILE_PAD = 0x1D01,
|
|
||||||
VG_TILE_REPEAT = 0x1D02,
|
|
||||||
VG_TILE_REFLECT = 0x1D03,
|
|
||||||
|
|
||||||
VG_TILING_MODE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGTilingMode;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
/* RGB{A,X} channel ordering */
|
|
||||||
VG_sRGBX_8888 = 0,
|
|
||||||
VG_sRGBA_8888 = 1,
|
|
||||||
VG_sRGBA_8888_PRE = 2,
|
|
||||||
VG_sRGB_565 = 3,
|
|
||||||
VG_sRGBA_5551 = 4,
|
|
||||||
VG_sRGBA_4444 = 5,
|
|
||||||
VG_sL_8 = 6,
|
|
||||||
VG_lRGBX_8888 = 7,
|
|
||||||
VG_lRGBA_8888 = 8,
|
|
||||||
VG_lRGBA_8888_PRE = 9,
|
|
||||||
VG_lL_8 = 10,
|
|
||||||
VG_A_8 = 11,
|
|
||||||
VG_BW_1 = 12,
|
|
||||||
VG_A_1 = 13,
|
|
||||||
VG_A_4 = 14,
|
|
||||||
|
|
||||||
/* {A,X}RGB channel ordering */
|
|
||||||
VG_sXRGB_8888 = 0 | (1 << 6),
|
|
||||||
VG_sARGB_8888 = 1 | (1 << 6),
|
|
||||||
VG_sARGB_8888_PRE = 2 | (1 << 6),
|
|
||||||
VG_sARGB_1555 = 4 | (1 << 6),
|
|
||||||
VG_sARGB_4444 = 5 | (1 << 6),
|
|
||||||
VG_lXRGB_8888 = 7 | (1 << 6),
|
|
||||||
VG_lARGB_8888 = 8 | (1 << 6),
|
|
||||||
VG_lARGB_8888_PRE = 9 | (1 << 6),
|
|
||||||
|
|
||||||
/* BGR{A,X} channel ordering */
|
|
||||||
VG_sBGRX_8888 = 0 | (1 << 7),
|
|
||||||
VG_sBGRA_8888 = 1 | (1 << 7),
|
|
||||||
VG_sBGRA_8888_PRE = 2 | (1 << 7),
|
|
||||||
VG_sBGR_565 = 3 | (1 << 7),
|
|
||||||
VG_sBGRA_5551 = 4 | (1 << 7),
|
|
||||||
VG_sBGRA_4444 = 5 | (1 << 7),
|
|
||||||
VG_lBGRX_8888 = 7 | (1 << 7),
|
|
||||||
VG_lBGRA_8888 = 8 | (1 << 7),
|
|
||||||
VG_lBGRA_8888_PRE = 9 | (1 << 7),
|
|
||||||
|
|
||||||
/* {A,X}BGR channel ordering */
|
|
||||||
VG_sXBGR_8888 = 0 | (1 << 6) | (1 << 7),
|
|
||||||
VG_sABGR_8888 = 1 | (1 << 6) | (1 << 7),
|
|
||||||
VG_sABGR_8888_PRE = 2 | (1 << 6) | (1 << 7),
|
|
||||||
VG_sABGR_1555 = 4 | (1 << 6) | (1 << 7),
|
|
||||||
VG_sABGR_4444 = 5 | (1 << 6) | (1 << 7),
|
|
||||||
VG_lXBGR_8888 = 7 | (1 << 6) | (1 << 7),
|
|
||||||
VG_lABGR_8888 = 8 | (1 << 6) | (1 << 7),
|
|
||||||
VG_lABGR_8888_PRE = 9 | (1 << 6) | (1 << 7),
|
|
||||||
|
|
||||||
VG_IMAGE_FORMAT_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGImageFormat;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_IMAGE_QUALITY_NONANTIALIASED = (1 << 0),
|
|
||||||
VG_IMAGE_QUALITY_FASTER = (1 << 1),
|
|
||||||
VG_IMAGE_QUALITY_BETTER = (1 << 2),
|
|
||||||
|
|
||||||
VG_IMAGE_QUALITY_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGImageQuality;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_IMAGE_FORMAT = 0x1E00,
|
|
||||||
VG_IMAGE_WIDTH = 0x1E01,
|
|
||||||
VG_IMAGE_HEIGHT = 0x1E02,
|
|
||||||
|
|
||||||
VG_IMAGE_PARAM_TYPE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGImageParamType;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_DRAW_IMAGE_NORMAL = 0x1F00,
|
|
||||||
VG_DRAW_IMAGE_MULTIPLY = 0x1F01,
|
|
||||||
VG_DRAW_IMAGE_STENCIL = 0x1F02,
|
|
||||||
|
|
||||||
VG_IMAGE_MODE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGImageMode;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_RED = (1 << 3),
|
|
||||||
VG_GREEN = (1 << 2),
|
|
||||||
VG_BLUE = (1 << 1),
|
|
||||||
VG_ALPHA = (1 << 0),
|
|
||||||
|
|
||||||
VG_IMAGE_CHANNEL_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGImageChannel;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_BLEND_SRC = 0x2000,
|
|
||||||
VG_BLEND_SRC_OVER = 0x2001,
|
|
||||||
VG_BLEND_DST_OVER = 0x2002,
|
|
||||||
VG_BLEND_SRC_IN = 0x2003,
|
|
||||||
VG_BLEND_DST_IN = 0x2004,
|
|
||||||
VG_BLEND_MULTIPLY = 0x2005,
|
|
||||||
VG_BLEND_SCREEN = 0x2006,
|
|
||||||
VG_BLEND_DARKEN = 0x2007,
|
|
||||||
VG_BLEND_LIGHTEN = 0x2008,
|
|
||||||
VG_BLEND_ADDITIVE = 0x2009,
|
|
||||||
|
|
||||||
VG_BLEND_MODE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGBlendMode;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_FONT_NUM_GLYPHS = 0x2F00,
|
|
||||||
|
|
||||||
VG_FONT_PARAM_TYPE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGFontParamType;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_IMAGE_FORMAT_QUERY = 0x2100,
|
|
||||||
VG_PATH_DATATYPE_QUERY = 0x2101,
|
|
||||||
|
|
||||||
VG_HARDWARE_QUERY_TYPE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGHardwareQueryType;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_HARDWARE_ACCELERATED = 0x2200,
|
|
||||||
VG_HARDWARE_UNACCELERATED = 0x2201,
|
|
||||||
|
|
||||||
VG_HARDWARE_QUERY_RESULT_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGHardwareQueryResult;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_VENDOR = 0x2300,
|
|
||||||
VG_RENDERER = 0x2301,
|
|
||||||
VG_VERSION = 0x2302,
|
|
||||||
VG_EXTENSIONS = 0x2303,
|
|
||||||
|
|
||||||
VG_STRING_ID_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGStringID;
|
|
||||||
|
|
||||||
/* Function Prototypes */
|
|
||||||
|
|
||||||
#ifndef VG_API_CALL
|
|
||||||
# error VG_API_CALL must be defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VG_API_ENTRY
|
|
||||||
# error VG_API_ENTRY must be defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VG_API_EXIT
|
|
||||||
# error VG_API_EXIT must be defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VG_API_CALL VGErrorCode VG_API_ENTRY vgGetError(void) VG_API_EXIT;
|
|
||||||
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgFlush(void) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgFinish(void) VG_API_EXIT;
|
|
||||||
|
|
||||||
/* Getters and Setters */
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSetf (VGParamType type, VGfloat value) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSeti (VGParamType type, VGint value) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSetfv(VGParamType type, VGint count,
|
|
||||||
const VGfloat * values) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSetiv(VGParamType type, VGint count,
|
|
||||||
const VGint * values) VG_API_EXIT;
|
|
||||||
|
|
||||||
VG_API_CALL VGfloat VG_API_ENTRY vgGetf(VGParamType type) VG_API_EXIT;
|
|
||||||
VG_API_CALL VGint VG_API_ENTRY vgGeti(VGParamType type) VG_API_EXIT;
|
|
||||||
VG_API_CALL VGint VG_API_ENTRY vgGetVectorSize(VGParamType type) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgGetfv(VGParamType type, VGint count, VGfloat * values) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgGetiv(VGParamType type, VGint count, VGint * values) VG_API_EXIT;
|
|
||||||
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSetParameterf(VGHandle object,
|
|
||||||
VGint paramType,
|
|
||||||
VGfloat value) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSetParameteri(VGHandle object,
|
|
||||||
VGint paramType,
|
|
||||||
VGint value) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSetParameterfv(VGHandle object,
|
|
||||||
VGint paramType,
|
|
||||||
VGint count, const VGfloat * values) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSetParameteriv(VGHandle object,
|
|
||||||
VGint paramType,
|
|
||||||
VGint count, const VGint * values) VG_API_EXIT;
|
|
||||||
|
|
||||||
VG_API_CALL VGfloat VG_API_ENTRY vgGetParameterf(VGHandle object,
|
|
||||||
VGint paramType) VG_API_EXIT;
|
|
||||||
VG_API_CALL VGint VG_API_ENTRY vgGetParameteri(VGHandle object,
|
|
||||||
VGint paramType);
|
|
||||||
VG_API_CALL VGint VG_API_ENTRY vgGetParameterVectorSize(VGHandle object,
|
|
||||||
VGint paramType) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgGetParameterfv(VGHandle object,
|
|
||||||
VGint paramType,
|
|
||||||
VGint count, VGfloat * values) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgGetParameteriv(VGHandle object,
|
|
||||||
VGint paramType,
|
|
||||||
VGint count, VGint * values) VG_API_EXIT;
|
|
||||||
|
|
||||||
/* Matrix Manipulation */
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgLoadIdentity(void) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgLoadMatrix(const VGfloat * m) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgGetMatrix(VGfloat * m) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgMultMatrix(const VGfloat * m) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgTranslate(VGfloat tx, VGfloat ty) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgScale(VGfloat sx, VGfloat sy) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgShear(VGfloat shx, VGfloat shy) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgRotate(VGfloat angle) VG_API_EXIT;
|
|
||||||
|
|
||||||
/* Masking and Clearing */
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgMask(VGHandle mask, VGMaskOperation operation,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgRenderToMask(VGPath path,
|
|
||||||
VGbitfield paintModes,
|
|
||||||
VGMaskOperation operation) VG_API_EXIT;
|
|
||||||
VG_API_CALL VGMaskLayer VG_API_ENTRY vgCreateMaskLayer(VGint width, VGint height) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgDestroyMaskLayer(VGMaskLayer maskLayer) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgFillMaskLayer(VGMaskLayer maskLayer,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height,
|
|
||||||
VGfloat value) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgCopyMask(VGMaskLayer maskLayer,
|
|
||||||
VGint dx, VGint dy,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgClear(VGint x, VGint y, VGint width, VGint height) VG_API_EXIT;
|
|
||||||
|
|
||||||
/* Paths */
|
|
||||||
VG_API_CALL VGPath VG_API_ENTRY vgCreatePath(VGint pathFormat,
|
|
||||||
VGPathDatatype datatype,
|
|
||||||
VGfloat scale, VGfloat bias,
|
|
||||||
VGint segmentCapacityHint,
|
|
||||||
VGint coordCapacityHint,
|
|
||||||
VGbitfield capabilities) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgClearPath(VGPath path, VGbitfield capabilities) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgDestroyPath(VGPath path) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgRemovePathCapabilities(VGPath path,
|
|
||||||
VGbitfield capabilities) VG_API_EXIT;
|
|
||||||
VG_API_CALL VGbitfield VG_API_ENTRY vgGetPathCapabilities(VGPath path) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgAppendPath(VGPath dstPath, VGPath srcPath) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgAppendPathData(VGPath dstPath,
|
|
||||||
VGint numSegments,
|
|
||||||
const VGubyte * pathSegments,
|
|
||||||
const void * pathData) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgModifyPathCoords(VGPath dstPath, VGint startIndex,
|
|
||||||
VGint numSegments,
|
|
||||||
const void * pathData) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgTransformPath(VGPath dstPath, VGPath srcPath) VG_API_EXIT;
|
|
||||||
VG_API_CALL VGboolean VG_API_ENTRY vgInterpolatePath(VGPath dstPath,
|
|
||||||
VGPath startPath,
|
|
||||||
VGPath endPath,
|
|
||||||
VGfloat amount) VG_API_EXIT;
|
|
||||||
VG_API_CALL VGfloat VG_API_ENTRY vgPathLength(VGPath path,
|
|
||||||
VGint startSegment, VGint numSegments) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgPointAlongPath(VGPath path,
|
|
||||||
VGint startSegment, VGint numSegments,
|
|
||||||
VGfloat distance,
|
|
||||||
VGfloat * x, VGfloat * y,
|
|
||||||
VGfloat * tangentX, VGfloat * tangentY) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgPathBounds(VGPath path,
|
|
||||||
VGfloat * minX, VGfloat * minY,
|
|
||||||
VGfloat * width, VGfloat * height) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgPathTransformedBounds(VGPath path,
|
|
||||||
VGfloat * minX, VGfloat * minY,
|
|
||||||
VGfloat * width, VGfloat * height) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgDrawPath(VGPath path, VGbitfield paintModes) VG_API_EXIT;
|
|
||||||
|
|
||||||
/* Paint */
|
|
||||||
VG_API_CALL VGPaint VG_API_ENTRY vgCreatePaint(void) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgDestroyPaint(VGPaint paint) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSetPaint(VGPaint paint, VGbitfield paintModes) VG_API_EXIT;
|
|
||||||
VG_API_CALL VGPaint VG_API_ENTRY vgGetPaint(VGPaintMode paintMode) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSetColor(VGPaint paint, VGuint rgba) VG_API_EXIT;
|
|
||||||
VG_API_CALL VGuint VG_API_ENTRY vgGetColor(VGPaint paint) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgPaintPattern(VGPaint paint, VGImage pattern) VG_API_EXIT;
|
|
||||||
|
|
||||||
/* Images */
|
|
||||||
VG_API_CALL VGImage VG_API_ENTRY vgCreateImage(VGImageFormat format,
|
|
||||||
VGint width, VGint height,
|
|
||||||
VGbitfield allowedQuality) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgDestroyImage(VGImage image) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgClearImage(VGImage image,
|
|
||||||
VGint x, VGint y, VGint width, VGint height) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgImageSubData(VGImage image,
|
|
||||||
const void * data, VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint x, VGint y, VGint width, VGint height) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgGetImageSubData(VGImage image,
|
|
||||||
void * data, VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height) VG_API_EXIT;
|
|
||||||
VG_API_CALL VGImage VG_API_ENTRY vgChildImage(VGImage parent,
|
|
||||||
VGint x, VGint y, VGint width, VGint height) VG_API_EXIT;
|
|
||||||
VG_API_CALL VGImage VG_API_ENTRY vgGetParent(VGImage image) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgCopyImage(VGImage dst, VGint dx, VGint dy,
|
|
||||||
VGImage src, VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height,
|
|
||||||
VGboolean dither) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgDrawImage(VGImage image) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSetPixels(VGint dx, VGint dy,
|
|
||||||
VGImage src, VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgWritePixels(const void * data, VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint dx, VGint dy,
|
|
||||||
VGint width, VGint height) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgGetPixels(VGImage dst, VGint dx, VGint dy,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgReadPixels(void * data, VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgCopyPixels(VGint dx, VGint dy,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height) VG_API_EXIT;
|
|
||||||
|
|
||||||
/* Text */
|
|
||||||
VG_API_CALL VGFont VG_API_ENTRY vgCreateFont(VGint glyphCapacityHint) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgDestroyFont(VGFont font) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSetGlyphToPath(VGFont font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
VGPath path,
|
|
||||||
VGboolean isHinted,
|
|
||||||
const VGfloat glyphOrigin [2],
|
|
||||||
const VGfloat escapement[2]) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSetGlyphToImage(VGFont font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
VGImage image,
|
|
||||||
const VGfloat glyphOrigin [2],
|
|
||||||
const VGfloat escapement[2]) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgClearGlyph(VGFont font,VGuint glyphIndex) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgDrawGlyph(VGFont font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
VGbitfield paintModes,
|
|
||||||
VGboolean allowAutoHinting) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgDrawGlyphs(VGFont font,
|
|
||||||
VGint glyphCount,
|
|
||||||
const VGuint *glyphIndices,
|
|
||||||
const VGfloat *adjustments_x,
|
|
||||||
const VGfloat *adjustments_y,
|
|
||||||
VGbitfield paintModes,
|
|
||||||
VGboolean allowAutoHinting) VG_API_EXIT;
|
|
||||||
|
|
||||||
/* Image Filters */
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgColorMatrix(VGImage dst, VGImage src,
|
|
||||||
const VGfloat * matrix) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgConvolve(VGImage dst, VGImage src,
|
|
||||||
VGint kernelWidth, VGint kernelHeight,
|
|
||||||
VGint shiftX, VGint shiftY,
|
|
||||||
const VGshort * kernel,
|
|
||||||
VGfloat scale,
|
|
||||||
VGfloat bias,
|
|
||||||
VGTilingMode tilingMode) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgSeparableConvolve(VGImage dst, VGImage src,
|
|
||||||
VGint kernelWidth,
|
|
||||||
VGint kernelHeight,
|
|
||||||
VGint shiftX, VGint shiftY,
|
|
||||||
const VGshort * kernelX,
|
|
||||||
const VGshort * kernelY,
|
|
||||||
VGfloat scale,
|
|
||||||
VGfloat bias,
|
|
||||||
VGTilingMode tilingMode) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgGaussianBlur(VGImage dst, VGImage src,
|
|
||||||
VGfloat stdDeviationX,
|
|
||||||
VGfloat stdDeviationY,
|
|
||||||
VGTilingMode tilingMode) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgLookup(VGImage dst, VGImage src,
|
|
||||||
const VGubyte * redLUT,
|
|
||||||
const VGubyte * greenLUT,
|
|
||||||
const VGubyte * blueLUT,
|
|
||||||
const VGubyte * alphaLUT,
|
|
||||||
VGboolean outputLinear,
|
|
||||||
VGboolean outputPremultiplied) VG_API_EXIT;
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgLookupSingle(VGImage dst, VGImage src,
|
|
||||||
const VGuint * lookupTable,
|
|
||||||
VGImageChannel sourceChannel,
|
|
||||||
VGboolean outputLinear,
|
|
||||||
VGboolean outputPremultiplied) VG_API_EXIT;
|
|
||||||
|
|
||||||
/* Hardware Queries */
|
|
||||||
VG_API_CALL VGHardwareQueryResult VG_API_ENTRY vgHardwareQuery(VGHardwareQueryType key,
|
|
||||||
VGint setting) VG_API_EXIT;
|
|
||||||
|
|
||||||
/* Renderer and Extension Information */
|
|
||||||
VG_API_CALL const VGubyte * VG_API_ENTRY vgGetString(VGStringID name) VG_API_EXIT;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _OPENVG_H */
|
|
||||||
|
|
@ -1,233 +0,0 @@
|
||||||
/* $Revision: 6810 $ on $Date:: 2008-10-29 07:31:37 -0700 #$ */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* VG extensions Reference Implementation
|
|
||||||
* -------------------------------------
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008 The Khronos Group Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and /or associated documentation files
|
|
||||||
* (the "Materials "), to deal in the Materials without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Materials,
|
|
||||||
* and to permit persons to whom the Materials are furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Materials.
|
|
||||||
*
|
|
||||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
|
|
||||||
* THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
*
|
|
||||||
*//**
|
|
||||||
* \file
|
|
||||||
* \brief VG extensions
|
|
||||||
*//*-------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _VGEXT_H
|
|
||||||
#define _VGEXT_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <VG/openvg.h>
|
|
||||||
#include <VG/vgu.h>
|
|
||||||
|
|
||||||
#ifndef VG_API_ENTRYP
|
|
||||||
# define VG_API_ENTRYP VG_API_ENTRY*
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VGU_API_ENTRYP
|
|
||||||
# define VGU_API_ENTRYP VGU_API_ENTRY*
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------
|
|
||||||
* KHR extensions
|
|
||||||
*------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
|
|
||||||
#ifndef VG_KHR_iterative_average_blur
|
|
||||||
VG_MAX_AVERAGE_BLUR_DIMENSION_KHR = 0x116B,
|
|
||||||
VG_AVERAGE_BLUR_DIMENSION_RESOLUTION_KHR = 0x116C,
|
|
||||||
VG_MAX_AVERAGE_BLUR_ITERATIONS_KHR = 0x116D,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VG_PARAM_TYPE_KHR_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGParamTypeKHR;
|
|
||||||
|
|
||||||
#ifndef VG_KHR_EGL_image
|
|
||||||
#define VG_KHR_EGL_image 1
|
|
||||||
/* VGEGLImageKHR is an opaque handle to an EGLImage */
|
|
||||||
typedef void* VGeglImageKHR;
|
|
||||||
|
|
||||||
#ifdef VG_VGEXT_PROTOTYPES
|
|
||||||
VG_API_CALL VGImage VG_API_ENTRY vgCreateEGLImageTargetKHR(VGeglImageKHR image);
|
|
||||||
#endif
|
|
||||||
typedef VGImage (VG_API_ENTRYP PFNVGCREATEEGLIMAGETARGETKHRPROC) (VGeglImageKHR image);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef VG_KHR_iterative_average_blur
|
|
||||||
#define VG_KHR_iterative_average_blur 1
|
|
||||||
|
|
||||||
#ifdef VG_VGEXT_PROTOTYPES
|
|
||||||
VG_API_CALL void vgIterativeAverageBlurKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGTilingMode tilingMode);
|
|
||||||
#endif
|
|
||||||
typedef void (VG_API_ENTRYP PFNVGITERATIVEAVERAGEBLURKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGTilingMode tilingMode);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef VG_KHR_advanced_blending
|
|
||||||
#define VG_KHR_advanced_blending 1
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_BLEND_OVERLAY_KHR = 0x2010,
|
|
||||||
VG_BLEND_HARDLIGHT_KHR = 0x2011,
|
|
||||||
VG_BLEND_SOFTLIGHT_SVG_KHR = 0x2012,
|
|
||||||
VG_BLEND_SOFTLIGHT_KHR = 0x2013,
|
|
||||||
VG_BLEND_COLORDODGE_KHR = 0x2014,
|
|
||||||
VG_BLEND_COLORBURN_KHR = 0x2015,
|
|
||||||
VG_BLEND_DIFFERENCE_KHR = 0x2016,
|
|
||||||
VG_BLEND_SUBTRACT_KHR = 0x2017,
|
|
||||||
VG_BLEND_INVERT_KHR = 0x2018,
|
|
||||||
VG_BLEND_EXCLUSION_KHR = 0x2019,
|
|
||||||
VG_BLEND_LINEARDODGE_KHR = 0x201a,
|
|
||||||
VG_BLEND_LINEARBURN_KHR = 0x201b,
|
|
||||||
VG_BLEND_VIVIDLIGHT_KHR = 0x201c,
|
|
||||||
VG_BLEND_LINEARLIGHT_KHR = 0x201d,
|
|
||||||
VG_BLEND_PINLIGHT_KHR = 0x201e,
|
|
||||||
VG_BLEND_HARDMIX_KHR = 0x201f,
|
|
||||||
VG_BLEND_CLEAR_KHR = 0x2020,
|
|
||||||
VG_BLEND_DST_KHR = 0x2021,
|
|
||||||
VG_BLEND_SRC_OUT_KHR = 0x2022,
|
|
||||||
VG_BLEND_DST_OUT_KHR = 0x2023,
|
|
||||||
VG_BLEND_SRC_ATOP_KHR = 0x2024,
|
|
||||||
VG_BLEND_DST_ATOP_KHR = 0x2025,
|
|
||||||
VG_BLEND_XOR_KHR = 0x2026,
|
|
||||||
|
|
||||||
VG_BLEND_MODE_KHR_FORCE_SIZE= VG_MAX_ENUM
|
|
||||||
} VGBlendModeKHR;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VG_KHR_parametric_filter
|
|
||||||
#define VG_KHR_parametric_filter 1
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_PF_OBJECT_VISIBLE_FLAG_KHR = (1 << 0),
|
|
||||||
VG_PF_KNOCKOUT_FLAG_KHR = (1 << 1),
|
|
||||||
VG_PF_OUTER_FLAG_KHR = (1 << 2),
|
|
||||||
VG_PF_INNER_FLAG_KHR = (1 << 3),
|
|
||||||
|
|
||||||
VG_PF_TYPE_KHR_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPfTypeKHR;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VGU_IMAGE_IN_USE_ERROR = 0xF010,
|
|
||||||
|
|
||||||
VGU_ERROR_CODE_KHR_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGUErrorCodeKHR;
|
|
||||||
|
|
||||||
#ifdef VG_VGEXT_PROTOTYPES
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgParametricFilterKHR(VGImage dst,VGImage src,VGImage blur,VGfloat strength,VGfloat offsetX,VGfloat offsetY,VGbitfield filterFlags,VGPaint highlightPaint,VGPaint shadowPaint);
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguDropShadowKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint shadowColorRGBA);
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguGlowKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint glowColorRGBA) ;
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguBevelKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint highlightColorRGBA,VGuint shadowColorRGBA);
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguGradientGlowKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint stopsCount,const VGfloat* glowColorRampStops);
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguGradientBevelKHR(VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint stopsCount,const VGfloat* bevelColorRampStops);
|
|
||||||
#endif
|
|
||||||
typedef void (VG_API_ENTRYP PFNVGPARAMETRICFILTERKHRPROC) (VGImage dst,VGImage src,VGImage blur,VGfloat strength,VGfloat offsetX,VGfloat offsetY,VGbitfield filterFlags,VGPaint highlightPaint,VGPaint shadowPaint);
|
|
||||||
typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUDROPSHADOWKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint shadowColorRGBA);
|
|
||||||
typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUGLOWKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint glowColorRGBA);
|
|
||||||
typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUBEVELKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint highlightColorRGBA,VGuint shadowColorRGBA);
|
|
||||||
typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUGRADIENTGLOWKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint stopsCount,const VGfloat* glowColorRampStops);
|
|
||||||
typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUGRADIENTBEVELKHRPROC) (VGImage dst,VGImage src,VGfloat dimX,VGfloat dimY,VGuint iterative,VGfloat strength,VGfloat distance,VGfloat angle,VGbitfield filterFlags,VGbitfield allowedQuality,VGuint stopsCount,const VGfloat* bevelColorRampStops);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------
|
|
||||||
* NDS extensions
|
|
||||||
*------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef VG_NDS_paint_generation
|
|
||||||
#define VG_NDS_paint_generation 1
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_PAINT_COLOR_RAMP_LINEAR_NDS = 0x1A10,
|
|
||||||
VG_COLOR_MATRIX_NDS = 0x1A11,
|
|
||||||
VG_PAINT_COLOR_TRANSFORM_LINEAR_NDS = 0x1A12,
|
|
||||||
|
|
||||||
VG_PAINT_PARAM_TYPE_NDS_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPaintParamTypeNds;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_DRAW_IMAGE_COLOR_MATRIX_NDS = 0x1F10,
|
|
||||||
|
|
||||||
VG_IMAGE_MODE_NDS_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGImageModeNds;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef VG_NDS_projective_geometry
|
|
||||||
#define VG_NDS_projective_geometry 1
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_CLIP_MODE_NDS = 0x1180,
|
|
||||||
VG_CLIP_LINES_NDS = 0x1181,
|
|
||||||
VG_MAX_CLIP_LINES_NDS = 0x1182,
|
|
||||||
|
|
||||||
VG_PARAM_TYPE_NDS_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGParamTypeNds;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_CLIPMODE_NONE_NDS = 0x3000,
|
|
||||||
VG_CLIPMODE_CLIP_CLOSED_NDS = 0x3001,
|
|
||||||
VG_CLIPMODE_CLIP_OPEN_NDS = 0x3002,
|
|
||||||
VG_CLIPMODE_CULL_NDS = 0x3003,
|
|
||||||
|
|
||||||
VG_CLIPMODE_NDS_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGClipModeNds;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_RQUAD_TO_NDS = ( 13 << 1 ),
|
|
||||||
VG_RCUBIC_TO_NDS = ( 14 << 1 ),
|
|
||||||
|
|
||||||
VG_PATH_SEGMENT_NDS_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPathSegmentNds;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VG_RQUAD_TO_ABS_NDS = (VG_RQUAD_TO_NDS | VG_ABSOLUTE),
|
|
||||||
VG_RQUAD_TO_REL_NDS = (VG_RQUAD_TO_NDS | VG_RELATIVE),
|
|
||||||
VG_RCUBIC_TO_ABS_NDS = (VG_RCUBIC_TO_NDS | VG_ABSOLUTE),
|
|
||||||
VG_RCUBIC_TO_REL_NDS = (VG_RCUBIC_TO_NDS | VG_RELATIVE),
|
|
||||||
|
|
||||||
VG_PATH_COMMAND_NDS_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGPathCommandNds;
|
|
||||||
|
|
||||||
#ifdef VG_VGEXT_PROTOTYPES
|
|
||||||
VG_API_CALL void VG_API_ENTRY vgProjectiveMatrixNDS(VGboolean enable) ;
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguTransformClipLineNDS(const VGfloat Ain,const VGfloat Bin,const VGfloat Cin,const VGfloat* matrix,const VGboolean inverse,VGfloat* Aout,VGfloat* Bout,VGfloat* Cout);
|
|
||||||
#endif
|
|
||||||
typedef void (VG_API_ENTRYP PFNVGPROJECTIVEMATRIXNDSPROC) (VGboolean enable) ;
|
|
||||||
typedef VGUErrorCode (VGU_API_ENTRYP PFNVGUTRANSFORMCLIPLINENDSPROC) (const VGfloat Ain,const VGfloat Bin,const VGfloat Cin,const VGfloat* matrix,const VGboolean inverse,VGfloat* Aout,VGfloat* Bout,VGfloat* Cout);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _VGEXT_H */
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
/* $Revision: 6810 $ on $Date:: 2008-10-29 07:31:37 -0700 #$ */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* VG platform specific header Reference Implementation
|
|
||||||
* ----------------------------------------------------
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008 The Khronos Group Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and /or associated documentation files
|
|
||||||
* (the "Materials "), to deal in the Materials without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Materials,
|
|
||||||
* and to permit persons to whom the Materials are furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Materials.
|
|
||||||
*
|
|
||||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
|
|
||||||
* THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
*
|
|
||||||
*//**
|
|
||||||
* \file
|
|
||||||
* \brief VG platform specific header
|
|
||||||
*//*-------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef _VGPLATFORM_H
|
|
||||||
#define _VGPLATFORM_H
|
|
||||||
|
|
||||||
#include <KHR/khrplatform.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VG_API_CALL
|
|
||||||
#if defined(OPENVG_STATIC_LIBRARY)
|
|
||||||
# define VG_API_CALL
|
|
||||||
#else
|
|
||||||
# define VG_API_CALL KHRONOS_APICALL
|
|
||||||
#endif /* defined OPENVG_STATIC_LIBRARY */
|
|
||||||
#endif /* ifndef VG_API_CALL */
|
|
||||||
|
|
||||||
#ifndef VGU_API_CALL
|
|
||||||
#if defined(OPENVG_STATIC_LIBRARY)
|
|
||||||
# define VGU_API_CALL
|
|
||||||
#else
|
|
||||||
# define VGU_API_CALL KHRONOS_APICALL
|
|
||||||
#endif /* defined OPENVG_STATIC_LIBRARY */
|
|
||||||
#endif /* ifndef VGU_API_CALL */
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef VG_API_ENTRY
|
|
||||||
#define VG_API_ENTRY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VG_API_EXIT
|
|
||||||
#define VG_API_EXIT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VGU_API_ENTRY
|
|
||||||
#define VGU_API_ENTRY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VGU_API_EXIT
|
|
||||||
#define VGU_API_EXIT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef float VGfloat;
|
|
||||||
typedef signed char VGbyte;
|
|
||||||
typedef unsigned char VGubyte;
|
|
||||||
typedef signed short VGshort;
|
|
||||||
typedef signed int VGint;
|
|
||||||
typedef unsigned int VGuint;
|
|
||||||
typedef unsigned int VGbitfield;
|
|
||||||
|
|
||||||
#ifndef VG_VGEXT_PROTOTYPES
|
|
||||||
#define VG_VGEXT_PROTOTYPES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _VGPLATFORM_H */
|
|
||||||
131
include/VG/vgu.h
131
include/VG/vgu.h
|
|
@ -1,131 +0,0 @@
|
||||||
/* $Revision: 6810 $ on $Date:: 2008-10-29 07:31:37 -0700 #$ */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* VGU 1.1 Reference Implementation
|
|
||||||
* -------------------------------------
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008 The Khronos Group Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and /or associated documentation files
|
|
||||||
* (the "Materials "), to deal in the Materials without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Materials,
|
|
||||||
* and to permit persons to whom the Materials are furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Materials.
|
|
||||||
*
|
|
||||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
|
|
||||||
* THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
*
|
|
||||||
*//**
|
|
||||||
* \file
|
|
||||||
* \brief VGU 1.1 API.
|
|
||||||
*//*-------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef _VGU_H
|
|
||||||
#define _VGU_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <VG/openvg.h>
|
|
||||||
|
|
||||||
#define VGU_VERSION_1_0 1
|
|
||||||
#define VGU_VERSION_1_1 2
|
|
||||||
|
|
||||||
#ifndef VGU_API_CALL
|
|
||||||
# error VGU_API_CALL must be defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VGU_API_ENTRY
|
|
||||||
# error VGU_API_ENTRY must be defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VGU_API_EXIT
|
|
||||||
# error VGU_API_EXIT must be defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VGU_NO_ERROR = 0,
|
|
||||||
VGU_BAD_HANDLE_ERROR = 0xF000,
|
|
||||||
VGU_ILLEGAL_ARGUMENT_ERROR = 0xF001,
|
|
||||||
VGU_OUT_OF_MEMORY_ERROR = 0xF002,
|
|
||||||
VGU_PATH_CAPABILITY_ERROR = 0xF003,
|
|
||||||
VGU_BAD_WARP_ERROR = 0xF004,
|
|
||||||
|
|
||||||
VGU_ERROR_CODE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGUErrorCode;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
VGU_ARC_OPEN = 0xF100,
|
|
||||||
VGU_ARC_CHORD = 0xF101,
|
|
||||||
VGU_ARC_PIE = 0xF102,
|
|
||||||
|
|
||||||
VGU_ARC_TYPE_FORCE_SIZE = VG_MAX_ENUM
|
|
||||||
} VGUArcType;
|
|
||||||
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguLine(VGPath path,
|
|
||||||
VGfloat x0, VGfloat y0,
|
|
||||||
VGfloat x1, VGfloat y1) VGU_API_EXIT;
|
|
||||||
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguPolygon(VGPath path,
|
|
||||||
const VGfloat * points, VGint count,
|
|
||||||
VGboolean closed) VGU_API_EXIT;
|
|
||||||
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguRect(VGPath path,
|
|
||||||
VGfloat x, VGfloat y,
|
|
||||||
VGfloat width, VGfloat height) VGU_API_EXIT;
|
|
||||||
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguRoundRect(VGPath path,
|
|
||||||
VGfloat x, VGfloat y,
|
|
||||||
VGfloat width, VGfloat height,
|
|
||||||
VGfloat arcWidth, VGfloat arcHeight) VGU_API_EXIT;
|
|
||||||
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguEllipse(VGPath path,
|
|
||||||
VGfloat cx, VGfloat cy,
|
|
||||||
VGfloat width, VGfloat height) VGU_API_EXIT;
|
|
||||||
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguArc(VGPath path,
|
|
||||||
VGfloat x, VGfloat y,
|
|
||||||
VGfloat width, VGfloat height,
|
|
||||||
VGfloat startAngle, VGfloat angleExtent,
|
|
||||||
VGUArcType arcType) VGU_API_EXIT;
|
|
||||||
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguComputeWarpQuadToSquare(VGfloat sx0, VGfloat sy0,
|
|
||||||
VGfloat sx1, VGfloat sy1,
|
|
||||||
VGfloat sx2, VGfloat sy2,
|
|
||||||
VGfloat sx3, VGfloat sy3,
|
|
||||||
VGfloat * matrix) VGU_API_EXIT;
|
|
||||||
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguComputeWarpSquareToQuad(VGfloat dx0, VGfloat dy0,
|
|
||||||
VGfloat dx1, VGfloat dy1,
|
|
||||||
VGfloat dx2, VGfloat dy2,
|
|
||||||
VGfloat dx3, VGfloat dy3,
|
|
||||||
VGfloat * matrix) VGU_API_EXIT;
|
|
||||||
|
|
||||||
VGU_API_CALL VGUErrorCode VGU_API_ENTRY vguComputeWarpQuadToQuad(VGfloat dx0, VGfloat dy0,
|
|
||||||
VGfloat dx1, VGfloat dy1,
|
|
||||||
VGfloat dx2, VGfloat dy2,
|
|
||||||
VGfloat dx3, VGfloat dy3,
|
|
||||||
VGfloat sx0, VGfloat sy0,
|
|
||||||
VGfloat sx1, VGfloat sy1,
|
|
||||||
VGfloat sx2, VGfloat sy2,
|
|
||||||
VGfloat sx3, VGfloat sy3,
|
|
||||||
VGfloat * matrix) VGU_API_EXIT;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* #ifndef _VGU_H */
|
|
||||||
|
|
@ -27,8 +27,6 @@ if env['platform'] in ['haiku']:
|
||||||
|
|
||||||
SConscript('mesa/SConscript')
|
SConscript('mesa/SConscript')
|
||||||
|
|
||||||
SConscript('mapi/vgapi/SConscript')
|
|
||||||
|
|
||||||
if not env['embedded']:
|
if not env['embedded']:
|
||||||
if env['platform'] not in ('cygwin', 'darwin', 'freebsd', 'haiku', 'windows'):
|
if env['platform'] not in ('cygwin', 'darwin', 'freebsd', 'haiku', 'windows'):
|
||||||
SConscript('glx/SConscript')
|
SConscript('glx/SConscript')
|
||||||
|
|
|
||||||
|
|
@ -136,11 +136,6 @@ if HAVE_DRICOMMON
|
||||||
SUBDIRS += state_trackers/dri targets/dri
|
SUBDIRS += state_trackers/dri targets/dri
|
||||||
endif
|
endif
|
||||||
|
|
||||||
## the egl target depends on vega
|
|
||||||
if HAVE_OPENVG
|
|
||||||
SUBDIRS += state_trackers/vega
|
|
||||||
endif
|
|
||||||
|
|
||||||
if HAVE_X11_DRIVER
|
if HAVE_X11_DRIVER
|
||||||
SUBDIRS += state_trackers/glx/xlib targets/libgl-xlib
|
SUBDIRS += state_trackers/glx/xlib targets/libgl-xlib
|
||||||
endif
|
endif
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,6 @@ SConscript([
|
||||||
])
|
])
|
||||||
|
|
||||||
if not env['embedded']:
|
if not env['embedded']:
|
||||||
SConscript('state_trackers/vega/SConscript')
|
|
||||||
|
|
||||||
if env['x11']:
|
if env['x11']:
|
||||||
SConscript([
|
SConscript([
|
||||||
'state_trackers/glx/xlib/SConscript',
|
'state_trackers/glx/xlib/SConscript',
|
||||||
|
|
|
||||||
|
|
@ -106,14 +106,6 @@ Tracker that implements the client-side DRI protocol, for providing direct
|
||||||
acceleration services to X11 servers with the DRI extension. Supports DRI1
|
acceleration services to X11 servers with the DRI extension. Supports DRI1
|
||||||
and DRI2. Only GL is supported.
|
and DRI2. Only GL is supported.
|
||||||
|
|
||||||
.. _egl:
|
|
||||||
|
|
||||||
EGL
|
|
||||||
^^^
|
|
||||||
|
|
||||||
Tracker for the Khronos EGL standard, used to set up GL and GLES contexts
|
|
||||||
without extra knowledge of the underlying windowing system.
|
|
||||||
|
|
||||||
GLX
|
GLX
|
||||||
^^^
|
^^^
|
||||||
|
|
||||||
|
|
@ -124,11 +116,6 @@ Tracker implementing a GL state machine. Not usable as a standalone tracker;
|
||||||
Mesa should be built with another state tracker, such as :ref:`DRI` or
|
Mesa should be built with another state tracker, such as :ref:`DRI` or
|
||||||
:ref:`EGL`.
|
:ref:`EGL`.
|
||||||
|
|
||||||
OpenVG
|
|
||||||
^^^^^^
|
|
||||||
|
|
||||||
Tracker that implements the Khronos OpenVG standard.
|
|
||||||
|
|
||||||
VDPAU
|
VDPAU
|
||||||
^^^^^
|
^^^^^
|
||||||
|
|
||||||
|
|
|
||||||
1
src/gallium/state_trackers/vega/.gitignore
vendored
1
src/gallium/state_trackers/vega/.gitignore
vendored
|
|
@ -1 +0,0 @@
|
||||||
api_tmp.h
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
# Copyright © 2012 Intel Corporation
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
# copy of this software and associated documentation files (the "Software"),
|
|
||||||
# to deal in the Software without restriction, including without limitation
|
|
||||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
# and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
# Software is furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice (including the next
|
|
||||||
# paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
# Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
# DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
include Makefile.sources
|
|
||||||
include $(top_srcdir)/src/gallium/Automake.inc
|
|
||||||
|
|
||||||
AM_CFLAGS = $(GALLIUM_CFLAGS)
|
|
||||||
AM_CPPFLAGS = \
|
|
||||||
-I$(top_srcdir)/include \
|
|
||||||
-I$(top_srcdir)/src/mapi
|
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libvega.la
|
|
||||||
|
|
||||||
libvega_la_SOURCES = $(C_SOURCES)
|
|
||||||
|
|
||||||
BUILT_SOURCES = api_tmp.h
|
|
||||||
CLEANFILES = api_tmp.h
|
|
||||||
|
|
||||||
api_tmp.h: $(top_srcdir)/src/mapi/vgapi/vgapi.csv $(top_srcdir)/src/mapi/mapi_abi.py
|
|
||||||
$(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(top_srcdir)/src/mapi/mapi_abi.py \
|
|
||||||
--printer vgapi --mode app $< > $@
|
|
||||||
|
|
||||||
EXTRA_DIST = SConscript
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
C_SOURCES := \
|
|
||||||
api.c \
|
|
||||||
api.h \
|
|
||||||
api_consts.h \
|
|
||||||
api_context.c \
|
|
||||||
api_filters.c \
|
|
||||||
api_images.c \
|
|
||||||
api_masks.c \
|
|
||||||
api_misc.c \
|
|
||||||
api_paint.c \
|
|
||||||
api_params.c \
|
|
||||||
api_path.c \
|
|
||||||
api_text.c \
|
|
||||||
api_transform.c \
|
|
||||||
arc.c \
|
|
||||||
arc.h \
|
|
||||||
asm_fill.h \
|
|
||||||
asm_filters.h \
|
|
||||||
asm_util.h \
|
|
||||||
bezier.c \
|
|
||||||
bezier.h \
|
|
||||||
handle.c \
|
|
||||||
handle.h \
|
|
||||||
image.c \
|
|
||||||
image.h \
|
|
||||||
mask.c \
|
|
||||||
mask.h \
|
|
||||||
matrix.h \
|
|
||||||
paint.c \
|
|
||||||
paint.h \
|
|
||||||
path.c \
|
|
||||||
path.h \
|
|
||||||
path_utils.h \
|
|
||||||
polygon.c \
|
|
||||||
polygon.h \
|
|
||||||
renderer.c \
|
|
||||||
renderer.h \
|
|
||||||
shader.c \
|
|
||||||
shader.h \
|
|
||||||
shaders_cache.c \
|
|
||||||
shaders_cache.h \
|
|
||||||
stroker.c \
|
|
||||||
stroker.h \
|
|
||||||
text.c \
|
|
||||||
text.h \
|
|
||||||
util_array.h \
|
|
||||||
vg_api.h \
|
|
||||||
vg_context.c \
|
|
||||||
vg_context.h \
|
|
||||||
vg_manager.c \
|
|
||||||
vg_manager.h \
|
|
||||||
vg_state.c \
|
|
||||||
vg_state.h \
|
|
||||||
vg_translate.c \
|
|
||||||
vg_translate.h \
|
|
||||||
vgu.c
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
#######################################################################
|
|
||||||
# SConscript for vega state_tracker
|
|
||||||
|
|
||||||
Import('*')
|
|
||||||
|
|
||||||
from sys import executable as python_cmd
|
|
||||||
|
|
||||||
env = env.Clone()
|
|
||||||
|
|
||||||
env.Append(CPPPATH = [
|
|
||||||
'#/src/mapi',
|
|
||||||
Dir('.'),
|
|
||||||
])
|
|
||||||
env.Append(CPPDEFINES = [
|
|
||||||
'KHRONOS_DLL_EXPORTS',
|
|
||||||
])
|
|
||||||
|
|
||||||
api_tmp, = env.CodeGenerate(
|
|
||||||
target = 'api_tmp.h',
|
|
||||||
script = '#src/mapi/mapi_abi.py',
|
|
||||||
source = '#src/mapi/vgapi/vgapi.csv',
|
|
||||||
command = python_cmd + ' $SCRIPT --printer vgapi --mode app $SOURCE > $TARGET'
|
|
||||||
)
|
|
||||||
|
|
||||||
st_vega = env.ConvenienceLibrary(
|
|
||||||
target = 'st_vega',
|
|
||||||
source = env.ParseSourceList('Makefile.sources', 'C_SOURCES')
|
|
||||||
)
|
|
||||||
|
|
||||||
Export('st_vega')
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
/*
|
|
||||||
* Mesa 3-D graphics library
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 LunarG Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Chia-I Wu <olv@lunarg.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mapi.h"
|
|
||||||
|
|
||||||
/* define vega_spec and vega_procs for use with mapi */
|
|
||||||
#define API_TMP_DEFINE_SPEC
|
|
||||||
#include "api.h"
|
|
||||||
|
|
||||||
static void api_init(void)
|
|
||||||
{
|
|
||||||
static boolean initialized = FALSE;
|
|
||||||
if (!initialized) {
|
|
||||||
mapi_init(vega_spec);
|
|
||||||
initialized = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mapi_table *api_create_dispatch(void)
|
|
||||||
{
|
|
||||||
struct mapi_table *tbl;
|
|
||||||
|
|
||||||
api_init();
|
|
||||||
|
|
||||||
tbl = mapi_table_create();
|
|
||||||
if (tbl)
|
|
||||||
mapi_table_fill(tbl, vega_procs);
|
|
||||||
|
|
||||||
return tbl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void api_destroy_dispatch(struct mapi_table *tbl)
|
|
||||||
{
|
|
||||||
mapi_table_destroy(tbl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void api_make_dispatch_current(const struct mapi_table *tbl)
|
|
||||||
{
|
|
||||||
mapi_table_make_current(tbl);
|
|
||||||
}
|
|
||||||
|
|
||||||
mapi_proc api_get_proc_address(const char *proc_name)
|
|
||||||
{
|
|
||||||
if (!proc_name || proc_name[0] != 'v' || proc_name[1] != 'g')
|
|
||||||
return NULL;
|
|
||||||
proc_name += 2;
|
|
||||||
|
|
||||||
api_init();
|
|
||||||
return mapi_get_proc_address(proc_name);
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Mesa 3-D graphics library
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 LunarG Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Chia-I Wu <olv@lunarg.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef API_H
|
|
||||||
#define API_H
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
#include "VG/vgext.h"
|
|
||||||
#include "vg_manager.h"
|
|
||||||
|
|
||||||
#include "api_tmp.h"
|
|
||||||
|
|
||||||
struct mapi_table;
|
|
||||||
|
|
||||||
struct mapi_table *api_create_dispatch(void);
|
|
||||||
|
|
||||||
void api_destroy_dispatch(struct mapi_table *tbl);
|
|
||||||
|
|
||||||
void api_make_dispatch_current(const struct mapi_table *tbl);
|
|
||||||
|
|
||||||
st_proc_t api_get_proc_address(const char *proc_name);
|
|
||||||
|
|
||||||
#endif /* API_H */
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef API_CONSTS_H
|
|
||||||
#define API_CONSTS_H
|
|
||||||
|
|
||||||
/*must be at least 32*/
|
|
||||||
#define VEGA_MAX_SCISSOR_RECTS 32
|
|
||||||
|
|
||||||
/*must be at least 16*/
|
|
||||||
#define VEGA_MAX_DASH_COUNT 32
|
|
||||||
|
|
||||||
/*must be at least 7*/
|
|
||||||
#define VEGA_MAX_KERNEL_SIZE 7
|
|
||||||
|
|
||||||
/*must be at least 15*/
|
|
||||||
#define VEGA_MAX_SEPARABLE_KERNEL_SIZE 15
|
|
||||||
|
|
||||||
/*must be at least 32*/
|
|
||||||
#define VEGA_MAX_COLOR_RAMP_STOPS 256
|
|
||||||
|
|
||||||
#define VEGA_MAX_IMAGE_WIDTH 2048
|
|
||||||
|
|
||||||
#define VEGA_MAX_IMAGE_HEIGHT 2048
|
|
||||||
|
|
||||||
#define VEGA_MAX_IMAGE_PIXELS (2048*2048)
|
|
||||||
|
|
||||||
#define VEGA_MAX_IMAGE_BYTES (2048*2048 * 4)
|
|
||||||
|
|
||||||
/*must be at least 128*/
|
|
||||||
#define VEGA_MAX_GAUSSIAN_STD_DEVIATION 128
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "vg_manager.h"
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "api.h"
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_screen.h"
|
|
||||||
|
|
||||||
VGErrorCode vegaGetError(void)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
VGErrorCode error = VG_NO_CONTEXT_ERROR;
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
error = ctx->_error;
|
|
||||||
ctx->_error = VG_NO_ERROR;
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaFlush(void)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_context *pipe;
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pipe = ctx->pipe;
|
|
||||||
pipe->flush(pipe, NULL, 0);
|
|
||||||
|
|
||||||
vg_manager_flush_frontbuffer(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaFinish(void)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_fence_handle *fence = NULL;
|
|
||||||
struct pipe_context *pipe;
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pipe = ctx->pipe;
|
|
||||||
|
|
||||||
pipe->flush(pipe, &fence, 0);
|
|
||||||
if (fence) {
|
|
||||||
pipe->screen->fence_finish(pipe->screen, fence,
|
|
||||||
PIPE_TIMEOUT_INFINITE);
|
|
||||||
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,705 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "image.h"
|
|
||||||
#include "api.h"
|
|
||||||
#include "handle.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
#include "shaders_cache.h"
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "pipe/p_screen.h"
|
|
||||||
|
|
||||||
#include "util/u_format.h"
|
|
||||||
#include "util/u_sampler.h"
|
|
||||||
#include "util/u_string.h"
|
|
||||||
|
|
||||||
#include "asm_filters.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct filter_info {
|
|
||||||
struct vg_image *dst;
|
|
||||||
struct vg_image *src;
|
|
||||||
struct vg_shader * (*setup_shader)(struct vg_context *, void *);
|
|
||||||
void *user_data;
|
|
||||||
const void *const_buffer;
|
|
||||||
VGint const_buffer_len;
|
|
||||||
VGTilingMode tiling_mode;
|
|
||||||
struct pipe_sampler_view *extra_texture_view;
|
|
||||||
};
|
|
||||||
|
|
||||||
static INLINE struct pipe_resource *create_texture_1d(struct vg_context *ctx,
|
|
||||||
const VGuint *color_data,
|
|
||||||
const VGint color_data_len)
|
|
||||||
{
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct pipe_screen *screen = pipe->screen;
|
|
||||||
struct pipe_resource *tex = 0;
|
|
||||||
struct pipe_resource templ;
|
|
||||||
|
|
||||||
memset(&templ, 0, sizeof(templ));
|
|
||||||
templ.target = PIPE_TEXTURE_1D;
|
|
||||||
templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
templ.last_level = 0;
|
|
||||||
templ.width0 = color_data_len;
|
|
||||||
templ.height0 = 1;
|
|
||||||
templ.depth0 = 1;
|
|
||||||
templ.array_size = 1;
|
|
||||||
templ.bind = PIPE_BIND_SAMPLER_VIEW;
|
|
||||||
|
|
||||||
tex = screen->resource_create(screen, &templ);
|
|
||||||
|
|
||||||
{ /* upload color_data */
|
|
||||||
struct pipe_transfer *transfer;
|
|
||||||
void *map =
|
|
||||||
pipe_transfer_map(pipe, tex,
|
|
||||||
0, 0,
|
|
||||||
PIPE_TRANSFER_READ_WRITE ,
|
|
||||||
0, 0, tex->width0, tex->height0,
|
|
||||||
&transfer);
|
|
||||||
memcpy(map, color_data, sizeof(VGint)*color_data_len);
|
|
||||||
pipe->transfer_unmap(pipe, transfer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE struct pipe_sampler_view *create_texture_1d_view(struct vg_context *ctx,
|
|
||||||
const VGuint *color_data,
|
|
||||||
const VGint color_data_len)
|
|
||||||
{
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct pipe_resource *texture;
|
|
||||||
struct pipe_sampler_view view_templ;
|
|
||||||
struct pipe_sampler_view *view;
|
|
||||||
|
|
||||||
texture = create_texture_1d(ctx, color_data, color_data_len);
|
|
||||||
|
|
||||||
if (!texture)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
u_sampler_view_default_template(&view_templ, texture, texture->format);
|
|
||||||
view = pipe->create_sampler_view(pipe, texture, &view_templ);
|
|
||||||
/* want the texture to go away if the view is freed */
|
|
||||||
pipe_resource_reference(&texture, NULL);
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct vg_shader * setup_color_matrix(struct vg_context *ctx, void *user_data)
|
|
||||||
{
|
|
||||||
struct vg_shader *shader =
|
|
||||||
shader_create_from_text(ctx->pipe, color_matrix_asm, 200,
|
|
||||||
PIPE_SHADER_FRAGMENT);
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct vg_shader * setup_convolution(struct vg_context *ctx, void *user_data)
|
|
||||||
{
|
|
||||||
char buffer[1024];
|
|
||||||
VGint num_consts = (VGint)(long)(user_data);
|
|
||||||
struct vg_shader *shader;
|
|
||||||
|
|
||||||
util_snprintf(buffer, 1023, convolution_asm, num_consts, num_consts / 2 + 1);
|
|
||||||
|
|
||||||
shader = shader_create_from_text(ctx->pipe, buffer, 200,
|
|
||||||
PIPE_SHADER_FRAGMENT);
|
|
||||||
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct vg_shader * setup_lookup(struct vg_context *ctx, void *user_data)
|
|
||||||
{
|
|
||||||
struct vg_shader *shader =
|
|
||||||
shader_create_from_text(ctx->pipe, lookup_asm,
|
|
||||||
200, PIPE_SHADER_FRAGMENT);
|
|
||||||
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct vg_shader * setup_lookup_single(struct vg_context *ctx, void *user_data)
|
|
||||||
{
|
|
||||||
char buffer[1024];
|
|
||||||
VGImageChannel channel = (VGImageChannel)(user_data);
|
|
||||||
struct vg_shader *shader;
|
|
||||||
|
|
||||||
switch(channel) {
|
|
||||||
case VG_RED:
|
|
||||||
util_snprintf(buffer, 1023, lookup_single_asm, "xxxx");
|
|
||||||
break;
|
|
||||||
case VG_GREEN:
|
|
||||||
util_snprintf(buffer, 1023, lookup_single_asm, "yyyy");
|
|
||||||
break;
|
|
||||||
case VG_BLUE:
|
|
||||||
util_snprintf(buffer, 1023, lookup_single_asm, "zzzz");
|
|
||||||
break;
|
|
||||||
case VG_ALPHA:
|
|
||||||
util_snprintf(buffer, 1023, lookup_single_asm, "wwww");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
debug_assert(!"Unknown color channel");
|
|
||||||
}
|
|
||||||
|
|
||||||
shader = shader_create_from_text(ctx->pipe, buffer, 200,
|
|
||||||
PIPE_SHADER_FRAGMENT);
|
|
||||||
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void execute_filter(struct vg_context *ctx,
|
|
||||||
struct filter_info *info)
|
|
||||||
{
|
|
||||||
struct vg_shader *shader;
|
|
||||||
const struct pipe_sampler_state *samplers[2];
|
|
||||||
struct pipe_sampler_view *views[2];
|
|
||||||
struct pipe_sampler_state sampler;
|
|
||||||
uint tex_wrap;
|
|
||||||
|
|
||||||
memset(&sampler, 0, sizeof(sampler));
|
|
||||||
sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
|
|
||||||
sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
|
|
||||||
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
|
||||||
sampler.normalized_coords = 1;
|
|
||||||
|
|
||||||
switch (info->tiling_mode) {
|
|
||||||
case VG_TILE_FILL:
|
|
||||||
tex_wrap = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
|
|
||||||
/* copy border color */
|
|
||||||
memcpy(sampler.border_color.f, ctx->state.vg.tile_fill_color,
|
|
||||||
sizeof(sampler.border_color));
|
|
||||||
break;
|
|
||||||
case VG_TILE_PAD:
|
|
||||||
tex_wrap = PIPE_TEX_WRAP_CLAMP_TO_EDGE;;
|
|
||||||
break;
|
|
||||||
case VG_TILE_REPEAT:
|
|
||||||
tex_wrap = PIPE_TEX_WRAP_REPEAT;;
|
|
||||||
break;
|
|
||||||
case VG_TILE_REFLECT:
|
|
||||||
tex_wrap = PIPE_TEX_WRAP_MIRROR_REPEAT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
debug_assert(!"Unknown tiling mode");
|
|
||||||
tex_wrap = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sampler.wrap_s = tex_wrap;
|
|
||||||
sampler.wrap_t = tex_wrap;
|
|
||||||
sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
|
|
||||||
samplers[0] = samplers[1] = &sampler;
|
|
||||||
views[0] = info->src->sampler_view;
|
|
||||||
views[1] = info->extra_texture_view;
|
|
||||||
|
|
||||||
shader = info->setup_shader(ctx, info->user_data);
|
|
||||||
|
|
||||||
if (renderer_filter_begin(ctx->renderer,
|
|
||||||
info->dst->sampler_view->texture, VG_TRUE,
|
|
||||||
ctx->state.vg.filter_channel_mask,
|
|
||||||
samplers, views, (info->extra_texture_view) ? 2 : 1,
|
|
||||||
shader->driver, info->const_buffer, info->const_buffer_len)) {
|
|
||||||
renderer_filter(ctx->renderer,
|
|
||||||
info->dst->x, info->dst->y, info->dst->width, info->dst->height,
|
|
||||||
info->src->x, info->src->y, info->src->width, info->src->height);
|
|
||||||
renderer_filter_end(ctx->renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_shader_destroy(ctx, shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaColorMatrix(VGImage dst, VGImage src,
|
|
||||||
const VGfloat * matrix)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *d, *s;
|
|
||||||
struct filter_info info;
|
|
||||||
|
|
||||||
if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!matrix || !is_aligned(matrix)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d = handle_to_image(dst);
|
|
||||||
s = handle_to_image(src);
|
|
||||||
|
|
||||||
if (vg_image_overlaps(d, s)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
info.dst = d;
|
|
||||||
info.src = s;
|
|
||||||
info.setup_shader = &setup_color_matrix;
|
|
||||||
info.user_data = NULL;
|
|
||||||
info.const_buffer = matrix;
|
|
||||||
info.const_buffer_len = 20 * sizeof(VGfloat);
|
|
||||||
info.tiling_mode = VG_TILE_PAD;
|
|
||||||
info.extra_texture_view = NULL;
|
|
||||||
execute_filter(ctx, &info);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VGfloat texture_offset(VGfloat width, VGint kernelSize, VGint current, VGint shift)
|
|
||||||
{
|
|
||||||
VGfloat diff = (VGfloat) (current - shift);
|
|
||||||
|
|
||||||
return diff / width;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaConvolve(VGImage dst, VGImage src,
|
|
||||||
VGint kernelWidth, VGint kernelHeight,
|
|
||||||
VGint shiftX, VGint shiftY,
|
|
||||||
const VGshort * kernel,
|
|
||||||
VGfloat scale,
|
|
||||||
VGfloat bias,
|
|
||||||
VGTilingMode tilingMode)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
VGfloat *buffer;
|
|
||||||
VGint buffer_len;
|
|
||||||
VGint i, j;
|
|
||||||
VGint idx = 0;
|
|
||||||
struct vg_image *d, *s;
|
|
||||||
VGint kernel_size = kernelWidth * kernelHeight;
|
|
||||||
struct filter_info info;
|
|
||||||
const VGint max_kernel_size = vegaGeti(VG_MAX_KERNEL_SIZE);
|
|
||||||
|
|
||||||
if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kernelWidth <= 0 || kernelHeight <= 0 ||
|
|
||||||
kernelWidth > max_kernel_size || kernelHeight > max_kernel_size) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!kernel || !is_aligned_to(kernel, 2)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tilingMode < VG_TILE_FILL ||
|
|
||||||
tilingMode > VG_TILE_REFLECT) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d = handle_to_image(dst);
|
|
||||||
s = handle_to_image(src);
|
|
||||||
|
|
||||||
if (vg_image_overlaps(d, s)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
|
|
||||||
buffer_len = 8 + 2 * 4 * kernel_size;
|
|
||||||
buffer = malloc(buffer_len * sizeof(VGfloat));
|
|
||||||
|
|
||||||
buffer[0] = 0.f;
|
|
||||||
buffer[1] = 1.f;
|
|
||||||
buffer[2] = 2.f; /*unused*/
|
|
||||||
buffer[3] = 4.f; /*unused*/
|
|
||||||
|
|
||||||
buffer[4] = (VGfloat) (kernelWidth * kernelHeight);
|
|
||||||
buffer[5] = scale;
|
|
||||||
buffer[6] = bias;
|
|
||||||
buffer[7] = 0.f;
|
|
||||||
|
|
||||||
idx = 8;
|
|
||||||
for (j = 0; j < kernelHeight; ++j) {
|
|
||||||
for (i = 0; i < kernelWidth; ++i) {
|
|
||||||
VGint index = j * kernelWidth + i;
|
|
||||||
VGfloat x, y;
|
|
||||||
|
|
||||||
x = (VGfloat) texture_offset(s->width, kernelWidth, i, shiftX);
|
|
||||||
y = (VGfloat) texture_offset(s->height, kernelHeight, j, shiftY);
|
|
||||||
|
|
||||||
buffer[idx + index*4 + 0] = x;
|
|
||||||
buffer[idx + index*4 + 1] = y;
|
|
||||||
buffer[idx + index*4 + 2] = 0.f;
|
|
||||||
buffer[idx + index*4 + 3] = 0.f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
idx += kernel_size * 4;
|
|
||||||
|
|
||||||
for (j = 0; j < kernelHeight; ++j) {
|
|
||||||
for (i = 0; i < kernelWidth; ++i) {
|
|
||||||
/* transpose the kernel */
|
|
||||||
VGint index = j * kernelWidth + i;
|
|
||||||
VGint kindex = (kernelWidth - i - 1) * kernelHeight + (kernelHeight - j - 1);
|
|
||||||
buffer[idx + index*4 + 0] = kernel[kindex];
|
|
||||||
buffer[idx + index*4 + 1] = kernel[kindex];
|
|
||||||
buffer[idx + index*4 + 2] = kernel[kindex];
|
|
||||||
buffer[idx + index*4 + 3] = kernel[kindex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
info.dst = d;
|
|
||||||
info.src = s;
|
|
||||||
info.setup_shader = &setup_convolution;
|
|
||||||
info.user_data = (void*)(long)(buffer_len/4);
|
|
||||||
info.const_buffer = buffer;
|
|
||||||
info.const_buffer_len = buffer_len * sizeof(VGfloat);
|
|
||||||
info.tiling_mode = tilingMode;
|
|
||||||
info.extra_texture_view = NULL;
|
|
||||||
execute_filter(ctx, &info);
|
|
||||||
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaSeparableConvolve(VGImage dst, VGImage src,
|
|
||||||
VGint kernelWidth,
|
|
||||||
VGint kernelHeight,
|
|
||||||
VGint shiftX, VGint shiftY,
|
|
||||||
const VGshort * kernelX,
|
|
||||||
const VGshort * kernelY,
|
|
||||||
VGfloat scale,
|
|
||||||
VGfloat bias,
|
|
||||||
VGTilingMode tilingMode)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
VGshort *kernel;
|
|
||||||
VGint i, j, idx = 0;
|
|
||||||
const VGint max_kernel_size = vegaGeti(VG_MAX_SEPARABLE_KERNEL_SIZE);
|
|
||||||
|
|
||||||
if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kernelWidth <= 0 || kernelHeight <= 0 ||
|
|
||||||
kernelWidth > max_kernel_size || kernelHeight > max_kernel_size) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!kernelX || !kernelY ||
|
|
||||||
!is_aligned_to(kernelX, 2) || !is_aligned_to(kernelY, 2)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (tilingMode < VG_TILE_FILL ||
|
|
||||||
tilingMode > VG_TILE_REFLECT) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
kernel = malloc(sizeof(VGshort)*kernelWidth*kernelHeight);
|
|
||||||
for (i = 0; i < kernelWidth; ++i) {
|
|
||||||
for (j = 0; j < kernelHeight; ++j) {
|
|
||||||
kernel[idx] = kernelX[i] * kernelY[j];
|
|
||||||
++idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vegaConvolve(dst, src, kernelWidth, kernelHeight, shiftX, shiftY,
|
|
||||||
kernel, scale, bias, tilingMode);
|
|
||||||
free(kernel);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGfloat compute_gaussian_componenet(VGfloat x, VGfloat y,
|
|
||||||
VGfloat stdDeviationX,
|
|
||||||
VGfloat stdDeviationY)
|
|
||||||
{
|
|
||||||
VGfloat mult = 1 / ( 2 * M_PI * stdDeviationX * stdDeviationY);
|
|
||||||
VGfloat e = exp( - ( pow(x, 2)/(2*pow(stdDeviationX, 2)) +
|
|
||||||
pow(y, 2)/(2*pow(stdDeviationY, 2)) ) );
|
|
||||||
return mult * e;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGint compute_kernel_size(VGfloat deviation)
|
|
||||||
{
|
|
||||||
VGint size = ceil(2.146 * deviation);
|
|
||||||
if (size > 11)
|
|
||||||
return 11;
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void compute_gaussian_kernel(VGfloat *kernel,
|
|
||||||
VGint width, VGint height,
|
|
||||||
VGfloat stdDeviationX,
|
|
||||||
VGfloat stdDeviationY)
|
|
||||||
{
|
|
||||||
VGint i, j;
|
|
||||||
VGfloat scale = 0.0f;
|
|
||||||
|
|
||||||
for (j = 0; j < height; ++j) {
|
|
||||||
for (i = 0; i < width; ++i) {
|
|
||||||
VGint idx = (height - j -1) * width + (width - i -1);
|
|
||||||
kernel[idx] = compute_gaussian_componenet(i-(ceil(width/2))-1,
|
|
||||||
j-ceil(height/2)-1,
|
|
||||||
stdDeviationX, stdDeviationY);
|
|
||||||
scale += kernel[idx];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < height; ++j) {
|
|
||||||
for (i = 0; i < width; ++i) {
|
|
||||||
VGint idx = j * width + i;
|
|
||||||
kernel[idx] /= scale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaGaussianBlur(VGImage dst, VGImage src,
|
|
||||||
VGfloat stdDeviationX,
|
|
||||||
VGfloat stdDeviationY,
|
|
||||||
VGTilingMode tilingMode)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *d, *s;
|
|
||||||
VGfloat *buffer, *kernel;
|
|
||||||
VGint kernel_width, kernel_height, kernel_size;
|
|
||||||
VGint buffer_len;
|
|
||||||
VGint idx, i, j;
|
|
||||||
struct filter_info info;
|
|
||||||
|
|
||||||
if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (stdDeviationX <= 0 || stdDeviationY <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tilingMode < VG_TILE_FILL ||
|
|
||||||
tilingMode > VG_TILE_REFLECT) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d = handle_to_image(dst);
|
|
||||||
s = handle_to_image(src);
|
|
||||||
|
|
||||||
if (vg_image_overlaps(d, s)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel_width = compute_kernel_size(stdDeviationX);
|
|
||||||
kernel_height = compute_kernel_size(stdDeviationY);
|
|
||||||
kernel_size = kernel_width * kernel_height;
|
|
||||||
kernel = malloc(sizeof(VGfloat)*kernel_size);
|
|
||||||
compute_gaussian_kernel(kernel, kernel_width, kernel_height,
|
|
||||||
stdDeviationX, stdDeviationY);
|
|
||||||
|
|
||||||
buffer_len = 8 + 2 * 4 * kernel_size;
|
|
||||||
buffer = malloc(buffer_len * sizeof(VGfloat));
|
|
||||||
|
|
||||||
buffer[0] = 0.f;
|
|
||||||
buffer[1] = 1.f;
|
|
||||||
buffer[2] = 2.f; /*unused*/
|
|
||||||
buffer[3] = 4.f; /*unused*/
|
|
||||||
|
|
||||||
buffer[4] = kernel_width * kernel_height;
|
|
||||||
buffer[5] = 1.f;/*scale*/
|
|
||||||
buffer[6] = 0.f;/*bias*/
|
|
||||||
buffer[7] = 0.f;
|
|
||||||
|
|
||||||
idx = 8;
|
|
||||||
for (j = 0; j < kernel_height; ++j) {
|
|
||||||
for (i = 0; i < kernel_width; ++i) {
|
|
||||||
VGint index = j * kernel_width + i;
|
|
||||||
VGfloat x, y;
|
|
||||||
|
|
||||||
x = texture_offset(s->width, kernel_width, i, kernel_width/2);
|
|
||||||
y = texture_offset(s->height, kernel_height, j, kernel_height/2);
|
|
||||||
|
|
||||||
buffer[idx + index*4 + 0] = x;
|
|
||||||
buffer[idx + index*4 + 1] = y;
|
|
||||||
buffer[idx + index*4 + 2] = 0.f;
|
|
||||||
buffer[idx + index*4 + 3] = 0.f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
idx += kernel_size * 4;
|
|
||||||
|
|
||||||
for (j = 0; j < kernel_height; ++j) {
|
|
||||||
for (i = 0; i < kernel_width; ++i) {
|
|
||||||
/* transpose the kernel */
|
|
||||||
VGint index = j * kernel_width + i;
|
|
||||||
VGint kindex = (kernel_width - i - 1) * kernel_height + (kernel_height - j - 1);
|
|
||||||
buffer[idx + index*4 + 0] = kernel[kindex];
|
|
||||||
buffer[idx + index*4 + 1] = kernel[kindex];
|
|
||||||
buffer[idx + index*4 + 2] = kernel[kindex];
|
|
||||||
buffer[idx + index*4 + 3] = kernel[kindex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
info.dst = d;
|
|
||||||
info.src = s;
|
|
||||||
info.setup_shader = &setup_convolution;
|
|
||||||
info.user_data = (void*)(long)(buffer_len/4);
|
|
||||||
info.const_buffer = buffer;
|
|
||||||
info.const_buffer_len = buffer_len * sizeof(VGfloat);
|
|
||||||
info.tiling_mode = tilingMode;
|
|
||||||
info.extra_texture_view = NULL;
|
|
||||||
execute_filter(ctx, &info);
|
|
||||||
|
|
||||||
free(buffer);
|
|
||||||
free(kernel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaLookup(VGImage dst, VGImage src,
|
|
||||||
const VGubyte * redLUT,
|
|
||||||
const VGubyte * greenLUT,
|
|
||||||
const VGubyte * blueLUT,
|
|
||||||
const VGubyte * alphaLUT,
|
|
||||||
VGboolean outputLinear,
|
|
||||||
VGboolean outputPremultiplied)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *d, *s;
|
|
||||||
VGuint color_data[256];
|
|
||||||
VGint i;
|
|
||||||
struct pipe_sampler_view *lut_texture_view;
|
|
||||||
VGfloat buffer[4];
|
|
||||||
struct filter_info info;
|
|
||||||
|
|
||||||
if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!redLUT || !greenLUT || !blueLUT || !alphaLUT) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d = handle_to_image(dst);
|
|
||||||
s = handle_to_image(src);
|
|
||||||
|
|
||||||
if (vg_image_overlaps(d, s)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 256; ++i) {
|
|
||||||
color_data[i] = blueLUT[i] << 24 | greenLUT[i] << 16 |
|
|
||||||
redLUT[i] << 8 | alphaLUT[i];
|
|
||||||
}
|
|
||||||
lut_texture_view = create_texture_1d_view(ctx, color_data, 255);
|
|
||||||
|
|
||||||
buffer[0] = 0.f;
|
|
||||||
buffer[1] = 0.f;
|
|
||||||
buffer[2] = 1.f;
|
|
||||||
buffer[3] = 1.f;
|
|
||||||
|
|
||||||
info.dst = d;
|
|
||||||
info.src = s;
|
|
||||||
info.setup_shader = &setup_lookup;
|
|
||||||
info.user_data = NULL;
|
|
||||||
info.const_buffer = buffer;
|
|
||||||
info.const_buffer_len = 4 * sizeof(VGfloat);
|
|
||||||
info.tiling_mode = VG_TILE_PAD;
|
|
||||||
info.extra_texture_view = lut_texture_view;
|
|
||||||
|
|
||||||
execute_filter(ctx, &info);
|
|
||||||
|
|
||||||
pipe_sampler_view_reference(&lut_texture_view, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaLookupSingle(VGImage dst, VGImage src,
|
|
||||||
const VGuint * lookupTable,
|
|
||||||
VGImageChannel sourceChannel,
|
|
||||||
VGboolean outputLinear,
|
|
||||||
VGboolean outputPremultiplied)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *d, *s;
|
|
||||||
struct pipe_sampler_view *lut_texture_view;
|
|
||||||
VGfloat buffer[4];
|
|
||||||
struct filter_info info;
|
|
||||||
VGuint color_data[256];
|
|
||||||
VGint i;
|
|
||||||
|
|
||||||
if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!lookupTable || !is_aligned(lookupTable)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sourceChannel != VG_RED && sourceChannel != VG_GREEN &&
|
|
||||||
sourceChannel != VG_BLUE && sourceChannel != VG_ALPHA) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d = handle_to_image(dst);
|
|
||||||
s = handle_to_image(src);
|
|
||||||
|
|
||||||
if (vg_image_overlaps(d, s)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
|
|
||||||
for (i = 0; i < 256; ++i) {
|
|
||||||
VGuint rgba = lookupTable[i];
|
|
||||||
VGubyte blue, green, red, alpha;
|
|
||||||
red = (rgba & 0xff000000)>>24;
|
|
||||||
green = (rgba & 0x00ff0000)>>16;
|
|
||||||
blue = (rgba & 0x0000ff00)>> 8;
|
|
||||||
alpha = (rgba & 0x000000ff)>> 0;
|
|
||||||
color_data[i] = blue << 24 | green << 16 |
|
|
||||||
red << 8 | alpha;
|
|
||||||
}
|
|
||||||
lut_texture_view = create_texture_1d_view(ctx, color_data, 256);
|
|
||||||
|
|
||||||
buffer[0] = 0.f;
|
|
||||||
buffer[1] = 0.f;
|
|
||||||
buffer[2] = 1.f;
|
|
||||||
buffer[3] = 1.f;
|
|
||||||
|
|
||||||
info.dst = d;
|
|
||||||
info.src = s;
|
|
||||||
info.setup_shader = &setup_lookup_single;
|
|
||||||
info.user_data = (void*)sourceChannel;
|
|
||||||
info.const_buffer = buffer;
|
|
||||||
info.const_buffer_len = 4 * sizeof(VGfloat);
|
|
||||||
info.tiling_mode = VG_TILE_PAD;
|
|
||||||
info.extra_texture_view = lut_texture_view;
|
|
||||||
|
|
||||||
execute_filter(ctx, &info);
|
|
||||||
|
|
||||||
pipe_sampler_view_reference(&lut_texture_view, NULL);
|
|
||||||
}
|
|
||||||
|
|
@ -1,492 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "image.h"
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "vg_translate.h"
|
|
||||||
#include "api_consts.h"
|
|
||||||
#include "api.h"
|
|
||||||
#include "handle.h"
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_screen.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "util/u_tile.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
|
|
||||||
static INLINE VGboolean supported_image_format(VGImageFormat format)
|
|
||||||
{
|
|
||||||
switch(format) {
|
|
||||||
case VG_sRGBX_8888:
|
|
||||||
case VG_sRGBA_8888:
|
|
||||||
case VG_sRGBA_8888_PRE:
|
|
||||||
case VG_sRGB_565:
|
|
||||||
case VG_sRGBA_5551:
|
|
||||||
case VG_sRGBA_4444:
|
|
||||||
case VG_sL_8:
|
|
||||||
case VG_lRGBX_8888:
|
|
||||||
case VG_lRGBA_8888:
|
|
||||||
case VG_lRGBA_8888_PRE:
|
|
||||||
case VG_lL_8:
|
|
||||||
case VG_A_8:
|
|
||||||
case VG_BW_1:
|
|
||||||
#ifdef OPENVG_VERSION_1_1
|
|
||||||
case VG_A_1:
|
|
||||||
case VG_A_4:
|
|
||||||
#endif
|
|
||||||
case VG_sXRGB_8888:
|
|
||||||
case VG_sARGB_8888:
|
|
||||||
case VG_sARGB_8888_PRE:
|
|
||||||
case VG_sARGB_1555:
|
|
||||||
case VG_sARGB_4444:
|
|
||||||
case VG_lXRGB_8888:
|
|
||||||
case VG_lARGB_8888:
|
|
||||||
case VG_lARGB_8888_PRE:
|
|
||||||
case VG_sBGRX_8888:
|
|
||||||
case VG_sBGRA_8888:
|
|
||||||
case VG_sBGRA_8888_PRE:
|
|
||||||
case VG_sBGR_565:
|
|
||||||
case VG_sBGRA_5551:
|
|
||||||
case VG_sBGRA_4444:
|
|
||||||
case VG_lBGRX_8888:
|
|
||||||
case VG_lBGRA_8888:
|
|
||||||
case VG_lBGRA_8888_PRE:
|
|
||||||
case VG_sXBGR_8888:
|
|
||||||
case VG_sABGR_8888:
|
|
||||||
case VG_sABGR_8888_PRE:
|
|
||||||
case VG_sABGR_1555:
|
|
||||||
case VG_sABGR_4444:
|
|
||||||
case VG_lXBGR_8888:
|
|
||||||
case VG_lABGR_8888:
|
|
||||||
case VG_lABGR_8888_PRE:
|
|
||||||
return VG_TRUE;
|
|
||||||
default:
|
|
||||||
return VG_FALSE;
|
|
||||||
}
|
|
||||||
return VG_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGImage vegaCreateImage(VGImageFormat format,
|
|
||||||
VGint width, VGint height,
|
|
||||||
VGbitfield allowedQuality)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (!supported_image_format(format)) {
|
|
||||||
vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
if (width > vegaGeti(VG_MAX_IMAGE_WIDTH) ||
|
|
||||||
height > vegaGeti(VG_MAX_IMAGE_HEIGHT)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
if (width * height > vegaGeti(VG_MAX_IMAGE_PIXELS)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(allowedQuality & ((VG_IMAGE_QUALITY_NONANTIALIASED |
|
|
||||||
VG_IMAGE_QUALITY_FASTER |
|
|
||||||
VG_IMAGE_QUALITY_BETTER)))) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return image_to_handle(image_create(format, width, height));
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaDestroyImage(VGImage image)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *img = handle_to_image(image);
|
|
||||||
|
|
||||||
if (image == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!vg_object_is_valid(image, VG_OBJECT_IMAGE)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
image_destroy(img);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaClearImage(VGImage image,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *img;
|
|
||||||
|
|
||||||
if (image == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
img = handle_to_image(image);
|
|
||||||
|
|
||||||
if (x + width < 0 || y + height < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
image_clear(img, x, y, width, height);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaImageSubData(VGImage image,
|
|
||||||
const void * data,
|
|
||||||
VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *img;
|
|
||||||
|
|
||||||
if (image == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!supported_image_format(dataFormat)) {
|
|
||||||
vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0 || !data || !is_aligned(data)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
img = handle_to_image(image);
|
|
||||||
image_sub_data(img, data, dataStride, dataFormat,
|
|
||||||
x, y, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaGetImageSubData(VGImage image,
|
|
||||||
void * data,
|
|
||||||
VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *img;
|
|
||||||
|
|
||||||
if (image == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!supported_image_format(dataFormat)) {
|
|
||||||
vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0 || !data || !is_aligned(data)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
img = handle_to_image(image);
|
|
||||||
image_get_sub_data(img, data, dataStride, dataFormat,
|
|
||||||
x, y, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
VGImage vegaChildImage(VGImage parent,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *p;
|
|
||||||
|
|
||||||
if (parent == VG_INVALID_HANDLE ||
|
|
||||||
!vg_context_is_object_valid(ctx, VG_OBJECT_IMAGE, parent) ||
|
|
||||||
!vg_object_is_valid(parent, VG_OBJECT_IMAGE)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0 || x < 0 || y < 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
p = handle_to_image(parent);
|
|
||||||
if (x > p->width || y > p->height) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
if (x + width > p->width || y + height > p->height) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return image_to_handle(image_child_image(p, x, y, width, height));
|
|
||||||
}
|
|
||||||
|
|
||||||
VGImage vegaGetParent(VGImage image)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *img;
|
|
||||||
|
|
||||||
if (image == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
img = handle_to_image(image);
|
|
||||||
if (img->parent)
|
|
||||||
return image_to_handle(img->parent);
|
|
||||||
else
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaCopyImage(VGImage dst, VGint dx, VGint dy,
|
|
||||||
VGImage src, VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height,
|
|
||||||
VGboolean dither)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (src == VG_INVALID_HANDLE || dst == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
image_copy(handle_to_image(dst), dx, dy,
|
|
||||||
handle_to_image(src), sx, sy,
|
|
||||||
width, height, dither);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaDrawImage(VGImage image)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (image == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
image_draw(handle_to_image(image),
|
|
||||||
&ctx->state.vg.image_user_to_surface_matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaSetPixels(VGint dx, VGint dy,
|
|
||||||
VGImage src, VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
|
|
||||||
if (src == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
image_set_pixels(dx, dy, handle_to_image(src), sx, sy, width,
|
|
||||||
height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaGetPixels(VGImage dst, VGint dx, VGint dy,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *img;
|
|
||||||
|
|
||||||
if (dst == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
img = handle_to_image(dst);
|
|
||||||
|
|
||||||
image_get_pixels(img, dx, dy,
|
|
||||||
sx, sy, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaWritePixels(const void * data, VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint dx, VGint dy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (!supported_image_format(dataFormat)) {
|
|
||||||
vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!data || !is_aligned(data)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
{
|
|
||||||
struct vg_image *img = image_create(dataFormat, width, height);
|
|
||||||
image_sub_data(img, data, dataStride, dataFormat, 0, 0,
|
|
||||||
width, height);
|
|
||||||
#if 0
|
|
||||||
struct matrix *matrix = &ctx->state.vg.image_user_to_surface_matrix;
|
|
||||||
matrix_translate(matrix, dx, dy);
|
|
||||||
image_draw(img);
|
|
||||||
matrix_translate(matrix, -dx, -dy);
|
|
||||||
#else
|
|
||||||
/* this looks like a better approach */
|
|
||||||
image_set_pixels(dx, dy, img, 0, 0, width, height);
|
|
||||||
#endif
|
|
||||||
image_destroy(img);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaReadPixels(void * data, VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
struct st_renderbuffer *strb = stfb->strb;
|
|
||||||
|
|
||||||
VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
|
|
||||||
VGfloat *df = (VGfloat*)temp;
|
|
||||||
VGint i;
|
|
||||||
VGubyte *dst = (VGubyte *)data;
|
|
||||||
VGint xoffset = 0, yoffset = 0;
|
|
||||||
|
|
||||||
if (!supported_image_format(dataFormat)) {
|
|
||||||
vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!data || !is_aligned(data)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sx < 0) {
|
|
||||||
xoffset = -sx;
|
|
||||||
xoffset *= _vega_size_for_format(dataFormat);
|
|
||||||
width += sx;
|
|
||||||
sx = 0;
|
|
||||||
}
|
|
||||||
if (sy < 0) {
|
|
||||||
yoffset = -sy;
|
|
||||||
yoffset *= dataStride;
|
|
||||||
height += sy;
|
|
||||||
sy = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sx + width > stfb->width || sy + height > stfb->height) {
|
|
||||||
width = stfb->width - sx;
|
|
||||||
height = stfb->height - sy;
|
|
||||||
/* nothing to read */
|
|
||||||
if (width <= 0 || height <= 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
VGint y = (stfb->height - sy) - 1, yStep = -1;
|
|
||||||
struct pipe_transfer *transfer;
|
|
||||||
void *map;
|
|
||||||
|
|
||||||
map = pipe_transfer_map(pipe, strb->texture, 0, 0,
|
|
||||||
PIPE_TRANSFER_READ,
|
|
||||||
0, 0, sx + width, stfb->height - sy,
|
|
||||||
&transfer);
|
|
||||||
|
|
||||||
/* Do a row at a time to flip image data vertically */
|
|
||||||
for (i = 0; i < height; i++) {
|
|
||||||
#if 0
|
|
||||||
debug_printf("%d-%d == %d\n", sy, height, y);
|
|
||||||
#endif
|
|
||||||
pipe_get_tile_rgba(transfer, map, sx, y, width, 1, df);
|
|
||||||
y += yStep;
|
|
||||||
_vega_pack_rgba_span_float(ctx, width, temp, dataFormat,
|
|
||||||
dst + yoffset + xoffset);
|
|
||||||
dst += dataStride;
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe->transfer_unmap(pipe, transfer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaCopyPixels(VGint dx, VGint dy,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
struct st_renderbuffer *strb = stfb->strb;
|
|
||||||
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* do nothing if we copy from outside the fb */
|
|
||||||
if (dx >= (VGint)stfb->width || dy >= (VGint)stfb->height ||
|
|
||||||
sx >= (VGint)stfb->width || sy >= (VGint)stfb->height)
|
|
||||||
return;
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
/* make sure rendering has completed */
|
|
||||||
vegaFinish();
|
|
||||||
|
|
||||||
vg_copy_surface(ctx, strb->surface, dx, dy,
|
|
||||||
strb->surface, sx, sy, width, height);
|
|
||||||
}
|
|
||||||
|
|
@ -1,246 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "mask.h"
|
|
||||||
#include "api.h"
|
|
||||||
#include "handle.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
|
|
||||||
void vegaMask(VGHandle mask, VGMaskOperation operation,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (width <=0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (operation < VG_CLEAR_MASK || operation > VG_SUBTRACT_MASK) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
|
|
||||||
if (operation == VG_CLEAR_MASK) {
|
|
||||||
mask_fill(x, y, width, height, 0.f);
|
|
||||||
} else if (operation == VG_FILL_MASK) {
|
|
||||||
mask_fill(x, y, width, height, 1.f);
|
|
||||||
} else if (vg_object_is_valid(mask, VG_OBJECT_IMAGE)) {
|
|
||||||
struct vg_image *image = handle_to_image(mask);
|
|
||||||
mask_using_image(image, operation, x, y, width, height);
|
|
||||||
} else if (vg_object_is_valid(mask, VG_OBJECT_MASK)) {
|
|
||||||
struct vg_mask_layer *layer = handle_to_masklayer(mask);
|
|
||||||
mask_using_layer(layer, operation, x, y, width, height);
|
|
||||||
} else {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaClear(VGint x, VGint y,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
#if 0
|
|
||||||
debug_printf("Clear [%d, %d, %d, %d] with [%f, %f, %f, %f]\n",
|
|
||||||
x, y, width, height,
|
|
||||||
ctx->state.vg.clear_color[0],
|
|
||||||
ctx->state.vg.clear_color[1],
|
|
||||||
ctx->state.vg.clear_color[2],
|
|
||||||
ctx->state.vg.clear_color[3]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* check for a whole surface clear */
|
|
||||||
if (!ctx->state.vg.scissoring &&
|
|
||||||
(x == 0 && y == 0 && width == stfb->width && height == stfb->height)) {
|
|
||||||
union pipe_color_union clear_color;
|
|
||||||
clear_color.f[0] = ctx->state.vg.clear_color[0];
|
|
||||||
clear_color.f[1] = ctx->state.vg.clear_color[1];
|
|
||||||
clear_color.f[2] = ctx->state.vg.clear_color[2];
|
|
||||||
clear_color.f[3] = ctx->state.vg.clear_color[3];
|
|
||||||
ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_COLOR0 | PIPE_CLEAR_DEPTHSTENCIL,
|
|
||||||
&clear_color, 1., 0);
|
|
||||||
} else if (renderer_clear_begin(ctx->renderer)) {
|
|
||||||
/* XXX verify coord round-off */
|
|
||||||
renderer_clear(ctx->renderer, x, y, width, height, ctx->state.vg.clear_color);
|
|
||||||
renderer_clear_end(ctx->renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef OPENVG_VERSION_1_1
|
|
||||||
|
|
||||||
|
|
||||||
void vegaRenderToMask(VGPath path,
|
|
||||||
VGbitfield paintModes,
|
|
||||||
VGMaskOperation operation)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!paintModes || (paintModes&(~(VG_STROKE_PATH|VG_FILL_PATH)))) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (operation < VG_CLEAR_MASK ||
|
|
||||||
operation > VG_SUBTRACT_MASK) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!vg_object_is_valid(path, VG_OBJECT_PATH)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
|
|
||||||
mask_render_to(handle_to_path(path), paintModes, operation);
|
|
||||||
}
|
|
||||||
|
|
||||||
VGMaskLayer vegaCreateMaskLayer(VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (width <= 0 || height <= 0 ||
|
|
||||||
width > vegaGeti(VG_MAX_IMAGE_WIDTH) ||
|
|
||||||
height > vegaGeti(VG_MAX_IMAGE_HEIGHT)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return masklayer_to_handle(mask_layer_create(width, height));
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaDestroyMaskLayer(VGMaskLayer maskLayer)
|
|
||||||
{
|
|
||||||
struct vg_mask_layer *mask = 0;
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (maskLayer == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!vg_object_is_valid(maskLayer, VG_OBJECT_MASK)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mask = handle_to_masklayer(maskLayer);
|
|
||||||
mask_layer_destroy(mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaFillMaskLayer(VGMaskLayer maskLayer,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height,
|
|
||||||
VGfloat value)
|
|
||||||
{
|
|
||||||
struct vg_mask_layer *mask = 0;
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (maskLayer == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value < 0 || value > 1) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (x < 0 || y < 0 || (x + width) < 0 || (y + height) < 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vg_object_is_valid(maskLayer, VG_OBJECT_MASK)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mask = handle_to_masklayer(maskLayer);
|
|
||||||
|
|
||||||
if (x + width > mask_layer_width(mask) ||
|
|
||||||
y + height > mask_layer_height(mask)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
|
|
||||||
mask_layer_fill(mask, x, y, width, height, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaCopyMask(VGMaskLayer maskLayer,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint dx, VGint dy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_mask_layer *mask = 0;
|
|
||||||
|
|
||||||
if (maskLayer == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!vg_object_is_valid(maskLayer, VG_OBJECT_MASK)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
|
|
||||||
mask = handle_to_masklayer(maskLayer);
|
|
||||||
mask_copy(mask, sx, sy, dx, dy, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "api.h"
|
|
||||||
|
|
||||||
/* Hardware Queries */
|
|
||||||
VGHardwareQueryResult vegaHardwareQuery(VGHardwareQueryType key,
|
|
||||||
VGint setting)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (key < VG_IMAGE_FORMAT_QUERY ||
|
|
||||||
key > VG_PATH_DATATYPE_QUERY) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_HARDWARE_UNACCELERATED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key == VG_IMAGE_FORMAT_QUERY) {
|
|
||||||
if (setting < VG_sRGBX_8888 ||
|
|
||||||
setting > VG_lABGR_8888_PRE) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_HARDWARE_UNACCELERATED;
|
|
||||||
}
|
|
||||||
} else if (key == VG_PATH_DATATYPE_QUERY) {
|
|
||||||
if (setting < VG_PATH_DATATYPE_S_8 ||
|
|
||||||
setting > VG_PATH_DATATYPE_F) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_HARDWARE_UNACCELERATED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* we're supposed to accelerate everything */
|
|
||||||
return VG_HARDWARE_ACCELERATED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Renderer and Extension Information */
|
|
||||||
const VGubyte *vegaGetString(VGStringID name)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
static const VGubyte *vendor = (VGubyte *)"Mesa Project";
|
|
||||||
static const VGubyte *renderer = (VGubyte *)"Vega OpenVG 1.1";
|
|
||||||
static const VGubyte *version = (VGubyte *)"1.1";
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
switch(name) {
|
|
||||||
case VG_VENDOR:
|
|
||||||
return vendor;
|
|
||||||
case VG_RENDERER:
|
|
||||||
return renderer;
|
|
||||||
case VG_VERSION:
|
|
||||||
return version;
|
|
||||||
case VG_EXTENSIONS:
|
|
||||||
return NULL;
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,172 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "paint.h"
|
|
||||||
#include "api.h"
|
|
||||||
#include "handle.h"
|
|
||||||
|
|
||||||
|
|
||||||
VGPaint vegaCreatePaint(void)
|
|
||||||
{
|
|
||||||
return paint_to_handle(paint_create(vg_current_context()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaDestroyPaint(VGPaint p)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (p == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
paint_destroy(handle_to_paint(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaSetPaint(VGPaint paint, VGbitfield paintModes)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (paint == VG_INVALID_HANDLE) {
|
|
||||||
/* restore the default */
|
|
||||||
paint = paint_to_handle(ctx->default_paint);
|
|
||||||
} else if (!vg_object_is_valid(paint, VG_OBJECT_PAINT)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(paintModes & ((VG_FILL_PATH|VG_STROKE_PATH)))) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (paintModes & VG_FILL_PATH) {
|
|
||||||
ctx->state.vg.fill_paint = handle_to_paint(paint);
|
|
||||||
}
|
|
||||||
if (paintModes & VG_STROKE_PATH) {
|
|
||||||
ctx->state.vg.stroke_paint = handle_to_paint(paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->state.dirty |= PAINT_DIRTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGPaint vegaGetPaint(VGPaintMode paintMode)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
VGPaint paint = VG_INVALID_HANDLE;
|
|
||||||
|
|
||||||
if (paintMode < VG_STROKE_PATH || paintMode > VG_FILL_PATH) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (paintMode == VG_FILL_PATH)
|
|
||||||
paint = paint_to_handle(ctx->state.vg.fill_paint);
|
|
||||||
else if (paintMode == VG_STROKE_PATH)
|
|
||||||
paint = paint_to_handle(ctx->state.vg.stroke_paint);
|
|
||||||
|
|
||||||
if (paint == paint_to_handle(ctx->default_paint))
|
|
||||||
paint = VG_INVALID_HANDLE;
|
|
||||||
|
|
||||||
return paint;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaSetColor(VGPaint paint, VGuint rgba)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_paint *p;
|
|
||||||
|
|
||||||
if (paint == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vg_object_is_valid(paint, VG_OBJECT_PAINT)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = handle_to_paint(paint);
|
|
||||||
paint_set_colori(p, rgba);
|
|
||||||
|
|
||||||
if (ctx->state.vg.fill_paint == p ||
|
|
||||||
ctx->state.vg.stroke_paint == p)
|
|
||||||
ctx->state.dirty |= PAINT_DIRTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGuint vegaGetColor(VGPaint paint)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_paint *p;
|
|
||||||
VGuint rgba = 0;
|
|
||||||
|
|
||||||
if (paint == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return rgba;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vg_object_is_valid(paint, VG_OBJECT_PAINT)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return rgba;
|
|
||||||
}
|
|
||||||
p = handle_to_paint(paint);
|
|
||||||
|
|
||||||
return paint_colori(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaPaintPattern(VGPaint paint, VGImage pattern)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (paint == VG_INVALID_HANDLE ||
|
|
||||||
!vg_context_is_object_valid(ctx, VG_OBJECT_PAINT, paint)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pattern == VG_INVALID_HANDLE) {
|
|
||||||
paint_set_type(handle_to_paint(paint), VG_PAINT_TYPE_COLOR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vg_context_is_object_valid(ctx, VG_OBJECT_IMAGE, pattern)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!vg_object_is_valid(paint, VG_OBJECT_PAINT) ||
|
|
||||||
!vg_object_is_valid(pattern, VG_OBJECT_IMAGE)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
paint_set_pattern(handle_to_paint(paint),
|
|
||||||
handle_to_image(pattern));
|
|
||||||
}
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,487 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "handle.h"
|
|
||||||
#include "path.h"
|
|
||||||
#include "api.h"
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
|
|
||||||
VGPath vegaCreatePath(VGint pathFormat,
|
|
||||||
VGPathDatatype datatype,
|
|
||||||
VGfloat scale, VGfloat bias,
|
|
||||||
VGint segmentCapacityHint,
|
|
||||||
VGint coordCapacityHint,
|
|
||||||
VGbitfield capabilities)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (pathFormat != VG_PATH_FORMAT_STANDARD) {
|
|
||||||
vg_set_error(ctx, VG_UNSUPPORTED_PATH_FORMAT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
if (datatype < VG_PATH_DATATYPE_S_8 ||
|
|
||||||
datatype > VG_PATH_DATATYPE_F) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
if (!scale) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return path_to_handle(path_create(datatype, scale, bias,
|
|
||||||
segmentCapacityHint, coordCapacityHint,
|
|
||||||
capabilities));
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaClearPath(VGPath path, VGbitfield capabilities)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *p = 0;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = handle_to_path(path);
|
|
||||||
path_clear(p, capabilities);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaDestroyPath(VGPath p)
|
|
||||||
{
|
|
||||||
struct path *path = 0;
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (p == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = handle_to_path(p);
|
|
||||||
path_destroy(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaRemovePathCapabilities(VGPath path,
|
|
||||||
VGbitfield capabilities)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
VGbitfield current;
|
|
||||||
struct path *p;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = handle_to_path(path);
|
|
||||||
current = path_capabilities(p);
|
|
||||||
path_set_capabilities(p, (current &
|
|
||||||
(~(capabilities & VG_PATH_CAPABILITY_ALL))));
|
|
||||||
}
|
|
||||||
|
|
||||||
VGbitfield vegaGetPathCapabilities(VGPath path)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *p = 0;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
p = handle_to_path(path);
|
|
||||||
return path_capabilities(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaAppendPath(VGPath dstPath, VGPath srcPath)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *src, *dst;
|
|
||||||
|
|
||||||
if (dstPath == VG_INVALID_HANDLE || srcPath == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
src = handle_to_path(srcPath);
|
|
||||||
dst = handle_to_path(dstPath);
|
|
||||||
|
|
||||||
if (!(path_capabilities(src) & VG_PATH_CAPABILITY_APPEND_FROM) ||
|
|
||||||
!(path_capabilities(dst) & VG_PATH_CAPABILITY_APPEND_TO)) {
|
|
||||||
vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
path_append_path(dst, src);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaAppendPathData(VGPath dstPath,
|
|
||||||
VGint numSegments,
|
|
||||||
const VGubyte * pathSegments,
|
|
||||||
const void * pathData)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *p = 0;
|
|
||||||
VGint i;
|
|
||||||
|
|
||||||
if (dstPath == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!pathSegments) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (numSegments <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (i = 0; i < numSegments; ++i) {
|
|
||||||
if (pathSegments[i] > VG_LCWARC_TO_REL) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p = handle_to_path(dstPath);
|
|
||||||
|
|
||||||
if (!p || !is_aligned_to(p, path_datatype_size(p))) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(path_capabilities(p)&VG_PATH_CAPABILITY_APPEND_TO)) {
|
|
||||||
vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
path_append_data(p, numSegments, pathSegments, pathData);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaModifyPathCoords(VGPath dstPath,
|
|
||||||
VGint startIndex,
|
|
||||||
VGint numSegments,
|
|
||||||
const void * pathData)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *p = 0;
|
|
||||||
|
|
||||||
if (dstPath == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (startIndex < 0 || numSegments <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = handle_to_path(dstPath);
|
|
||||||
|
|
||||||
if (!pathData || !is_aligned_to(pathData, path_datatype_size(p))) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startIndex + numSegments > path_num_segments(p)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(path_capabilities(p)&VG_PATH_CAPABILITY_MODIFY)) {
|
|
||||||
vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
path_modify_coords(p, startIndex, numSegments, pathData);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaTransformPath(VGPath dstPath, VGPath srcPath)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *src = 0, *dst = 0;
|
|
||||||
|
|
||||||
if (dstPath == VG_INVALID_HANDLE || srcPath == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
src = handle_to_path(srcPath);
|
|
||||||
dst = handle_to_path(dstPath);
|
|
||||||
|
|
||||||
if (!(path_capabilities(src) & VG_PATH_CAPABILITY_TRANSFORM_FROM) ||
|
|
||||||
!(path_capabilities(dst) & VG_PATH_CAPABILITY_TRANSFORM_TO)) {
|
|
||||||
vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
path_transform(dst, src);
|
|
||||||
}
|
|
||||||
|
|
||||||
VGboolean vegaInterpolatePath(VGPath dstPath,
|
|
||||||
VGPath startPath,
|
|
||||||
VGPath endPath,
|
|
||||||
VGfloat amount)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *start = 0, *dst = 0, *end = 0;
|
|
||||||
|
|
||||||
if (dstPath == VG_INVALID_HANDLE ||
|
|
||||||
startPath == VG_INVALID_HANDLE ||
|
|
||||||
endPath == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return VG_FALSE;
|
|
||||||
}
|
|
||||||
dst = handle_to_path(dstPath);
|
|
||||||
start = handle_to_path(startPath);
|
|
||||||
end = handle_to_path(endPath);
|
|
||||||
|
|
||||||
if (!(path_capabilities(dst) & VG_PATH_CAPABILITY_INTERPOLATE_TO) ||
|
|
||||||
!(path_capabilities(start) & VG_PATH_CAPABILITY_INTERPOLATE_FROM) ||
|
|
||||||
!(path_capabilities(end) & VG_PATH_CAPABILITY_INTERPOLATE_FROM)) {
|
|
||||||
vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
|
|
||||||
return VG_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return path_interpolate(dst,
|
|
||||||
start, end, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
VGfloat vegaPathLength(VGPath path,
|
|
||||||
VGint startSegment,
|
|
||||||
VGint numSegments)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *p = 0;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (startSegment < 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (numSegments <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
p = handle_to_path(path);
|
|
||||||
|
|
||||||
if (!(path_capabilities(p) & VG_PATH_CAPABILITY_PATH_LENGTH)) {
|
|
||||||
vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (startSegment + numSegments > path_num_segments(p)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return path_length(p, startSegment, numSegments);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaPointAlongPath(VGPath path,
|
|
||||||
VGint startSegment,
|
|
||||||
VGint numSegments,
|
|
||||||
VGfloat distance,
|
|
||||||
VGfloat * x, VGfloat * y,
|
|
||||||
VGfloat * tangentX,
|
|
||||||
VGfloat * tangentY)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *p = 0;
|
|
||||||
VGbitfield caps;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (startSegment < 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (numSegments <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_aligned(x) || !is_aligned(y) ||
|
|
||||||
!is_aligned(tangentX) || !is_aligned(tangentY)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = handle_to_path(path);
|
|
||||||
|
|
||||||
caps = path_capabilities(p);
|
|
||||||
if (!(caps & VG_PATH_CAPABILITY_POINT_ALONG_PATH) ||
|
|
||||||
!(caps & VG_PATH_CAPABILITY_TANGENT_ALONG_PATH)) {
|
|
||||||
vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startSegment + numSegments > path_num_segments(p)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
VGfloat point[2], normal[2];
|
|
||||||
path_point(p, startSegment, numSegments, distance,
|
|
||||||
point, normal);
|
|
||||||
if (x)
|
|
||||||
*x = point[0];
|
|
||||||
if (y)
|
|
||||||
*y = point[1];
|
|
||||||
if (tangentX)
|
|
||||||
*tangentX = -normal[1];
|
|
||||||
if (tangentY)
|
|
||||||
*tangentY = normal[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaPathBounds(VGPath path,
|
|
||||||
VGfloat * minX,
|
|
||||||
VGfloat * minY,
|
|
||||||
VGfloat * width,
|
|
||||||
VGfloat * height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *p = 0;
|
|
||||||
VGbitfield caps;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!minX || !minY || !width || !height) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_aligned(minX) || !is_aligned(minY) ||
|
|
||||||
!is_aligned(width) || !is_aligned(height)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = handle_to_path(path);
|
|
||||||
|
|
||||||
caps = path_capabilities(p);
|
|
||||||
if (!(caps & VG_PATH_CAPABILITY_PATH_BOUNDS)) {
|
|
||||||
vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
path_bounding_rect(p, minX, minY, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaPathTransformedBounds(VGPath path,
|
|
||||||
VGfloat * minX,
|
|
||||||
VGfloat * minY,
|
|
||||||
VGfloat * width,
|
|
||||||
VGfloat * height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *p = 0;
|
|
||||||
VGbitfield caps;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!minX || !minY || !width || !height) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_aligned(minX) || !is_aligned(minY) ||
|
|
||||||
!is_aligned(width) || !is_aligned(height)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = handle_to_path(path);
|
|
||||||
|
|
||||||
caps = path_capabilities(p);
|
|
||||||
if (!(caps & VG_PATH_CAPABILITY_PATH_TRANSFORMED_BOUNDS)) {
|
|
||||||
vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* faster, but seems to have precision problems... */
|
|
||||||
path_bounding_rect(p, minX, minY, width, height);
|
|
||||||
if (*width > 0 && *height > 0) {
|
|
||||||
VGfloat pts[] = {*minX, *minY,
|
|
||||||
*minX + *width, *minY,
|
|
||||||
*minX + *width, *minY + *height,
|
|
||||||
*minX, *minY + *height};
|
|
||||||
struct matrix *matrix = &ctx->state.vg.path_user_to_surface_matrix;
|
|
||||||
VGfloat maxX, maxY;
|
|
||||||
matrix_map_point(matrix, pts[0], pts[1], pts + 0, pts + 1);
|
|
||||||
matrix_map_point(matrix, pts[2], pts[3], pts + 2, pts + 3);
|
|
||||||
matrix_map_point(matrix, pts[4], pts[5], pts + 4, pts + 5);
|
|
||||||
matrix_map_point(matrix, pts[6], pts[7], pts + 6, pts + 7);
|
|
||||||
*minX = MIN2(pts[0], MIN2(pts[2], MIN2(pts[4], pts[6])));
|
|
||||||
*minY = MIN2(pts[1], MIN2(pts[3], MIN2(pts[5], pts[7])));
|
|
||||||
maxX = MAX2(pts[0], MAX2(pts[2], MAX2(pts[4], pts[6])));
|
|
||||||
maxY = MAX2(pts[1], MAX2(pts[3], MAX2(pts[5], pts[7])));
|
|
||||||
*width = maxX - *minX;
|
|
||||||
*height = maxY - *minY;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
struct path *dst = path_create(VG_PATH_DATATYPE_F, 1.0, 0,
|
|
||||||
0, 0, VG_PATH_CAPABILITY_ALL);
|
|
||||||
path_transform(dst, p);
|
|
||||||
path_bounding_rect(dst, minX, minY, width, height);
|
|
||||||
path_destroy(dst);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void vegaDrawPath(VGPath path, VGbitfield paintModes)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *p = handle_to_path(path);
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(paintModes & (VG_STROKE_PATH | VG_FILL_PATH))) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path_is_empty(p))
|
|
||||||
return;
|
|
||||||
path_render(p, paintModes,
|
|
||||||
&ctx->state.vg.path_user_to_surface_matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,209 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "text.h"
|
|
||||||
#include "api.h"
|
|
||||||
#include "handle.h"
|
|
||||||
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
|
|
||||||
#ifdef OPENVG_VERSION_1_1
|
|
||||||
|
|
||||||
VGFont vegaCreateFont(VGint glyphCapacityHint)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (glyphCapacityHint < 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return font_to_handle(font_create(glyphCapacityHint));
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaDestroyFont(VGFont f)
|
|
||||||
{
|
|
||||||
struct vg_font *font = handle_to_font(f);
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (f == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!vg_object_is_valid(f, VG_OBJECT_FONT)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
font_destroy(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaSetGlyphToPath(VGFont font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
VGPath path,
|
|
||||||
VGboolean isHinted,
|
|
||||||
const VGfloat glyphOrigin[2],
|
|
||||||
const VGfloat escapement[2])
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct path *pathObj;
|
|
||||||
struct vg_font *f;
|
|
||||||
|
|
||||||
if (font == VG_INVALID_HANDLE ||
|
|
||||||
!vg_context_is_object_valid(ctx, VG_OBJECT_FONT, font)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!glyphOrigin || !escapement ||
|
|
||||||
!is_aligned(glyphOrigin) || !is_aligned(escapement)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (path != VG_INVALID_HANDLE &&
|
|
||||||
!vg_context_is_object_valid(ctx, VG_OBJECT_PATH, path)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pathObj = handle_to_path(path);
|
|
||||||
f = handle_to_font(font);
|
|
||||||
|
|
||||||
font_set_glyph_to_path(f, glyphIndex, pathObj,
|
|
||||||
isHinted, glyphOrigin, escapement);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaSetGlyphToImage(VGFont font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
VGImage image,
|
|
||||||
const VGfloat glyphOrigin[2],
|
|
||||||
const VGfloat escapement[2])
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *img_obj;
|
|
||||||
struct vg_font *f;
|
|
||||||
|
|
||||||
if (font == VG_INVALID_HANDLE ||
|
|
||||||
!vg_context_is_object_valid(ctx, VG_OBJECT_FONT, font)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!glyphOrigin || !escapement ||
|
|
||||||
!is_aligned(glyphOrigin) || !is_aligned(escapement)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (image != VG_INVALID_HANDLE &&
|
|
||||||
!vg_context_is_object_valid(ctx, VG_OBJECT_IMAGE, image)) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
img_obj = handle_to_image(image);
|
|
||||||
f = handle_to_font(font);
|
|
||||||
|
|
||||||
font_set_glyph_to_image(f, glyphIndex, img_obj, glyphOrigin, escapement);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaClearGlyph(VGFont font,
|
|
||||||
VGuint glyphIndex)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_font *f;
|
|
||||||
|
|
||||||
if (font == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
f = handle_to_font(font);
|
|
||||||
|
|
||||||
font_clear_glyph(f, glyphIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaDrawGlyph(VGFont font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
VGbitfield paintModes,
|
|
||||||
VGboolean allowAutoHinting)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_font *f;
|
|
||||||
|
|
||||||
if (font == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (paintModes & (~(VG_STROKE_PATH|VG_FILL_PATH))) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
f = handle_to_font(font);
|
|
||||||
|
|
||||||
font_draw_glyph(f, glyphIndex, paintModes, allowAutoHinting);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaDrawGlyphs(VGFont font,
|
|
||||||
VGint glyphCount,
|
|
||||||
const VGuint *glyphIndices,
|
|
||||||
const VGfloat *adjustments_x,
|
|
||||||
const VGfloat *adjustments_y,
|
|
||||||
VGbitfield paintModes,
|
|
||||||
VGboolean allowAutoHinting)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_font *f;
|
|
||||||
|
|
||||||
if (font == VG_INVALID_HANDLE) {
|
|
||||||
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (glyphCount <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!glyphIndices || !is_aligned(glyphIndices)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((adjustments_x && !is_aligned(adjustments_x)) ||
|
|
||||||
(adjustments_y && !is_aligned(adjustments_y))) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (paintModes & (~(VG_STROKE_PATH|VG_FILL_PATH))) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
f = handle_to_font(font);
|
|
||||||
|
|
||||||
font_draw_glyphs(f, glyphCount, glyphIndices,
|
|
||||||
adjustments_x, adjustments_y, paintModes, allowAutoHinting);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* OPENVG_VERSION_1_1 */
|
|
||||||
|
|
@ -1,129 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
|
|
||||||
#include "matrix.h"
|
|
||||||
#include "api.h"
|
|
||||||
|
|
||||||
void vegaLoadIdentity(void)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct matrix *mat = vg_state_matrix(&ctx->state.vg);
|
|
||||||
matrix_load_identity(mat);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaLoadMatrix(const VGfloat * m)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct matrix *mat;
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m || !is_aligned(m)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mat = vg_state_matrix(&ctx->state.vg);
|
|
||||||
matrix_init(mat, m);
|
|
||||||
if (!matrix_is_affine(mat)) {
|
|
||||||
if (ctx->state.vg.matrix_mode != VG_MATRIX_IMAGE_USER_TO_SURFACE) {
|
|
||||||
matrix_make_affine(mat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaGetMatrix(VGfloat * m)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct matrix *mat;
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m || !is_aligned(m)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mat = vg_state_matrix(&ctx->state.vg);
|
|
||||||
memcpy(m, mat->m, sizeof(VGfloat)*9);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaMultMatrix(const VGfloat * m)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct matrix *dst, src;
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m || !is_aligned(m)) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
matrix_init(&src, m);
|
|
||||||
dst = vg_state_matrix(&ctx->state.vg);
|
|
||||||
if (!matrix_is_affine(&src)) {
|
|
||||||
if (ctx->state.vg.matrix_mode != VG_MATRIX_IMAGE_USER_TO_SURFACE) {
|
|
||||||
matrix_make_affine(&src);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
matrix_mult(dst, &src);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaTranslate(VGfloat tx, VGfloat ty)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct matrix *dst = vg_state_matrix(&ctx->state.vg);
|
|
||||||
matrix_translate(dst, tx, ty);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaScale(VGfloat sx, VGfloat sy)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct matrix *dst = vg_state_matrix(&ctx->state.vg);
|
|
||||||
matrix_scale(dst, sx, sy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaShear(VGfloat shx, VGfloat shy)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct matrix *dst = vg_state_matrix(&ctx->state.vg);
|
|
||||||
matrix_shear(dst, shx, shy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vegaRotate(VGfloat angle)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct matrix *dst = vg_state_matrix(&ctx->state.vg);
|
|
||||||
matrix_rotate(dst, angle);
|
|
||||||
}
|
|
||||||
|
|
@ -1,709 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "arc.h"
|
|
||||||
|
|
||||||
#include "matrix.h"
|
|
||||||
#include "bezier.h"
|
|
||||||
#include "polygon.h"
|
|
||||||
#include "stroker.h"
|
|
||||||
#include "path.h"
|
|
||||||
|
|
||||||
#include "util/u_debug.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
|
|
||||||
#ifndef M_PI
|
|
||||||
#define M_PI 3.14159265358979323846
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DEBUG_ARCS 0
|
|
||||||
|
|
||||||
static const VGfloat two_pi = M_PI * 2;
|
|
||||||
|
|
||||||
|
|
||||||
static const double coeffs3Low[2][4][4] = {
|
|
||||||
{
|
|
||||||
{ 3.85268, -21.229, -0.330434, 0.0127842 },
|
|
||||||
{ -1.61486, 0.706564, 0.225945, 0.263682 },
|
|
||||||
{ -0.910164, 0.388383, 0.00551445, 0.00671814 },
|
|
||||||
{ -0.630184, 0.192402, 0.0098871, 0.0102527 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ -0.162211, 9.94329, 0.13723, 0.0124084 },
|
|
||||||
{ -0.253135, 0.00187735, 0.0230286, 0.01264 },
|
|
||||||
{ -0.0695069, -0.0437594, 0.0120636, 0.0163087 },
|
|
||||||
{ -0.0328856, -0.00926032, -0.00173573, 0.00527385 }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* coefficients for error estimation
|
|
||||||
while using cubic Bézier curves for approximation
|
|
||||||
1/4 <= b/a <= 1 */
|
|
||||||
static const double coeffs3High[2][4][4] = {
|
|
||||||
{
|
|
||||||
{ 0.0899116, -19.2349, -4.11711, 0.183362 },
|
|
||||||
{ 0.138148, -1.45804, 1.32044, 1.38474 },
|
|
||||||
{ 0.230903, -0.450262, 0.219963, 0.414038 },
|
|
||||||
{ 0.0590565, -0.101062, 0.0430592, 0.0204699 }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ 0.0164649, 9.89394, 0.0919496, 0.00760802 },
|
|
||||||
{ 0.0191603, -0.0322058, 0.0134667, -0.0825018 },
|
|
||||||
{ 0.0156192, -0.017535, 0.00326508, -0.228157 },
|
|
||||||
{ -0.0236752, 0.0405821, -0.0173086, 0.176187 }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* safety factor to convert the "best" error approximation
|
|
||||||
into a "max bound" error */
|
|
||||||
static const double safety3[] = {
|
|
||||||
0.001, 4.98, 0.207, 0.0067
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The code below is from the OpenVG 1.1 Spec
|
|
||||||
* Section 18.4 */
|
|
||||||
|
|
||||||
/* Given: Points (x0, y0) and (x1, y1)
|
|
||||||
* Return: TRUE if a solution exists, FALSE otherwise
|
|
||||||
* Circle centers are written to (cx0, cy0) and (cx1, cy1)
|
|
||||||
*/
|
|
||||||
static VGboolean
|
|
||||||
find_unit_circles(double x0, double y0, double x1, double y1,
|
|
||||||
double *cx0, double *cy0,
|
|
||||||
double *cx1, double *cy1)
|
|
||||||
{
|
|
||||||
/* Compute differences and averages */
|
|
||||||
double dx = x0 - x1;
|
|
||||||
double dy = y0 - y1;
|
|
||||||
double xm = (x0 + x1)/2;
|
|
||||||
double ym = (y0 + y1)/2;
|
|
||||||
double dsq, disc, s, sdx, sdy;
|
|
||||||
|
|
||||||
/* Solve for intersecting unit circles */
|
|
||||||
dsq = dx*dx + dy*dy;
|
|
||||||
if (dsq == 0.0) return VG_FALSE; /* Points are coincident */
|
|
||||||
disc = 1.0/dsq - 1.0/4.0;
|
|
||||||
|
|
||||||
/* the precision we care about here is around float so if we're
|
|
||||||
* around the float defined zero then make it official to avoid
|
|
||||||
* precision problems later on */
|
|
||||||
if (floatIsZero(disc))
|
|
||||||
disc = 0.0;
|
|
||||||
|
|
||||||
if (disc < 0.0) return VG_FALSE; /* Points are too far apart */
|
|
||||||
s = sqrt(disc);
|
|
||||||
sdx = s*dx;
|
|
||||||
sdy = s*dy;
|
|
||||||
*cx0 = xm + sdy;
|
|
||||||
*cy0 = ym - sdx;
|
|
||||||
*cx1 = xm - sdy;
|
|
||||||
*cy1 = ym + sdx;
|
|
||||||
return VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Given: Ellipse parameters rh, rv, rot (in degrees),
|
|
||||||
* endpoints (x0, y0) and (x1, y1)
|
|
||||||
* Return: TRUE if a solution exists, FALSE otherwise
|
|
||||||
* Ellipse centers are written to (cx0, cy0) and (cx1, cy1)
|
|
||||||
*/
|
|
||||||
static VGboolean
|
|
||||||
find_ellipses(double rh, double rv, double rot,
|
|
||||||
double x0, double y0, double x1, double y1,
|
|
||||||
double *cx0, double *cy0, double *cx1, double *cy1)
|
|
||||||
{
|
|
||||||
double COS, SIN, x0p, y0p, x1p, y1p, pcx0, pcy0, pcx1, pcy1;
|
|
||||||
/* Convert rotation angle from degrees to radians */
|
|
||||||
rot *= M_PI/180.0;
|
|
||||||
/* Pre-compute rotation matrix entries */
|
|
||||||
COS = cos(rot); SIN = sin(rot);
|
|
||||||
/* Transform (x0, y0) and (x1, y1) into unit space */
|
|
||||||
/* using (inverse) rotate, followed by (inverse) scale */
|
|
||||||
x0p = (x0*COS + y0*SIN)/rh;
|
|
||||||
y0p = (-x0*SIN + y0*COS)/rv;
|
|
||||||
x1p = (x1*COS + y1*SIN)/rh;
|
|
||||||
y1p = (-x1*SIN + y1*COS)/rv;
|
|
||||||
if (!find_unit_circles(x0p, y0p, x1p, y1p,
|
|
||||||
&pcx0, &pcy0, &pcx1, &pcy1)) {
|
|
||||||
return VG_FALSE;
|
|
||||||
}
|
|
||||||
/* Transform back to original coordinate space */
|
|
||||||
/* using (forward) scale followed by (forward) rotate */
|
|
||||||
pcx0 *= rh; pcy0 *= rv;
|
|
||||||
pcx1 *= rh; pcy1 *= rv;
|
|
||||||
*cx0 = pcx0*COS - pcy0*SIN;
|
|
||||||
*cy0 = pcx0*SIN + pcy0*COS;
|
|
||||||
*cx1 = pcx1*COS - pcy1*SIN;
|
|
||||||
*cy1 = pcx1*SIN + pcy1*COS;
|
|
||||||
return VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGboolean
|
|
||||||
try_to_fix_radii(struct arc *arc)
|
|
||||||
{
|
|
||||||
double COS, SIN, rot, x0p, y0p, x1p, y1p;
|
|
||||||
double dx, dy, dsq, scale;
|
|
||||||
|
|
||||||
/* Convert rotation angle from degrees to radians */
|
|
||||||
rot = DEGREES_TO_RADIANS(arc->theta);
|
|
||||||
|
|
||||||
/* Pre-compute rotation matrix entries */
|
|
||||||
COS = cos(rot); SIN = sin(rot);
|
|
||||||
|
|
||||||
/* Transform (x0, y0) and (x1, y1) into unit space */
|
|
||||||
/* using (inverse) rotate, followed by (inverse) scale */
|
|
||||||
x0p = (arc->x1*COS + arc->y1*SIN)/arc->a;
|
|
||||||
y0p = (-arc->x1*SIN + arc->y1*COS)/arc->b;
|
|
||||||
x1p = (arc->x2*COS + arc->y2*SIN)/arc->a;
|
|
||||||
y1p = (-arc->x2*SIN + arc->y2*COS)/arc->b;
|
|
||||||
/* Compute differences and averages */
|
|
||||||
dx = x0p - x1p;
|
|
||||||
dy = y0p - y1p;
|
|
||||||
|
|
||||||
dsq = dx*dx + dy*dy;
|
|
||||||
#if 0
|
|
||||||
if (dsq <= 0.001) {
|
|
||||||
debug_printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaaaa\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
scale = 1/(2/sqrt(dsq));
|
|
||||||
arc->a *= scale;
|
|
||||||
arc->b *= scale;
|
|
||||||
return VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE double vector_normalize(double *v)
|
|
||||||
{
|
|
||||||
double sq = v[0] * v[0] + v[1] * v[1];
|
|
||||||
return sqrt(sq);
|
|
||||||
}
|
|
||||||
static INLINE double vector_orientation(double *v)
|
|
||||||
{
|
|
||||||
double norm = vector_normalize(v);
|
|
||||||
double cosa = v[0] / norm;
|
|
||||||
double sina = v[1] / norm;
|
|
||||||
return (sina>=0 ? acos(cosa) : 2*M_PI - acos(cosa));
|
|
||||||
}
|
|
||||||
static INLINE double vector_dot(double *v0,
|
|
||||||
double *v1)
|
|
||||||
{
|
|
||||||
return v0[0] * v1[0] + v0[1] * v1[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE double vector_angles(double *v0,
|
|
||||||
double *v1)
|
|
||||||
{
|
|
||||||
double dot = vector_dot(v0, v1);
|
|
||||||
double norm0 = vector_normalize(v0);
|
|
||||||
double norm1 = vector_normalize(v1);
|
|
||||||
|
|
||||||
return acos(dot / (norm0 * norm1));
|
|
||||||
}
|
|
||||||
|
|
||||||
static VGboolean find_angles(struct arc *arc)
|
|
||||||
{
|
|
||||||
double vec0[2], vec1[2];
|
|
||||||
double lambda1, lambda2;
|
|
||||||
double angle;
|
|
||||||
struct matrix matrix;
|
|
||||||
|
|
||||||
if (floatIsZero(arc->a) || floatIsZero(arc->b)) {
|
|
||||||
return VG_FALSE;
|
|
||||||
}
|
|
||||||
/* map the points to an identity circle */
|
|
||||||
matrix_load_identity(&matrix);
|
|
||||||
matrix_scale(&matrix, 1.f, arc->a/arc->b);
|
|
||||||
matrix_rotate(&matrix, -arc->theta);
|
|
||||||
matrix_map_point(&matrix,
|
|
||||||
arc->x1, arc->y1,
|
|
||||||
&arc->x1, &arc->y1);
|
|
||||||
matrix_map_point(&matrix,
|
|
||||||
arc->x2, arc->y2,
|
|
||||||
&arc->x2, &arc->y2);
|
|
||||||
matrix_map_point(&matrix,
|
|
||||||
arc->cx, arc->cy,
|
|
||||||
&arc->cx, &arc->cy);
|
|
||||||
|
|
||||||
#if DEBUG_ARCS
|
|
||||||
debug_printf("Matrix 3 [%f, %f, %f| %f, %f, %f| %f, %f, %f]\n",
|
|
||||||
matrix.m[0], matrix.m[1], matrix.m[2],
|
|
||||||
matrix.m[3], matrix.m[4], matrix.m[5],
|
|
||||||
matrix.m[6], matrix.m[7], matrix.m[8]);
|
|
||||||
debug_printf("Endpoints [%f, %f], [%f, %f]\n",
|
|
||||||
arc->x1, arc->y1, arc->x2, arc->y2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vec0[0] = arc->x1 - arc->cx;
|
|
||||||
vec0[1] = arc->y1 - arc->cy;
|
|
||||||
vec1[0] = arc->x2 - arc->cx;
|
|
||||||
vec1[1] = arc->y2 - arc->cy;
|
|
||||||
|
|
||||||
#if DEBUG_ARCS
|
|
||||||
debug_printf("Vec is [%f, %f], [%f, %f], [%f, %f]\n",
|
|
||||||
vec0[0], vec0[1], vec1[0], vec1[1], arc->cx, arc->cy);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lambda1 = vector_orientation(vec0);
|
|
||||||
|
|
||||||
if (isnan(lambda1))
|
|
||||||
lambda1 = 0.f;
|
|
||||||
|
|
||||||
if (arc->type == VG_SCWARC_TO ||
|
|
||||||
arc->type == VG_SCCWARC_TO)
|
|
||||||
angle = vector_angles(vec0, vec1);
|
|
||||||
else if (arc->type == VG_LCWARC_TO ||
|
|
||||||
arc->type == VG_LCCWARC_TO) {
|
|
||||||
angle = 2*M_PI - vector_angles(vec0, vec1);
|
|
||||||
} else
|
|
||||||
abort();
|
|
||||||
|
|
||||||
if (isnan(angle))
|
|
||||||
angle = M_PI;
|
|
||||||
|
|
||||||
|
|
||||||
if (arc->type == VG_SCWARC_TO ||
|
|
||||||
arc->type == VG_LCWARC_TO)
|
|
||||||
lambda2 = lambda1 - angle;
|
|
||||||
else
|
|
||||||
lambda2 = lambda1 + angle;
|
|
||||||
|
|
||||||
#if DEBUG_ARCS
|
|
||||||
debug_printf("Angle is %f and (%f, %f)\n", angle, lambda1, lambda2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
arc->eta1 = atan2(sin(lambda1) / arc->b,
|
|
||||||
cos(lambda1) / arc->a);
|
|
||||||
arc->eta2 = atan2(sin(lambda2) / arc->b,
|
|
||||||
cos(lambda2) / arc->a);
|
|
||||||
|
|
||||||
/* make sure we have eta1 <= eta2 <= eta1 + 2 PI */
|
|
||||||
arc->eta2 -= two_pi * floor((arc->eta2 - arc->eta1) / two_pi);
|
|
||||||
|
|
||||||
/* the preceding correction fails if we have exactly et2 - eta1 = 2 PI
|
|
||||||
it reduces the interval to zero length */
|
|
||||||
if ((lambda2 - lambda1 > M_PI) && (arc->eta2 - arc->eta1 < M_PI)) {
|
|
||||||
arc->eta2 += 2 * M_PI;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
arc->eta1 = lambda1;
|
|
||||||
arc->eta2 = lambda2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG_ARCS
|
|
||||||
static void check_endpoints(struct arc *arc)
|
|
||||||
{
|
|
||||||
double x1, y1, x2, y2;
|
|
||||||
|
|
||||||
double a_cos_eta1 = arc->a * cos(arc->eta1);
|
|
||||||
double b_sin_eta1 = arc->b * sin(arc->eta1);
|
|
||||||
x1 = arc->cx + a_cos_eta1 * arc->cos_theta -
|
|
||||||
b_sin_eta1 * arc->sin_theta;
|
|
||||||
y1 = arc->cy + a_cos_eta1 * arc->sin_theta +
|
|
||||||
b_sin_eta1 * arc->cos_theta;
|
|
||||||
|
|
||||||
double a_cos_eta2 = arc->a * cos(arc->eta2);
|
|
||||||
double b_sin_eta2 = arc->b * sin(arc->eta2);
|
|
||||||
x2 = arc->cx + a_cos_eta2 * arc->cos_theta -
|
|
||||||
b_sin_eta2 * arc->sin_theta;
|
|
||||||
y2 = arc->cy + a_cos_eta2 * arc->sin_theta +
|
|
||||||
b_sin_eta2 * arc->cos_theta;
|
|
||||||
|
|
||||||
debug_printf("Computed (%f, %f), (%f, %f)\n",
|
|
||||||
x1, y1, x2, y2);
|
|
||||||
debug_printf("Real (%f, %f), (%f, %f)\n",
|
|
||||||
arc->x1, arc->y1,
|
|
||||||
arc->x2, arc->y2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void arc_init(struct arc *arc,
|
|
||||||
VGPathSegment type,
|
|
||||||
VGfloat x1, VGfloat y1,
|
|
||||||
VGfloat x2, VGfloat y2,
|
|
||||||
VGfloat rh, VGfloat rv,
|
|
||||||
VGfloat rot)
|
|
||||||
{
|
|
||||||
assert(type == VG_SCCWARC_TO ||
|
|
||||||
type == VG_SCWARC_TO ||
|
|
||||||
type == VG_LCCWARC_TO ||
|
|
||||||
type == VG_LCWARC_TO);
|
|
||||||
arc->type = type;
|
|
||||||
arc->x1 = x1;
|
|
||||||
arc->y1 = y1;
|
|
||||||
arc->x2 = x2;
|
|
||||||
arc->y2 = y2;
|
|
||||||
arc->a = rh;
|
|
||||||
arc->b = rv;
|
|
||||||
arc->theta = rot;
|
|
||||||
arc->cos_theta = cos(arc->theta);
|
|
||||||
arc->sin_theta = sin(arc->theta);
|
|
||||||
{
|
|
||||||
double cx0, cy0, cx1, cy1;
|
|
||||||
double cx, cy;
|
|
||||||
arc->is_valid = find_ellipses(rh, rv, rot, x1, y1, x2, y2,
|
|
||||||
&cx0, &cy0, &cx1, &cy1);
|
|
||||||
|
|
||||||
if (!arc->is_valid && try_to_fix_radii(arc)) {
|
|
||||||
rh = arc->a;
|
|
||||||
rv = arc->b;
|
|
||||||
arc->is_valid =
|
|
||||||
find_ellipses(rh, rv, rot, x1, y1, x2, y2,
|
|
||||||
&cx0, &cy0, &cx1, &cy1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == VG_SCWARC_TO ||
|
|
||||||
type == VG_LCCWARC_TO) {
|
|
||||||
cx = cx1;
|
|
||||||
cy = cy1;
|
|
||||||
} else {
|
|
||||||
cx = cx0;
|
|
||||||
cy = cy0;
|
|
||||||
}
|
|
||||||
#if DEBUG_ARCS
|
|
||||||
debug_printf("Centers are : (%f, %f) , (%f, %f). Real (%f, %f)\n",
|
|
||||||
cx0, cy0, cx1, cy1, cx, cy);
|
|
||||||
#endif
|
|
||||||
arc->cx = cx;
|
|
||||||
arc->cy = cy;
|
|
||||||
if (arc->is_valid) {
|
|
||||||
arc->is_valid = find_angles(arc);
|
|
||||||
#if DEBUG_ARCS
|
|
||||||
check_endpoints(arc);
|
|
||||||
#endif
|
|
||||||
/* remap a few points. find_angles requires
|
|
||||||
* rot in angles, the rest of the code
|
|
||||||
* will need them in radians. and find_angles
|
|
||||||
* modifies the center to match an identity
|
|
||||||
* circle so lets reset it */
|
|
||||||
arc->theta = DEGREES_TO_RADIANS(rot);
|
|
||||||
arc->cos_theta = cos(arc->theta);
|
|
||||||
arc->sin_theta = sin(arc->theta);
|
|
||||||
arc->cx = cx;
|
|
||||||
arc->cy = cy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE double rational_function(double x, const double *c)
|
|
||||||
{
|
|
||||||
return (x * (x * c[0] + c[1]) + c[2]) / (x + c[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double estimate_error(struct arc *arc,
|
|
||||||
double etaA, double etaB)
|
|
||||||
{
|
|
||||||
double eta = 0.5 * (etaA + etaB);
|
|
||||||
|
|
||||||
double x = arc->b / arc->a;
|
|
||||||
double dEta = etaB - etaA;
|
|
||||||
double cos2 = cos(2 * eta);
|
|
||||||
double cos4 = cos(4 * eta);
|
|
||||||
double cos6 = cos(6 * eta);
|
|
||||||
double c0, c1;
|
|
||||||
|
|
||||||
/* select the right coeficients set according to degree and b/a */
|
|
||||||
const double (*coeffs)[4][4];
|
|
||||||
const double *safety;
|
|
||||||
coeffs = (x < 0.25) ? coeffs3Low : coeffs3High;
|
|
||||||
safety = safety3;
|
|
||||||
|
|
||||||
c0 = rational_function(x, coeffs[0][0])
|
|
||||||
+ cos2 * rational_function(x, coeffs[0][1])
|
|
||||||
+ cos4 * rational_function(x, coeffs[0][2])
|
|
||||||
+ cos6 * rational_function(x, coeffs[0][3]);
|
|
||||||
|
|
||||||
c1 = rational_function(x, coeffs[1][0])
|
|
||||||
+ cos2 * rational_function(x, coeffs[1][1])
|
|
||||||
+ cos4 * rational_function(x, coeffs[1][2])
|
|
||||||
+ cos6 * rational_function(x, coeffs[1][3]);
|
|
||||||
|
|
||||||
return rational_function(x, safety) * arc->a * exp(c0 + c1 * dEta);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct arc_cb {
|
|
||||||
void (*move)(struct arc_cb *cb, VGfloat x, VGfloat y);
|
|
||||||
void (*point)(struct arc_cb *cb, VGfloat x, VGfloat y);
|
|
||||||
void (*bezier)(struct arc_cb *cb, struct bezier *bezier);
|
|
||||||
|
|
||||||
void *user_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void cb_null_move(struct arc_cb *cb, VGfloat x, VGfloat y)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void polygon_point(struct arc_cb *cb, VGfloat x, VGfloat y)
|
|
||||||
{
|
|
||||||
struct polygon *poly = (struct polygon*)cb->user_data;
|
|
||||||
polygon_vertex_append(poly, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void polygon_bezier(struct arc_cb *cb, struct bezier *bezier)
|
|
||||||
{
|
|
||||||
struct polygon *poly = (struct polygon*)cb->user_data;
|
|
||||||
bezier_add_to_polygon(bezier, poly);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stroke_point(struct arc_cb *cb, VGfloat x, VGfloat y)
|
|
||||||
{
|
|
||||||
struct stroker *stroker = (struct stroker*)cb->user_data;
|
|
||||||
stroker_line_to(stroker, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stroke_curve(struct arc_cb *cb, struct bezier *bezier)
|
|
||||||
{
|
|
||||||
struct stroker *stroker = (struct stroker*)cb->user_data;
|
|
||||||
stroker_curve_to(stroker,
|
|
||||||
bezier->x2, bezier->y2,
|
|
||||||
bezier->x3, bezier->y3,
|
|
||||||
bezier->x4, bezier->y4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stroke_emit_point(struct arc_cb *cb, VGfloat x, VGfloat y)
|
|
||||||
{
|
|
||||||
struct stroker *stroker = (struct stroker*)cb->user_data;
|
|
||||||
stroker_emit_line_to(stroker, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stroke_emit_curve(struct arc_cb *cb, struct bezier *bezier)
|
|
||||||
{
|
|
||||||
struct stroker *stroker = (struct stroker*)cb->user_data;
|
|
||||||
stroker_emit_curve_to(stroker,
|
|
||||||
bezier->x2, bezier->y2,
|
|
||||||
bezier->x3, bezier->y3,
|
|
||||||
bezier->x4, bezier->y4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void arc_path_move(struct arc_cb *cb, VGfloat x, VGfloat y)
|
|
||||||
{
|
|
||||||
struct path *path = (struct path*)cb->user_data;
|
|
||||||
path_move_to(path, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void arc_path_point(struct arc_cb *cb, VGfloat x, VGfloat y)
|
|
||||||
{
|
|
||||||
struct path *path = (struct path*)cb->user_data;
|
|
||||||
path_line_to(path, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void arc_path_bezier(struct arc_cb *cb, struct bezier *bezier)
|
|
||||||
{
|
|
||||||
struct path *path = (struct path*)cb->user_data;
|
|
||||||
path_cubic_to(path,
|
|
||||||
bezier->x2, bezier->y2,
|
|
||||||
bezier->x3, bezier->y3,
|
|
||||||
bezier->x4, bezier->y4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE int num_beziers_needed(struct arc *arc)
|
|
||||||
{
|
|
||||||
double threshold = 0.05;
|
|
||||||
VGboolean found = VG_FALSE;
|
|
||||||
int n = 1;
|
|
||||||
double min_eta, max_eta;
|
|
||||||
|
|
||||||
min_eta = MIN2(arc->eta1, arc->eta2);
|
|
||||||
max_eta = MAX2(arc->eta1, arc->eta2);
|
|
||||||
|
|
||||||
while ((! found) && (n < 1024)) {
|
|
||||||
double d_eta = (max_eta - min_eta) / n;
|
|
||||||
if (d_eta <= 0.5 * M_PI) {
|
|
||||||
double eta_b = min_eta;
|
|
||||||
int i;
|
|
||||||
found = VG_TRUE;
|
|
||||||
for (i = 0; found && (i < n); ++i) {
|
|
||||||
double etaA = eta_b;
|
|
||||||
eta_b += d_eta;
|
|
||||||
found = (estimate_error(arc, etaA, eta_b) <= threshold);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n = n << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void arc_to_beziers(struct arc *arc,
|
|
||||||
struct arc_cb cb,
|
|
||||||
struct matrix *matrix)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int n = 1;
|
|
||||||
double d_eta, eta_b, cos_eta_b,
|
|
||||||
sin_eta_b, a_cos_eta_b, b_sin_eta_b, a_sin_eta_b,
|
|
||||||
b_cos_eta_b, x_b, y_b, x_b_dot, y_b_dot, lx, ly;
|
|
||||||
double t, alpha;
|
|
||||||
|
|
||||||
{ /* always move to the start of the arc */
|
|
||||||
VGfloat x = arc->x1;
|
|
||||||
VGfloat y = arc->y1;
|
|
||||||
matrix_map_point(matrix, x, y, &x, &y);
|
|
||||||
cb.move(&cb, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!arc->is_valid) {
|
|
||||||
VGfloat x = arc->x2;
|
|
||||||
VGfloat y = arc->y2;
|
|
||||||
matrix_map_point(matrix, x, y, &x, &y);
|
|
||||||
cb.point(&cb, x, y);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find the number of Bézier curves needed */
|
|
||||||
n = num_beziers_needed(arc);
|
|
||||||
|
|
||||||
d_eta = (arc->eta2 - arc->eta1) / n;
|
|
||||||
eta_b = arc->eta1;
|
|
||||||
|
|
||||||
cos_eta_b = cos(eta_b);
|
|
||||||
sin_eta_b = sin(eta_b);
|
|
||||||
a_cos_eta_b = arc->a * cos_eta_b;
|
|
||||||
b_sin_eta_b = arc->b * sin_eta_b;
|
|
||||||
a_sin_eta_b = arc->a * sin_eta_b;
|
|
||||||
b_cos_eta_b = arc->b * cos_eta_b;
|
|
||||||
x_b = arc->cx + a_cos_eta_b * arc->cos_theta -
|
|
||||||
b_sin_eta_b * arc->sin_theta;
|
|
||||||
y_b = arc->cy + a_cos_eta_b * arc->sin_theta +
|
|
||||||
b_sin_eta_b * arc->cos_theta;
|
|
||||||
x_b_dot = -a_sin_eta_b * arc->cos_theta -
|
|
||||||
b_cos_eta_b * arc->sin_theta;
|
|
||||||
y_b_dot = -a_sin_eta_b * arc->sin_theta +
|
|
||||||
b_cos_eta_b * arc->cos_theta;
|
|
||||||
|
|
||||||
{
|
|
||||||
VGfloat x = x_b, y = y_b;
|
|
||||||
matrix_map_point(matrix, x, y, &x, &y);
|
|
||||||
cb.point(&cb, x, y);
|
|
||||||
}
|
|
||||||
lx = x_b;
|
|
||||||
ly = y_b;
|
|
||||||
|
|
||||||
t = tan(0.5 * d_eta);
|
|
||||||
alpha = sin(d_eta) * (sqrt(4 + 3 * t * t) - 1) / 3;
|
|
||||||
|
|
||||||
for (i = 0; i < n; ++i) {
|
|
||||||
struct bezier bezier;
|
|
||||||
double xA = x_b;
|
|
||||||
double yA = y_b;
|
|
||||||
double xADot = x_b_dot;
|
|
||||||
double yADot = y_b_dot;
|
|
||||||
|
|
||||||
eta_b += d_eta;
|
|
||||||
cos_eta_b = cos(eta_b);
|
|
||||||
sin_eta_b = sin(eta_b);
|
|
||||||
a_cos_eta_b = arc->a * cos_eta_b;
|
|
||||||
b_sin_eta_b = arc->b * sin_eta_b;
|
|
||||||
a_sin_eta_b = arc->a * sin_eta_b;
|
|
||||||
b_cos_eta_b = arc->b * cos_eta_b;
|
|
||||||
x_b = arc->cx + a_cos_eta_b * arc->cos_theta -
|
|
||||||
b_sin_eta_b * arc->sin_theta;
|
|
||||||
y_b = arc->cy + a_cos_eta_b * arc->sin_theta +
|
|
||||||
b_sin_eta_b * arc->cos_theta;
|
|
||||||
x_b_dot = -a_sin_eta_b * arc->cos_theta -
|
|
||||||
b_cos_eta_b * arc->sin_theta;
|
|
||||||
y_b_dot = -a_sin_eta_b * arc->sin_theta +
|
|
||||||
b_cos_eta_b * arc->cos_theta;
|
|
||||||
|
|
||||||
bezier_init(&bezier,
|
|
||||||
lx, ly,
|
|
||||||
(float) (xA + alpha * xADot), (float) (yA + alpha * yADot),
|
|
||||||
(float) (x_b - alpha * x_b_dot), (float) (y_b - alpha * y_b_dot),
|
|
||||||
(float) x_b, (float) y_b);
|
|
||||||
#if 0
|
|
||||||
debug_printf("%d) Bezier (%f, %f), (%f, %f), (%f, %f), (%f, %f)\n",
|
|
||||||
i,
|
|
||||||
bezier.x1, bezier.y1,
|
|
||||||
bezier.x2, bezier.y2,
|
|
||||||
bezier.x3, bezier.y3,
|
|
||||||
bezier.x4, bezier.y4);
|
|
||||||
#endif
|
|
||||||
bezier_transform(&bezier, matrix);
|
|
||||||
cb.bezier(&cb, &bezier);
|
|
||||||
lx = x_b;
|
|
||||||
ly = y_b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void arc_add_to_polygon(struct arc *arc,
|
|
||||||
struct polygon *poly,
|
|
||||||
struct matrix *matrix)
|
|
||||||
{
|
|
||||||
struct arc_cb cb;
|
|
||||||
|
|
||||||
cb.move = cb_null_move;
|
|
||||||
cb.point = polygon_point;
|
|
||||||
cb.bezier = polygon_bezier;
|
|
||||||
cb.user_data = poly;
|
|
||||||
|
|
||||||
arc_to_beziers(arc, cb, matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arc_stroke_cb(struct arc *arc,
|
|
||||||
struct stroker *stroke,
|
|
||||||
struct matrix *matrix)
|
|
||||||
{
|
|
||||||
struct arc_cb cb;
|
|
||||||
|
|
||||||
cb.move = cb_null_move;
|
|
||||||
cb.point = stroke_point;
|
|
||||||
cb.bezier = stroke_curve;
|
|
||||||
cb.user_data = stroke;
|
|
||||||
|
|
||||||
arc_to_beziers(arc, cb, matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arc_stroker_emit(struct arc *arc,
|
|
||||||
struct stroker *stroker,
|
|
||||||
struct matrix *matrix)
|
|
||||||
{
|
|
||||||
struct arc_cb cb;
|
|
||||||
|
|
||||||
cb.move = cb_null_move;
|
|
||||||
cb.point = stroke_emit_point;
|
|
||||||
cb.bezier = stroke_emit_curve;
|
|
||||||
cb.user_data = stroker;
|
|
||||||
|
|
||||||
arc_to_beziers(arc, cb, matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arc_to_path(struct arc *arc,
|
|
||||||
struct path *path,
|
|
||||||
struct matrix *matrix)
|
|
||||||
{
|
|
||||||
struct arc_cb cb;
|
|
||||||
|
|
||||||
cb.move = arc_path_move;
|
|
||||||
cb.point = arc_path_point;
|
|
||||||
cb.bezier = arc_path_bezier;
|
|
||||||
cb.user_data = path;
|
|
||||||
|
|
||||||
arc_to_beziers(arc, cb, matrix);
|
|
||||||
}
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef ARC_H
|
|
||||||
#define ARC_H
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
struct polygon;
|
|
||||||
struct matrix;
|
|
||||||
struct stroker;
|
|
||||||
struct path;
|
|
||||||
|
|
||||||
struct arc {
|
|
||||||
VGPathSegment type;
|
|
||||||
|
|
||||||
VGfloat cx, cy;
|
|
||||||
|
|
||||||
VGfloat a, b;
|
|
||||||
|
|
||||||
VGfloat theta;
|
|
||||||
VGfloat cos_theta, sin_theta;
|
|
||||||
|
|
||||||
VGfloat eta1;
|
|
||||||
VGfloat eta2;
|
|
||||||
|
|
||||||
VGfloat x1, y1, x2, y2;
|
|
||||||
|
|
||||||
VGboolean is_valid;
|
|
||||||
};
|
|
||||||
|
|
||||||
void arc_init(struct arc *arc,
|
|
||||||
VGPathSegment type,
|
|
||||||
VGfloat x1, VGfloat y1,
|
|
||||||
VGfloat x2, VGfloat y2,
|
|
||||||
VGfloat rh, VGfloat rv,
|
|
||||||
VGfloat rot);
|
|
||||||
|
|
||||||
void arc_add_to_polygon(struct arc *arc,
|
|
||||||
struct polygon *poly,
|
|
||||||
struct matrix *matrix);
|
|
||||||
|
|
||||||
|
|
||||||
void arc_to_path(struct arc *arc,
|
|
||||||
struct path *p,
|
|
||||||
struct matrix *matrix);
|
|
||||||
|
|
||||||
void arc_stroke_cb(struct arc *arc,
|
|
||||||
struct stroker *stroke,
|
|
||||||
struct matrix *matrix);
|
|
||||||
|
|
||||||
void arc_stroker_emit(struct arc *arc,
|
|
||||||
struct stroker *stroke,
|
|
||||||
struct matrix *matrix);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,693 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef ASM_FILL_H
|
|
||||||
#define ASM_FILL_H
|
|
||||||
|
|
||||||
#include "tgsi/tgsi_ureg.h"
|
|
||||||
|
|
||||||
typedef void (* ureg_func)( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant);
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
solid_fill( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
ureg_MOV(ureg, *out, constant[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform frag-coord-to-paint-coord transform. The transformation is in
|
|
||||||
* CONST[4..6].
|
|
||||||
*/
|
|
||||||
#define PAINT_TRANSFORM \
|
|
||||||
ureg_MOV(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_XY), in[0]); \
|
|
||||||
ureg_MOV(ureg, \
|
|
||||||
ureg_writemask(temp[0], TGSI_WRITEMASK_Z), \
|
|
||||||
ureg_scalar(constant[3], TGSI_SWIZZLE_Y)); \
|
|
||||||
ureg_DP3(ureg, temp[1], constant[4], ureg_src(temp[0])); \
|
|
||||||
ureg_DP3(ureg, temp[2], constant[5], ureg_src(temp[0])); \
|
|
||||||
ureg_DP3(ureg, temp[3], constant[6], ureg_src(temp[0])); \
|
|
||||||
ureg_RCP(ureg, temp[3], ureg_src(temp[3])); \
|
|
||||||
ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3])); \
|
|
||||||
ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3])); \
|
|
||||||
ureg_MOV(ureg, \
|
|
||||||
ureg_writemask(temp[4], TGSI_WRITEMASK_X), \
|
|
||||||
ureg_src(temp[1])); \
|
|
||||||
ureg_MOV(ureg, \
|
|
||||||
ureg_writemask(temp[4], TGSI_WRITEMASK_Y), \
|
|
||||||
ureg_src(temp[2]));
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
linear_grad( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
PAINT_TRANSFORM
|
|
||||||
|
|
||||||
/* grad = DP2((x, y), CONST[2].xy) * CONST[2].z */
|
|
||||||
ureg_MUL(ureg, temp[0],
|
|
||||||
ureg_scalar(constant[2], TGSI_SWIZZLE_Y),
|
|
||||||
ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_Y));
|
|
||||||
ureg_MAD(ureg, temp[1],
|
|
||||||
ureg_scalar(constant[2], TGSI_SWIZZLE_X),
|
|
||||||
ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_X),
|
|
||||||
ureg_src(temp[0]));
|
|
||||||
ureg_MUL(ureg, temp[2], ureg_src(temp[1]),
|
|
||||||
ureg_scalar(constant[2], TGSI_SWIZZLE_Z));
|
|
||||||
|
|
||||||
ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[2]), sampler[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
radial_grad( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
PAINT_TRANSFORM
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculate (sqrt(B^2 + AC) - B) / A, where
|
|
||||||
*
|
|
||||||
* A is CONST[2].z,
|
|
||||||
* B is DP2((x, y), CONST[2].xy), and
|
|
||||||
* C is DP2((x, y), (x, y)).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* B and C */
|
|
||||||
ureg_DP2(ureg, temp[0], ureg_src(temp[4]), constant[2]);
|
|
||||||
ureg_DP2(ureg, temp[1], ureg_src(temp[4]), ureg_src(temp[4]));
|
|
||||||
|
|
||||||
/* the square root */
|
|
||||||
ureg_MUL(ureg, temp[2], ureg_src(temp[0]), ureg_src(temp[0]));
|
|
||||||
ureg_MAD(ureg, temp[3], ureg_src(temp[1]),
|
|
||||||
ureg_scalar(constant[2], TGSI_SWIZZLE_Z), ureg_src(temp[2]));
|
|
||||||
ureg_RSQ(ureg, temp[3], ureg_src(temp[3]));
|
|
||||||
ureg_RCP(ureg, temp[3], ureg_src(temp[3]));
|
|
||||||
|
|
||||||
ureg_SUB(ureg, temp[3], ureg_src(temp[3]), ureg_src(temp[0]));
|
|
||||||
ureg_RCP(ureg, temp[0], ureg_scalar(constant[2], TGSI_SWIZZLE_Z));
|
|
||||||
ureg_MUL(ureg, temp[0], ureg_src(temp[0]), ureg_src(temp[3]));
|
|
||||||
|
|
||||||
ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[0]), sampler[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
pattern( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
PAINT_TRANSFORM
|
|
||||||
|
|
||||||
/* (s, t) = (x / tex_width, y / tex_height) */
|
|
||||||
ureg_RCP(ureg, temp[0],
|
|
||||||
ureg_swizzle(constant[3],
|
|
||||||
TGSI_SWIZZLE_Z,
|
|
||||||
TGSI_SWIZZLE_W,
|
|
||||||
TGSI_SWIZZLE_Z,
|
|
||||||
TGSI_SWIZZLE_W));
|
|
||||||
ureg_MOV(ureg, temp[1], ureg_src(temp[4]));
|
|
||||||
ureg_MUL(ureg,
|
|
||||||
ureg_writemask(temp[1], TGSI_WRITEMASK_X),
|
|
||||||
ureg_src(temp[1]),
|
|
||||||
ureg_src(temp[0]));
|
|
||||||
ureg_MUL(ureg,
|
|
||||||
ureg_writemask(temp[1], TGSI_WRITEMASK_Y),
|
|
||||||
ureg_src(temp[1]),
|
|
||||||
ureg_src(temp[0]));
|
|
||||||
|
|
||||||
ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, ureg_src(temp[1]), sampler[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
paint_degenerate( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
/* CONST[3].y is 1.0f */
|
|
||||||
ureg_MOV(ureg, temp[1], ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
|
|
||||||
ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[1]), sampler[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
image_normal( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
/* store and pass image color in TEMP[1] */
|
|
||||||
ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
|
|
||||||
ureg_MOV(ureg, *out, ureg_src(temp[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
image_multiply( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
/* store and pass image color in TEMP[1] */
|
|
||||||
ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
|
|
||||||
ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
image_stencil( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
/* store and pass image color in TEMP[1] */
|
|
||||||
ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
|
|
||||||
ureg_MOV(ureg, *out, ureg_src(temp[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
color_transform( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
/* note that TEMP[1] may already be used for image color */
|
|
||||||
|
|
||||||
ureg_MAD(ureg, temp[2], ureg_src(temp[0]), constant[0], constant[1]);
|
|
||||||
/* clamp to [0.0f, 1.0f] */
|
|
||||||
ureg_CLAMP(ureg, temp[2],
|
|
||||||
ureg_src(temp[2]),
|
|
||||||
ureg_scalar(constant[3], TGSI_SWIZZLE_X),
|
|
||||||
ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
|
|
||||||
ureg_MOV(ureg, *out, ureg_src(temp[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
alpha_normal( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
/* save per-channel alpha in TEMP[1] */
|
|
||||||
ureg_MOV(ureg, temp[1], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
|
|
||||||
|
|
||||||
ureg_MOV(ureg, *out, ureg_src(temp[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
alpha_per_channel( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
/* save per-channel alpha in TEMP[1] */
|
|
||||||
ureg_MUL(ureg,
|
|
||||||
ureg_writemask(temp[1], TGSI_WRITEMASK_W),
|
|
||||||
ureg_src(temp[0]),
|
|
||||||
ureg_src(temp[1]));
|
|
||||||
ureg_MUL(ureg,
|
|
||||||
ureg_writemask(temp[1], TGSI_WRITEMASK_XYZ),
|
|
||||||
ureg_src(temp[1]),
|
|
||||||
ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
|
|
||||||
|
|
||||||
/* update alpha */
|
|
||||||
ureg_MOV(ureg,
|
|
||||||
ureg_writemask(temp[0], TGSI_WRITEMASK_W),
|
|
||||||
ureg_src(temp[1]));
|
|
||||||
ureg_MOV(ureg, *out, ureg_src(temp[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Premultiply src and dst.
|
|
||||||
*/
|
|
||||||
static INLINE void
|
|
||||||
blend_premultiply( struct ureg_program *ureg,
|
|
||||||
struct ureg_src src,
|
|
||||||
struct ureg_src src_channel_alpha,
|
|
||||||
struct ureg_src dst)
|
|
||||||
{
|
|
||||||
/* premultiply src */
|
|
||||||
ureg_MUL(ureg,
|
|
||||||
ureg_writemask(ureg_dst(src), TGSI_WRITEMASK_XYZ),
|
|
||||||
src,
|
|
||||||
src_channel_alpha);
|
|
||||||
/* premultiply dst */
|
|
||||||
ureg_MUL(ureg,
|
|
||||||
ureg_writemask(ureg_dst(dst), TGSI_WRITEMASK_XYZ),
|
|
||||||
dst,
|
|
||||||
ureg_scalar(dst, TGSI_SWIZZLE_W));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unpremultiply src.
|
|
||||||
*/
|
|
||||||
static INLINE void
|
|
||||||
blend_unpremultiply( struct ureg_program *ureg,
|
|
||||||
struct ureg_src src,
|
|
||||||
struct ureg_src one,
|
|
||||||
struct ureg_dst temp[1])
|
|
||||||
{
|
|
||||||
/* replace 0.0f by 1.0f before calculating reciprocal */
|
|
||||||
ureg_CMP(ureg,
|
|
||||||
temp[0],
|
|
||||||
ureg_negate(ureg_scalar(src, TGSI_SWIZZLE_W)),
|
|
||||||
ureg_scalar(src, TGSI_SWIZZLE_W),
|
|
||||||
one);
|
|
||||||
ureg_RCP(ureg, temp[0], ureg_src(temp[0]));
|
|
||||||
|
|
||||||
ureg_MUL(ureg,
|
|
||||||
ureg_writemask(ureg_dst(src), TGSI_WRITEMASK_XYZ),
|
|
||||||
src,
|
|
||||||
ureg_src(temp[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emit instructions for the specified blend mode. Colors will be
|
|
||||||
* unpremultiplied. Two temporary registers are required.
|
|
||||||
*
|
|
||||||
* The output is written back to src.
|
|
||||||
*/
|
|
||||||
static INLINE void
|
|
||||||
blend_generic(struct ureg_program *ureg,
|
|
||||||
VGBlendMode mode,
|
|
||||||
struct ureg_src src,
|
|
||||||
struct ureg_src src_channel_alpha,
|
|
||||||
struct ureg_src dst,
|
|
||||||
struct ureg_src one,
|
|
||||||
struct ureg_dst temp[2])
|
|
||||||
{
|
|
||||||
struct ureg_dst out;
|
|
||||||
|
|
||||||
blend_premultiply(ureg, src, src_channel_alpha, dst);
|
|
||||||
|
|
||||||
/* blend in-place */
|
|
||||||
out = ureg_dst(src);
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case VG_BLEND_SRC:
|
|
||||||
ureg_MOV(ureg, out, src);
|
|
||||||
break;
|
|
||||||
case VG_BLEND_SRC_OVER:
|
|
||||||
/* RGBA_out = RGBA_src + (1 - A_src) * RGBA_dst */
|
|
||||||
ureg_SUB(ureg, temp[0], one, src_channel_alpha);
|
|
||||||
ureg_MAD(ureg, out, ureg_src(temp[0]), dst, src);
|
|
||||||
break;
|
|
||||||
case VG_BLEND_DST_OVER:
|
|
||||||
/* RGBA_out = RGBA_dst + (1 - A_dst) * RGBA_src */
|
|
||||||
ureg_SUB(ureg, temp[0], one, ureg_scalar(dst, TGSI_SWIZZLE_W));
|
|
||||||
ureg_MAD(ureg, out, ureg_src(temp[0]), src, dst);
|
|
||||||
break;
|
|
||||||
case VG_BLEND_SRC_IN:
|
|
||||||
ureg_MUL(ureg, out, src, ureg_scalar(dst, TGSI_SWIZZLE_W));
|
|
||||||
break;
|
|
||||||
case VG_BLEND_DST_IN:
|
|
||||||
ureg_MUL(ureg, out, dst, src_channel_alpha);
|
|
||||||
break;
|
|
||||||
case VG_BLEND_MULTIPLY:
|
|
||||||
/*
|
|
||||||
* RGB_out = (1 - A_dst) * RGB_src + (1 - A_src) * RGB_dst +
|
|
||||||
* RGB_src * RGB_dst
|
|
||||||
*/
|
|
||||||
ureg_MAD(ureg, temp[0],
|
|
||||||
ureg_scalar(dst, TGSI_SWIZZLE_W), ureg_negate(src), src);
|
|
||||||
ureg_MAD(ureg, temp[1],
|
|
||||||
src_channel_alpha, ureg_negate(dst), dst);
|
|
||||||
ureg_MAD(ureg, temp[0], src, dst, ureg_src(temp[0]));
|
|
||||||
ureg_ADD(ureg, out, ureg_src(temp[0]), ureg_src(temp[1]));
|
|
||||||
/* alpha is src over */
|
|
||||||
ureg_ADD(ureg, ureg_writemask(out, TGSI_WRITEMASK_W),
|
|
||||||
src, ureg_src(temp[1]));
|
|
||||||
break;
|
|
||||||
case VG_BLEND_SCREEN:
|
|
||||||
/* RGBA_out = RGBA_src + (1 - RGBA_src) * RGBA_dst */
|
|
||||||
ureg_SUB(ureg, temp[0], one, src);
|
|
||||||
ureg_MAD(ureg, out, ureg_src(temp[0]), dst, src);
|
|
||||||
break;
|
|
||||||
case VG_BLEND_DARKEN:
|
|
||||||
case VG_BLEND_LIGHTEN:
|
|
||||||
/* src over */
|
|
||||||
ureg_SUB(ureg, temp[0], one, src_channel_alpha);
|
|
||||||
ureg_MAD(ureg, temp[0], ureg_src(temp[0]), dst, src);
|
|
||||||
/* dst over */
|
|
||||||
ureg_SUB(ureg, temp[1], one, ureg_scalar(dst, TGSI_SWIZZLE_W));
|
|
||||||
ureg_MAD(ureg, temp[1], ureg_src(temp[1]), src, dst);
|
|
||||||
/* take min/max for colors */
|
|
||||||
if (mode == VG_BLEND_DARKEN) {
|
|
||||||
ureg_MIN(ureg, ureg_writemask(out, TGSI_WRITEMASK_XYZ),
|
|
||||||
ureg_src(temp[0]), ureg_src(temp[1]));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ureg_MAX(ureg, ureg_writemask(out, TGSI_WRITEMASK_XYZ),
|
|
||||||
ureg_src(temp[0]), ureg_src(temp[1]));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VG_BLEND_ADDITIVE:
|
|
||||||
/* RGBA_out = RGBA_src + RGBA_dst */
|
|
||||||
ureg_ADD(ureg, temp[0], src, dst);
|
|
||||||
ureg_MIN(ureg, out, ureg_src(temp[0]), one);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
blend_unpremultiply(ureg, src, one, temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BLEND_GENERIC(mode) \
|
|
||||||
do { \
|
|
||||||
ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]); \
|
|
||||||
blend_generic(ureg, (mode), ureg_src(temp[0]), ureg_src(temp[1]), \
|
|
||||||
ureg_src(temp[2]), \
|
|
||||||
ureg_scalar(constant[3], TGSI_SWIZZLE_Y), temp + 3); \
|
|
||||||
ureg_MOV(ureg, *out, ureg_src(temp[0])); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
blend_src( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
BLEND_GENERIC(VG_BLEND_SRC);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
blend_src_over( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
BLEND_GENERIC(VG_BLEND_SRC_OVER);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
blend_dst_over( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
BLEND_GENERIC(VG_BLEND_DST_OVER);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
blend_src_in( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
BLEND_GENERIC(VG_BLEND_SRC_IN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
blend_dst_in( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
BLEND_GENERIC(VG_BLEND_DST_IN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
blend_multiply( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
BLEND_GENERIC(VG_BLEND_MULTIPLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
blend_screen( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
BLEND_GENERIC(VG_BLEND_SCREEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
blend_darken( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
BLEND_GENERIC(VG_BLEND_DARKEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
blend_lighten( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
BLEND_GENERIC(VG_BLEND_LIGHTEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
blend_additive( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
BLEND_GENERIC(VG_BLEND_ADDITIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
mask( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[1]);
|
|
||||||
ureg_MUL(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_W),
|
|
||||||
ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
|
|
||||||
ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
|
|
||||||
ureg_MOV(ureg, *out, ureg_src(temp[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
premultiply( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
ureg_MUL(ureg,
|
|
||||||
ureg_writemask(temp[0], TGSI_WRITEMASK_XYZ),
|
|
||||||
ureg_src(temp[0]),
|
|
||||||
ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
unpremultiply( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
ureg_TEX(ureg, temp[0], TGSI_TEXTURE_2D, in[0], sampler[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
color_bw( struct ureg_program *ureg,
|
|
||||||
struct ureg_dst *out,
|
|
||||||
struct ureg_src *in,
|
|
||||||
struct ureg_src *sampler,
|
|
||||||
struct ureg_dst *temp,
|
|
||||||
struct ureg_src *constant)
|
|
||||||
{
|
|
||||||
ureg_ADD(ureg, temp[1],
|
|
||||||
ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
|
|
||||||
ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
|
|
||||||
ureg_RCP(ureg, temp[2], ureg_src(temp[1]));
|
|
||||||
ureg_ADD(ureg, temp[1],
|
|
||||||
ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
|
|
||||||
ureg_src(temp[2]));
|
|
||||||
ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X),
|
|
||||||
ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X),
|
|
||||||
ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_Y));
|
|
||||||
ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X),
|
|
||||||
ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_Z),
|
|
||||||
ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X));
|
|
||||||
ureg_SGE(ureg,
|
|
||||||
ureg_writemask(temp[0], TGSI_WRITEMASK_XYZ),
|
|
||||||
ureg_scalar(ureg_src(temp[2]), TGSI_SWIZZLE_X),
|
|
||||||
ureg_src(temp[1]));
|
|
||||||
ureg_SGE(ureg,
|
|
||||||
ureg_writemask(temp[0], TGSI_WRITEMASK_W),
|
|
||||||
ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
|
|
||||||
ureg_scalar(ureg_src(temp[2]), TGSI_SWIZZLE_Y));
|
|
||||||
ureg_MOV(ureg, *out, ureg_src(temp[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct shader_asm_info {
|
|
||||||
VGint id;
|
|
||||||
ureg_func func;
|
|
||||||
|
|
||||||
VGboolean needs_position;
|
|
||||||
|
|
||||||
VGint start_const;
|
|
||||||
VGint num_consts;
|
|
||||||
|
|
||||||
VGint start_sampler;
|
|
||||||
VGint num_samplers;
|
|
||||||
|
|
||||||
VGint start_temp;
|
|
||||||
VGint num_temps;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* paint types */
|
|
||||||
static const struct shader_asm_info shaders_paint_asm[] = {
|
|
||||||
{VEGA_SOLID_FILL_SHADER, solid_fill,
|
|
||||||
VG_FALSE, 2, 1, 0, 0, 0, 0},
|
|
||||||
{VEGA_LINEAR_GRADIENT_SHADER, linear_grad,
|
|
||||||
VG_TRUE, 2, 5, 0, 1, 0, 5},
|
|
||||||
{VEGA_RADIAL_GRADIENT_SHADER, radial_grad,
|
|
||||||
VG_TRUE, 2, 5, 0, 1, 0, 5},
|
|
||||||
{VEGA_PATTERN_SHADER, pattern,
|
|
||||||
VG_TRUE, 3, 4, 0, 1, 0, 5},
|
|
||||||
{VEGA_PAINT_DEGENERATE_SHADER, paint_degenerate,
|
|
||||||
VG_FALSE, 3, 1, 0, 1, 0, 2}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* image draw modes */
|
|
||||||
static const struct shader_asm_info shaders_image_asm[] = {
|
|
||||||
{VEGA_IMAGE_NORMAL_SHADER, image_normal,
|
|
||||||
VG_TRUE, 0, 0, 3, 1, 0, 2},
|
|
||||||
{VEGA_IMAGE_MULTIPLY_SHADER, image_multiply,
|
|
||||||
VG_TRUE, 0, 0, 3, 1, 0, 2},
|
|
||||||
{VEGA_IMAGE_STENCIL_SHADER, image_stencil,
|
|
||||||
VG_TRUE, 0, 0, 3, 1, 0, 2}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct shader_asm_info shaders_color_transform_asm[] = {
|
|
||||||
{VEGA_COLOR_TRANSFORM_SHADER, color_transform,
|
|
||||||
VG_FALSE, 0, 4, 0, 0, 0, 3}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct shader_asm_info shaders_alpha_asm[] = {
|
|
||||||
{VEGA_ALPHA_NORMAL_SHADER, alpha_normal,
|
|
||||||
VG_FALSE, 0, 0, 0, 0, 0, 2},
|
|
||||||
{VEGA_ALPHA_PER_CHANNEL_SHADER, alpha_per_channel,
|
|
||||||
VG_FALSE, 0, 0, 0, 0, 0, 2}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* extra blend modes */
|
|
||||||
static const struct shader_asm_info shaders_blend_asm[] = {
|
|
||||||
#define BLEND_ASM_INFO(id, func) { (id), (func), VG_TRUE, 3, 1, 2, 1, 0, 5 }
|
|
||||||
BLEND_ASM_INFO(VEGA_BLEND_SRC_SHADER, blend_src),
|
|
||||||
BLEND_ASM_INFO(VEGA_BLEND_SRC_OVER_SHADER, blend_src_over),
|
|
||||||
BLEND_ASM_INFO(VEGA_BLEND_DST_OVER_SHADER, blend_dst_over),
|
|
||||||
BLEND_ASM_INFO(VEGA_BLEND_SRC_IN_SHADER, blend_src_in),
|
|
||||||
BLEND_ASM_INFO(VEGA_BLEND_DST_IN_SHADER, blend_dst_in),
|
|
||||||
BLEND_ASM_INFO(VEGA_BLEND_MULTIPLY_SHADER, blend_multiply),
|
|
||||||
BLEND_ASM_INFO(VEGA_BLEND_SCREEN_SHADER, blend_screen),
|
|
||||||
BLEND_ASM_INFO(VEGA_BLEND_DARKEN_SHADER, blend_darken),
|
|
||||||
BLEND_ASM_INFO(VEGA_BLEND_LIGHTEN_SHADER, blend_lighten),
|
|
||||||
BLEND_ASM_INFO(VEGA_BLEND_ADDITIVE_SHADER, blend_additive)
|
|
||||||
#undef BLEND_ASM_INFO
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct shader_asm_info shaders_mask_asm[] = {
|
|
||||||
{VEGA_MASK_SHADER, mask,
|
|
||||||
VG_TRUE, 0, 0, 1, 1, 0, 2}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* premultiply */
|
|
||||||
static const struct shader_asm_info shaders_premultiply_asm[] = {
|
|
||||||
{VEGA_PREMULTIPLY_SHADER, premultiply,
|
|
||||||
VG_FALSE, 0, 0, 0, 0, 0, 1},
|
|
||||||
{VEGA_UNPREMULTIPLY_SHADER, unpremultiply,
|
|
||||||
VG_FALSE, 0, 0, 0, 0, 0, 1},
|
|
||||||
};
|
|
||||||
|
|
||||||
/* color transform to black and white */
|
|
||||||
static const struct shader_asm_info shaders_bw_asm[] = {
|
|
||||||
{VEGA_BW_SHADER, color_bw,
|
|
||||||
VG_FALSE, 3, 1, 0, 0, 0, 3},
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef ASM_FILTERS_H
|
|
||||||
#define ASM_FILTERS_H
|
|
||||||
|
|
||||||
static const char color_matrix_asm[] =
|
|
||||||
"FRAG\n"
|
|
||||||
"DCL IN[0], GENERIC[0], PERSPECTIVE\n"
|
|
||||||
"DCL OUT[0], COLOR, CONSTANT\n"
|
|
||||||
"DCL CONST[0..4], CONSTANT\n"
|
|
||||||
"DCL TEMP[0..4], CONSTANT\n"
|
|
||||||
"DCL SAMP[0], CONSTANT\n"
|
|
||||||
"TEX TEMP[0], IN[0], SAMP[0], 2D\n"
|
|
||||||
"MOV TEMP[1], TEMP[0].xxxx\n"
|
|
||||||
"MOV TEMP[2], TEMP[0].yyyy\n"
|
|
||||||
"MOV TEMP[3], TEMP[0].zzzz\n"
|
|
||||||
"MOV TEMP[4], TEMP[0].wwww\n"
|
|
||||||
"MUL TEMP[1], TEMP[1], CONST[0]\n"
|
|
||||||
"MUL TEMP[2], TEMP[2], CONST[1]\n"
|
|
||||||
"MUL TEMP[3], TEMP[3], CONST[2]\n"
|
|
||||||
"MUL TEMP[4], TEMP[4], CONST[3]\n"
|
|
||||||
"ADD TEMP[0], TEMP[1], CONST[4]\n"
|
|
||||||
"ADD TEMP[0], TEMP[0], TEMP[2]\n"
|
|
||||||
"ADD TEMP[0], TEMP[0], TEMP[3]\n"
|
|
||||||
"ADD TEMP[0], TEMP[0], TEMP[4]\n"
|
|
||||||
"MOV OUT[0], TEMP[0]\n"
|
|
||||||
"END\n";
|
|
||||||
|
|
||||||
static const char convolution_asm[] =
|
|
||||||
"FRAG\n"
|
|
||||||
"DCL IN[0], GENERIC[0], PERSPECTIVE\n"
|
|
||||||
"DCL OUT[0], COLOR, CONSTANT\n"
|
|
||||||
"DCL TEMP[0..4], CONSTANT\n"
|
|
||||||
"DCL ADDR[0], CONSTANT\n"
|
|
||||||
"DCL CONST[0..%d], CONSTANT\n"
|
|
||||||
"DCL SAMP[0], CONSTANT\n"
|
|
||||||
"0: MOV TEMP[0], CONST[0].xxxx\n"
|
|
||||||
"1: MOV TEMP[1], CONST[0].xxxx\n"
|
|
||||||
"2: BGNLOOP :14\n"
|
|
||||||
"3: SGE TEMP[0].z, TEMP[0].yyyy, CONST[1].xxxx\n"
|
|
||||||
"4: IF TEMP[0].zzzz :7\n"
|
|
||||||
"5: BRK\n"
|
|
||||||
"6: ENDIF\n"
|
|
||||||
"7: ARL ADDR[0].x, TEMP[0].yyyy\n"
|
|
||||||
"8: MOV TEMP[3], CONST[ADDR[0]+2]\n"
|
|
||||||
"9: ADD TEMP[4].xy, IN[0], TEMP[3]\n"
|
|
||||||
"10: TEX TEMP[2], TEMP[4], SAMP[0], 2D\n"
|
|
||||||
"11: MOV TEMP[3], CONST[ADDR[0]+%d]\n"
|
|
||||||
"12: MAD TEMP[1], TEMP[2], TEMP[3], TEMP[1]\n"
|
|
||||||
"13: ADD TEMP[0].y, TEMP[0].yyyy, CONST[0].yyyy\n"
|
|
||||||
"14: ENDLOOP :2\n"
|
|
||||||
"15: MAD OUT[0], TEMP[1], CONST[1].yyyy, CONST[1].zzzz\n"
|
|
||||||
"16: END\n";
|
|
||||||
|
|
||||||
|
|
||||||
static const char lookup_asm[] =
|
|
||||||
"FRAG\n"
|
|
||||||
"DCL IN[0], GENERIC[0], PERSPECTIVE\n"
|
|
||||||
"DCL OUT[0], COLOR, CONSTANT\n"
|
|
||||||
"DCL TEMP[0..2], CONSTANT\n"
|
|
||||||
"DCL CONST[0], CONSTANT\n"
|
|
||||||
"DCL SAMP[0..1], CONSTANT\n"
|
|
||||||
"TEX TEMP[0], IN[0], SAMP[0], 2D\n"
|
|
||||||
"MOV TEMP[1], TEMP[0]\n"
|
|
||||||
/* do red */
|
|
||||||
"TEX TEMP[2], TEMP[1].xxxx, SAMP[1], 1D\n"
|
|
||||||
"MOV TEMP[0].x, TEMP[2].xxxx\n"
|
|
||||||
/* do blue */
|
|
||||||
"TEX TEMP[2], TEMP[1].yyyy, SAMP[1], 1D\n"
|
|
||||||
"MOV TEMP[0].y, TEMP[2].yyyy\n"
|
|
||||||
/* do green */
|
|
||||||
"TEX TEMP[2], TEMP[1].zzzz, SAMP[1], 1D\n"
|
|
||||||
"MOV TEMP[0].z, TEMP[2].zzzz\n"
|
|
||||||
/* do alpha */
|
|
||||||
"TEX TEMP[2], TEMP[1].wwww, SAMP[1], 1D\n"
|
|
||||||
"MOV TEMP[0].w, TEMP[2].wwww\n"
|
|
||||||
"MOV OUT[0], TEMP[0]\n"
|
|
||||||
"END\n";
|
|
||||||
|
|
||||||
|
|
||||||
static const char lookup_single_asm[] =
|
|
||||||
"FRAG\n"
|
|
||||||
"DCL IN[0], GENERIC[0], PERSPECTIVE\n"
|
|
||||||
"DCL OUT[0], COLOR, CONSTANT\n"
|
|
||||||
"DCL TEMP[0..2], CONSTANT\n"
|
|
||||||
"DCL CONST[0], CONSTANT\n"
|
|
||||||
"DCL SAMP[0..1], CONSTANT\n"
|
|
||||||
"TEX TEMP[0], IN[0], SAMP[0], 2D\n"
|
|
||||||
"TEX TEMP[1], TEMP[0].%s, SAMP[1], 1D\n"
|
|
||||||
"MOV OUT[0], TEMP[1]\n"
|
|
||||||
"END\n";
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef ASM_UTIL_H
|
|
||||||
#define ASM_UTIL_H
|
|
||||||
|
|
||||||
/* μnew = μmask */
|
|
||||||
static const char set_mask_asm[] =
|
|
||||||
"FRAG\n"
|
|
||||||
"DCL IN[0], GENERIC[0], PERSPECTIVE\n"
|
|
||||||
"DCL SAMP[0], CONSTANT\n"
|
|
||||||
"DCL OUT[0], COLOR, CONSTANT\n"
|
|
||||||
"0: TEX OUT[0], IN[0], SAMP[0], 2D\n"/*umask*/
|
|
||||||
"1: END\n";
|
|
||||||
|
|
||||||
/* μnew = 1 – (1 – μmask)*(1 – μprev) */
|
|
||||||
static const char union_mask_asm[] =
|
|
||||||
"FRAG\n"
|
|
||||||
"DCL IN[0], GENERIC[0], PERSPECTIVE\n"
|
|
||||||
"DCL IN[1], POSITION, LINEAR\n"
|
|
||||||
"DCL CONST[0], CONSTANT\n"
|
|
||||||
"DCL SAMP[0..1], CONSTANT\n"
|
|
||||||
"DCL TEMP[0..3], CONSTANT\n"
|
|
||||||
"DCL OUT[0], COLOR, CONSTANT\n"
|
|
||||||
"0: TEX TEMP[1], IN[0], SAMP[0], 2D\n"/*umask*/
|
|
||||||
"1: TEX TEMP[0], IN[1], SAMP[1], 2D\n"/*uprev*/
|
|
||||||
"2: SUB TEMP[2], CONST[0], TEMP[0]\n"
|
|
||||||
"3: SUB TEMP[3], CONST[0], TEMP[1]\n"
|
|
||||||
"4: MUL TEMP[0].w, TEMP[2].wwww, TEMP[3].wwww\n"
|
|
||||||
"5: SUB OUT[0], CONST[0], TEMP[0]\n"
|
|
||||||
"6: END\n";
|
|
||||||
|
|
||||||
/* μnew = μmask *μprev */
|
|
||||||
static const char intersect_mask_asm[] =
|
|
||||||
"FRAG\n"
|
|
||||||
"DCL IN[0], GENERIC[0], PERSPECTIVE\n"
|
|
||||||
"DCL IN[1], POSITION, LINEAR\n"
|
|
||||||
"DCL CONST[0], CONSTANT\n"
|
|
||||||
"DCL SAMP[0..1], CONSTANT\n"
|
|
||||||
"DCL TEMP[0..1], CONSTANT\n"
|
|
||||||
"DCL OUT[0], COLOR, CONSTANT\n"
|
|
||||||
"0: TEX TEMP[0], IN[1], SAMP[1], 2D\n"/*uprev*/
|
|
||||||
"1: TEX TEMP[1], IN[0], SAMP[0], 2D\n"/*umask*/
|
|
||||||
"2: MUL OUT[0], TEMP[0].wwww, TEMP[1].wwww\n"
|
|
||||||
"3: END\n";
|
|
||||||
|
|
||||||
/* μnew = μprev*(1 – μmask) */
|
|
||||||
static const char subtract_mask_asm[] =
|
|
||||||
"FRAG\n"
|
|
||||||
"DCL IN[0], GENERIC[0], PERSPECTIVE\n"
|
|
||||||
"DCL IN[1], POSITION, LINEAR\n"
|
|
||||||
"DCL CONST[0], CONSTANT\n"
|
|
||||||
"DCL SAMP[0..1], CONSTANT\n"
|
|
||||||
"DCL TEMP[0..2], CONSTANT\n"
|
|
||||||
"DCL OUT[0], COLOR, CONSTANT\n"
|
|
||||||
"0: TEX TEMP[1], IN[0], SAMP[0], 2D\n"/*umask*/
|
|
||||||
"1: TEX TEMP[0], IN[1], SAMP[1], 2D\n"/*uprev*/
|
|
||||||
"2: SUB TEMP[2], CONST[0], TEMP[1]\n"
|
|
||||||
"3: MUL OUT[0], TEMP[2].wwww, TEMP[0].wwww\n"
|
|
||||||
"4: END\n";
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,706 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "bezier.h"
|
|
||||||
|
|
||||||
#include "matrix.h"
|
|
||||||
#include "polygon.h"
|
|
||||||
|
|
||||||
#include "pipe/p_compiler.h"
|
|
||||||
#include "util/u_debug.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
static const float flatness = 0.5;
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void split_left(struct bezier *bez, VGfloat t, struct bezier* left)
|
|
||||||
{
|
|
||||||
left->x1 = bez->x1;
|
|
||||||
left->y1 = bez->y1;
|
|
||||||
|
|
||||||
left->x2 = bez->x1 + t * (bez->x2 - bez->x1);
|
|
||||||
left->y2 = bez->y1 + t * (bez->y2 - bez->y1);
|
|
||||||
|
|
||||||
left->x3 = bez->x2 + t * (bez->x3 - bez->x2);
|
|
||||||
left->y3 = bez->y2 + t * (bez->y3 - bez->y2);
|
|
||||||
|
|
||||||
bez->x3 = bez->x3 + t * (bez->x4 - bez->x3);
|
|
||||||
bez->y3 = bez->y3 + t * (bez->y4 - bez->y3);
|
|
||||||
|
|
||||||
bez->x2 = left->x3 + t * (bez->x3 - left->x3);
|
|
||||||
bez->y2 = left->y3 + t * (bez->y3 - left->y3);
|
|
||||||
|
|
||||||
left->x3 = left->x2 + t * (left->x3 - left->x2);
|
|
||||||
left->y3 = left->y2 + t * (left->y3 - left->y2);
|
|
||||||
|
|
||||||
left->x4 = bez->x1 = left->x3 + t * (bez->x2 - left->x3);
|
|
||||||
left->y4 = bez->y1 = left->y3 + t * (bez->y2 - left->y3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void split(struct bezier *bez,
|
|
||||||
struct bezier *first_half,
|
|
||||||
struct bezier *second_half)
|
|
||||||
{
|
|
||||||
double c = (bez->x2 + bez->x3) * 0.5;
|
|
||||||
first_half->x2 = (bez->x1 + bez->x2) * 0.5;
|
|
||||||
second_half->x3 = (bez->x3 + bez->x4) * 0.5;
|
|
||||||
first_half->x1 = bez->x1;
|
|
||||||
second_half->x4 = bez->x4;
|
|
||||||
first_half->x3 = (first_half->x2 + c) * 0.5;
|
|
||||||
second_half->x2 = (second_half->x3 + c) * 0.5;
|
|
||||||
first_half->x4 = second_half->x1 =
|
|
||||||
(first_half->x3 + second_half->x2) * 0.5;
|
|
||||||
|
|
||||||
c = (bez->y2 + bez->y3) / 2;
|
|
||||||
first_half->y2 = (bez->y1 + bez->y2) * 0.5;
|
|
||||||
second_half->y3 = (bez->y3 + bez->y4) * 0.5;
|
|
||||||
first_half->y1 = bez->y1;
|
|
||||||
second_half->y4 = bez->y4;
|
|
||||||
first_half->y3 = (first_half->y2 + c) * 0.5;
|
|
||||||
second_half->y2 = (second_half->y3 + c) * 0.5;
|
|
||||||
first_half->y4 = second_half->y1 =
|
|
||||||
(first_half->y3 + second_half->y2) * 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct polygon * bezier_to_polygon(struct bezier *bez)
|
|
||||||
{
|
|
||||||
struct polygon *poly = polygon_create(64);
|
|
||||||
polygon_vertex_append(poly, bez->x1, bez->y1);
|
|
||||||
bezier_add_to_polygon(bez, poly);
|
|
||||||
return poly;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bezier_add_to_polygon(const struct bezier *bez,
|
|
||||||
struct polygon *poly)
|
|
||||||
{
|
|
||||||
struct bezier beziers[32];
|
|
||||||
struct bezier *b;
|
|
||||||
|
|
||||||
beziers[0] = *bez;
|
|
||||||
b = beziers;
|
|
||||||
|
|
||||||
while (b >= beziers) {
|
|
||||||
double y4y1 = b->y4 - b->y1;
|
|
||||||
double x4x1 = b->x4 - b->x1;
|
|
||||||
double l = ABS(x4x1) + ABS(y4y1);
|
|
||||||
double d;
|
|
||||||
if (l > 1.f) {
|
|
||||||
d = ABS((x4x1)*(b->y1 - b->y2) - (y4y1)*(b->x1 - b->x2))
|
|
||||||
+ ABS((x4x1)*(b->y1 - b->y3) - (y4y1)*(b->x1 - b->x3));
|
|
||||||
} else {
|
|
||||||
d = ABS(b->x1 - b->x2) + ABS(b->y1 - b->y2) +
|
|
||||||
ABS(b->x1 - b->x3) + ABS(b->y1 - b->y3);
|
|
||||||
l = 1.;
|
|
||||||
}
|
|
||||||
if (d < flatness*l || b == beziers + 31) {
|
|
||||||
/* good enough, we pop it off and add the endpoint */
|
|
||||||
polygon_vertex_append(poly, b->x4, b->y4);
|
|
||||||
--b;
|
|
||||||
} else {
|
|
||||||
/* split, second half of the bezier goes lower into the stack */
|
|
||||||
split(b, b+1, b);
|
|
||||||
++b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_if_close(struct bezier *bez, VGfloat *length, VGfloat error)
|
|
||||||
{
|
|
||||||
struct bezier left, right; /* bez poly splits */
|
|
||||||
VGfloat len = 0.0; /* arc length */
|
|
||||||
VGfloat chord; /* chord length */
|
|
||||||
|
|
||||||
len = len + line_length(bez->x1, bez->y1, bez->x2, bez->y2);
|
|
||||||
len = len + line_length(bez->x2, bez->y2, bez->x3, bez->y3);
|
|
||||||
len = len + line_length(bez->x3, bez->y3, bez->x4, bez->y4);
|
|
||||||
|
|
||||||
chord = line_length(bez->x1, bez->y1, bez->x4, bez->y4);
|
|
||||||
|
|
||||||
if ((len-chord) > error) {
|
|
||||||
split(bez, &left, &right); /* split in two */
|
|
||||||
add_if_close(&left, length, error); /* try left side */
|
|
||||||
add_if_close(&right, length, error); /* try right side */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*length = *length + len;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float bezier_length(struct bezier *bez, float error)
|
|
||||||
{
|
|
||||||
VGfloat length = 0.f;
|
|
||||||
|
|
||||||
add_if_close(bez, &length, error);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bezier_init(struct bezier *bez,
|
|
||||||
float x1, float y1,
|
|
||||||
float x2, float y2,
|
|
||||||
float x3, float y3,
|
|
||||||
float x4, float y4)
|
|
||||||
{
|
|
||||||
bez->x1 = x1;
|
|
||||||
bez->y1 = y1;
|
|
||||||
bez->x2 = x2;
|
|
||||||
bez->y2 = y2;
|
|
||||||
bez->x3 = x3;
|
|
||||||
bez->y3 = y3;
|
|
||||||
bez->x4 = x4;
|
|
||||||
bez->y4 = y4;
|
|
||||||
#if 0
|
|
||||||
debug_printf("bezier in [%f, %f, %f, %f, %f, %f]\n",
|
|
||||||
x1, y1, x2, y2, x3, y3, x4, y4);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void bezier_init2v(struct bezier *bez,
|
|
||||||
float *pt1,
|
|
||||||
float *pt2,
|
|
||||||
float *pt3,
|
|
||||||
float *pt4)
|
|
||||||
{
|
|
||||||
bez->x1 = pt1[0];
|
|
||||||
bez->y1 = pt1[1];
|
|
||||||
|
|
||||||
bez->x2 = pt2[0];
|
|
||||||
bez->y2 = pt2[1];
|
|
||||||
|
|
||||||
bez->x3 = pt3[0];
|
|
||||||
bez->y3 = pt3[1];
|
|
||||||
|
|
||||||
bez->x4 = pt4[0];
|
|
||||||
bez->y4 = pt4[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bezier_transform(struct bezier *bez,
|
|
||||||
struct matrix *matrix)
|
|
||||||
{
|
|
||||||
assert(matrix_is_affine(matrix));
|
|
||||||
matrix_map_point(matrix, bez->x1, bez->y1, &bez->x1, &bez->y1);
|
|
||||||
matrix_map_point(matrix, bez->x2, bez->y2, &bez->x2, &bez->y2);
|
|
||||||
matrix_map_point(matrix, bez->x3, bez->y3, &bez->x3, &bez->y3);
|
|
||||||
matrix_map_point(matrix, bez->x4, bez->y4, &bez->x4, &bez->y4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void bezier_point_at(const struct bezier *bez, float t, float *pt)
|
|
||||||
{
|
|
||||||
float a, b, c, d;
|
|
||||||
float m_t;
|
|
||||||
m_t = 1. - t;
|
|
||||||
b = m_t * m_t;
|
|
||||||
c = t * t;
|
|
||||||
d = c * t;
|
|
||||||
a = b * m_t;
|
|
||||||
b *= 3. * t;
|
|
||||||
c *= 3. * m_t;
|
|
||||||
pt[0] = a*bez->x1 + b*bez->x2 + c*bez->x3 + d*bez->x4;
|
|
||||||
pt[1] = a*bez->y1 + b*bez->y2 + c*bez->y3 + d*bez->y4;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void bezier_normal_at(const struct bezier *bez, float t, float *norm)
|
|
||||||
{
|
|
||||||
float m_t = 1. - t;
|
|
||||||
float a = m_t * m_t;
|
|
||||||
float b = t * m_t;
|
|
||||||
float c = t * t;
|
|
||||||
|
|
||||||
norm[0] = (bez->y2-bez->y1) * a + (bez->y3-bez->y2) * b + (bez->y4-bez->y3) * c;
|
|
||||||
norm[1] = -(bez->x2-bez->x1) * a - (bez->x3-bez->x2) * b - (bez->x4-bez->x3) * c;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum shift_result {
|
|
||||||
Ok,
|
|
||||||
Discard,
|
|
||||||
Split,
|
|
||||||
Circle
|
|
||||||
};
|
|
||||||
|
|
||||||
static enum shift_result good_offset(const struct bezier *b1,
|
|
||||||
const struct bezier *b2,
|
|
||||||
float offset, float threshold)
|
|
||||||
{
|
|
||||||
const float o2 = offset*offset;
|
|
||||||
const float max_dist_line = threshold*offset*offset;
|
|
||||||
const float max_dist_normal = threshold*offset;
|
|
||||||
const float spacing = 0.25;
|
|
||||||
float i;
|
|
||||||
for (i = spacing; i < 0.99; i += spacing) {
|
|
||||||
float p1[2],p2[2], d, l;
|
|
||||||
float normal[2];
|
|
||||||
bezier_point_at(b1, i, p1);
|
|
||||||
bezier_point_at(b2, i, p2);
|
|
||||||
d = (p1[0] - p2[0])*(p1[0] - p2[0]) + (p1[1] - p2[1])*(p1[1] - p2[1]);
|
|
||||||
if (ABS(d - o2) > max_dist_line)
|
|
||||||
return Split;
|
|
||||||
|
|
||||||
bezier_normal_at(b1, i, normal);
|
|
||||||
l = ABS(normal[0]) + ABS(normal[1]);
|
|
||||||
if (l != 0.) {
|
|
||||||
d = ABS(normal[0]*(p1[1] - p2[1]) - normal[1]*(p1[0] - p2[0]) ) / l;
|
|
||||||
if (d > max_dist_normal)
|
|
||||||
return Split;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void shift_line_by_normal(float *l, float offset)
|
|
||||||
{
|
|
||||||
float norm[4];
|
|
||||||
float tx, ty;
|
|
||||||
|
|
||||||
line_normal(l, norm);
|
|
||||||
line_normalize(norm);
|
|
||||||
|
|
||||||
tx = (norm[2] - norm[0]) * offset;
|
|
||||||
ty = (norm[3] - norm[1]) * offset;
|
|
||||||
l[0] += tx; l[1] += ty;
|
|
||||||
l[2] += tx; l[3] += ty;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGboolean is_bezier_line(float (*points)[2], int count)
|
|
||||||
{
|
|
||||||
float dx13 = points[2][0] - points[0][0];
|
|
||||||
float dy13 = points[2][1] - points[0][1];
|
|
||||||
|
|
||||||
float dx12 = points[1][0] - points[0][0];
|
|
||||||
float dy12 = points[1][1] - points[0][1];
|
|
||||||
|
|
||||||
debug_assert(count > 2);
|
|
||||||
|
|
||||||
if (count == 3) {
|
|
||||||
return floatsEqual(dx12 * dy13, dx13 * dy12);
|
|
||||||
} else if (count == 4) {
|
|
||||||
float dx14 = points[3][0] - points[0][0];
|
|
||||||
float dy14 = points[3][1] - points[0][1];
|
|
||||||
|
|
||||||
return (floatsEqual(dx12 * dy13, dx13 * dy12) &&
|
|
||||||
floatsEqual(dx12 * dy14, dx14 * dy12));
|
|
||||||
}
|
|
||||||
|
|
||||||
return VG_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void compute_pt_normal(float *pt1, float *pt2, float *res)
|
|
||||||
{
|
|
||||||
float line[4];
|
|
||||||
float normal[4];
|
|
||||||
line[0] = 0.f; line[1] = 0.f;
|
|
||||||
line[2] = pt2[0] - pt1[0];
|
|
||||||
line[3] = pt2[1] - pt1[1];
|
|
||||||
line_normal(line, normal);
|
|
||||||
line_normalize(normal);
|
|
||||||
|
|
||||||
res[0] = normal[2];
|
|
||||||
res[1] = normal[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum shift_result shift(const struct bezier *orig,
|
|
||||||
struct bezier *shifted,
|
|
||||||
float offset, float threshold)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int map[4];
|
|
||||||
VGboolean p1_p2_equal = (orig->x1 == orig->x2 && orig->y1 == orig->y2);
|
|
||||||
VGboolean p2_p3_equal = (orig->x2 == orig->x3 && orig->y2 == orig->y3);
|
|
||||||
VGboolean p3_p4_equal = (orig->x3 == orig->x4 && orig->y3 == orig->y4);
|
|
||||||
|
|
||||||
float points[4][2];
|
|
||||||
int np = 0;
|
|
||||||
float bounds[4];
|
|
||||||
float points_shifted[4][2];
|
|
||||||
float prev_normal[2];
|
|
||||||
|
|
||||||
points[np][0] = orig->x1;
|
|
||||||
points[np][1] = orig->y1;
|
|
||||||
map[0] = 0;
|
|
||||||
++np;
|
|
||||||
if (!p1_p2_equal) {
|
|
||||||
points[np][0] = orig->x2;
|
|
||||||
points[np][1] = orig->y2;
|
|
||||||
++np;
|
|
||||||
}
|
|
||||||
map[1] = np - 1;
|
|
||||||
if (!p2_p3_equal) {
|
|
||||||
points[np][0] = orig->x3;
|
|
||||||
points[np][1] = orig->y3;
|
|
||||||
++np;
|
|
||||||
}
|
|
||||||
map[2] = np - 1;
|
|
||||||
if (!p3_p4_equal) {
|
|
||||||
points[np][0] = orig->x4;
|
|
||||||
points[np][1] = orig->y4;
|
|
||||||
++np;
|
|
||||||
}
|
|
||||||
map[3] = np - 1;
|
|
||||||
if (np == 1)
|
|
||||||
return Discard;
|
|
||||||
|
|
||||||
/* We need to specialcase lines of 3 or 4 points due to numerical
|
|
||||||
instability in intersection code below */
|
|
||||||
if (np > 2 && is_bezier_line(points, np)) {
|
|
||||||
float l[4] = { points[0][0], points[0][1],
|
|
||||||
points[np-1][0], points[np-1][1] };
|
|
||||||
float ctrl1[2], ctrl2[2];
|
|
||||||
if (floatsEqual(points[0][0], points[np-1][0]) &&
|
|
||||||
floatsEqual(points[0][1], points[np-1][1]))
|
|
||||||
return Discard;
|
|
||||||
|
|
||||||
shift_line_by_normal(l, offset);
|
|
||||||
line_point_at(l, 0.33, ctrl1);
|
|
||||||
line_point_at(l, 0.66, ctrl2);
|
|
||||||
bezier_init(shifted, l[0], l[1],
|
|
||||||
ctrl1[0], ctrl1[1], ctrl2[0], ctrl2[1],
|
|
||||||
l[2], l[3]);
|
|
||||||
return Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
bezier_bounds(orig, bounds);
|
|
||||||
if (np == 4 && bounds[2] < .1*offset && bounds[3] < .1*offset) {
|
|
||||||
float l = (orig->x1 - orig->x2)*(orig->x1 - orig->x2) +
|
|
||||||
(orig->y1 - orig->y2)*(orig->y1 - orig->y1) *
|
|
||||||
(orig->x3 - orig->x4)*(orig->x3 - orig->x4) +
|
|
||||||
(orig->y3 - orig->y4)*(orig->y3 - orig->y4);
|
|
||||||
float dot = (orig->x1 - orig->x2)*(orig->x3 - orig->x4) +
|
|
||||||
(orig->y1 - orig->y2)*(orig->y3 - orig->y4);
|
|
||||||
if (dot < 0 && dot*dot < 0.8*l)
|
|
||||||
/* the points are close and reverse dirction. Approximate the whole
|
|
||||||
thing by a semi circle */
|
|
||||||
return Circle;
|
|
||||||
}
|
|
||||||
|
|
||||||
compute_pt_normal(points[0], points[1], prev_normal);
|
|
||||||
|
|
||||||
points_shifted[0][0] = points[0][0] + offset * prev_normal[0];
|
|
||||||
points_shifted[0][1] = points[0][1] + offset * prev_normal[1];
|
|
||||||
|
|
||||||
for (i = 1; i < np - 1; ++i) {
|
|
||||||
float normal_sum[2], r;
|
|
||||||
float next_normal[2];
|
|
||||||
compute_pt_normal(points[i], points[i + 1], next_normal);
|
|
||||||
|
|
||||||
normal_sum[0] = prev_normal[0] + next_normal[0];
|
|
||||||
normal_sum[1] = prev_normal[1] + next_normal[1];
|
|
||||||
|
|
||||||
r = 1.0 + prev_normal[0] * next_normal[0]
|
|
||||||
+ prev_normal[1] * next_normal[1];
|
|
||||||
|
|
||||||
if (floatsEqual(r + 1, 1)) {
|
|
||||||
points_shifted[i][0] = points[i][0] + offset * prev_normal[0];
|
|
||||||
points_shifted[i][1] = points[i][1] + offset * prev_normal[1];
|
|
||||||
} else {
|
|
||||||
float k = offset / r;
|
|
||||||
points_shifted[i][0] = points[i][0] + k * normal_sum[0];
|
|
||||||
points_shifted[i][1] = points[i][1] + k * normal_sum[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_normal[0] = next_normal[0];
|
|
||||||
prev_normal[1] = next_normal[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
points_shifted[np - 1][0] = points[np - 1][0] + offset * prev_normal[0];
|
|
||||||
points_shifted[np - 1][1] = points[np - 1][1] + offset * prev_normal[1];
|
|
||||||
|
|
||||||
bezier_init2v(shifted,
|
|
||||||
points_shifted[map[0]], points_shifted[map[1]],
|
|
||||||
points_shifted[map[2]], points_shifted[map[3]]);
|
|
||||||
|
|
||||||
return good_offset(orig, shifted, offset, threshold);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VGboolean make_circle(const struct bezier *b, float offset, struct bezier *o)
|
|
||||||
{
|
|
||||||
float normals[3][2];
|
|
||||||
float dist;
|
|
||||||
float angles[2];
|
|
||||||
float sign = 1.f;
|
|
||||||
int i;
|
|
||||||
float circle[3][2];
|
|
||||||
|
|
||||||
normals[0][0] = b->y2 - b->y1;
|
|
||||||
normals[0][1] = b->x1 - b->x2;
|
|
||||||
dist = sqrt(normals[0][0]*normals[0][0] + normals[0][1]*normals[0][1]);
|
|
||||||
if (floatsEqual(dist + 1, 1.f))
|
|
||||||
return VG_FALSE;
|
|
||||||
normals[0][0] /= dist;
|
|
||||||
normals[0][1] /= dist;
|
|
||||||
|
|
||||||
normals[2][0] = b->y4 - b->y3;
|
|
||||||
normals[2][1] = b->x3 - b->x4;
|
|
||||||
dist = sqrt(normals[2][0]*normals[2][0] + normals[2][1]*normals[2][1]);
|
|
||||||
if (floatsEqual(dist + 1, 1.f))
|
|
||||||
return VG_FALSE;
|
|
||||||
normals[2][0] /= dist;
|
|
||||||
normals[2][1] /= dist;
|
|
||||||
|
|
||||||
normals[1][0] = b->x1 - b->x2 - b->x3 + b->x4;
|
|
||||||
normals[1][1] = b->y1 - b->y2 - b->y3 + b->y4;
|
|
||||||
dist = -1*sqrt(normals[1][0]*normals[1][0] + normals[1][1]*normals[1][1]);
|
|
||||||
normals[1][0] /= dist;
|
|
||||||
normals[1][1] /= dist;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; ++i) {
|
|
||||||
float cos_a = normals[i][0]*normals[i+1][0] + normals[i][1]*normals[i+1][1];
|
|
||||||
if (cos_a > 1.)
|
|
||||||
cos_a = 1.;
|
|
||||||
if (cos_a < -1.)
|
|
||||||
cos_a = -1;
|
|
||||||
angles[i] = acos(cos_a)/M_PI;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (angles[0] + angles[1] > 1.) {
|
|
||||||
/* more than 180 degrees */
|
|
||||||
normals[1][0] = -normals[1][0];
|
|
||||||
normals[1][1] = -normals[1][1];
|
|
||||||
angles[0] = 1. - angles[0];
|
|
||||||
angles[1] = 1. - angles[1];
|
|
||||||
sign = -1.;
|
|
||||||
}
|
|
||||||
|
|
||||||
circle[0][0] = b->x1 + normals[0][0]*offset;
|
|
||||||
circle[0][1] = b->y1 + normals[0][1]*offset;
|
|
||||||
|
|
||||||
circle[1][0] = 0.5*(b->x1 + b->x4) + normals[1][0]*offset;
|
|
||||||
circle[1][1] = 0.5*(b->y1 + b->y4) + normals[1][1]*offset;
|
|
||||||
|
|
||||||
circle[2][0] = b->x4 + normals[2][0]*offset;
|
|
||||||
circle[2][1] = b->y4 + normals[2][1]*offset;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; ++i) {
|
|
||||||
float kappa = 2.*KAPPA * sign * offset * angles[i];
|
|
||||||
|
|
||||||
o->x1 = circle[i][0];
|
|
||||||
o->y1 = circle[i][1];
|
|
||||||
o->x2 = circle[i][0] - normals[i][1]*kappa;
|
|
||||||
o->y2 = circle[i][1] + normals[i][0]*kappa;
|
|
||||||
o->x3 = circle[i+1][0] + normals[i+1][1]*kappa;
|
|
||||||
o->y3 = circle[i+1][1] - normals[i+1][0]*kappa;
|
|
||||||
o->x4 = circle[i+1][0];
|
|
||||||
o->y4 = circle[i+1][1];
|
|
||||||
|
|
||||||
++o;
|
|
||||||
}
|
|
||||||
return VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bezier_translate_by_normal(struct bezier *bez,
|
|
||||||
struct bezier *curves,
|
|
||||||
int max_curves,
|
|
||||||
float normal_len,
|
|
||||||
float threshold)
|
|
||||||
{
|
|
||||||
struct bezier beziers[10];
|
|
||||||
struct bezier *b, *o;
|
|
||||||
|
|
||||||
/* fixme: this should really be floatsEqual */
|
|
||||||
if (bez->x1 == bez->x2 && bez->x1 == bez->x3 && bez->x1 == bez->x4 &&
|
|
||||||
bez->y1 == bez->y2 && bez->y1 == bez->y3 && bez->y1 == bez->y4)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
--max_curves;
|
|
||||||
redo:
|
|
||||||
beziers[0] = *bez;
|
|
||||||
b = beziers;
|
|
||||||
o = curves;
|
|
||||||
|
|
||||||
while (b >= beziers) {
|
|
||||||
int stack_segments = b - beziers + 1;
|
|
||||||
enum shift_result res;
|
|
||||||
if ((stack_segments == 10) || (o - curves == max_curves - stack_segments)) {
|
|
||||||
threshold *= 1.5;
|
|
||||||
if (threshold > 2.)
|
|
||||||
goto give_up;
|
|
||||||
goto redo;
|
|
||||||
}
|
|
||||||
res = shift(b, o, normal_len, threshold);
|
|
||||||
if (res == Discard) {
|
|
||||||
--b;
|
|
||||||
} else if (res == Ok) {
|
|
||||||
++o;
|
|
||||||
--b;
|
|
||||||
continue;
|
|
||||||
} else if (res == Circle && max_curves - (o - curves) >= 2) {
|
|
||||||
/* add semi circle */
|
|
||||||
if (make_circle(b, normal_len, o))
|
|
||||||
o += 2;
|
|
||||||
--b;
|
|
||||||
} else {
|
|
||||||
split(b, b+1, b);
|
|
||||||
++b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
give_up:
|
|
||||||
while (b >= beziers) {
|
|
||||||
enum shift_result res = shift(b, o, normal_len, threshold);
|
|
||||||
|
|
||||||
/* if res isn't Ok or Split then *o is undefined */
|
|
||||||
if (res == Ok || res == Split)
|
|
||||||
++o;
|
|
||||||
|
|
||||||
--b;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug_assert(o - curves <= max_curves);
|
|
||||||
return o - curves;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bezier_bounds(const struct bezier *bez,
|
|
||||||
float *bounds/*x/y/width/height*/)
|
|
||||||
{
|
|
||||||
float xmin = bez->x1;
|
|
||||||
float xmax = bez->x1;
|
|
||||||
float ymin = bez->y1;
|
|
||||||
float ymax = bez->y1;
|
|
||||||
|
|
||||||
if (bez->x2 < xmin)
|
|
||||||
xmin = bez->x2;
|
|
||||||
else if (bez->x2 > xmax)
|
|
||||||
xmax = bez->x2;
|
|
||||||
if (bez->x3 < xmin)
|
|
||||||
xmin = bez->x3;
|
|
||||||
else if (bez->x3 > xmax)
|
|
||||||
xmax = bez->x3;
|
|
||||||
if (bez->x4 < xmin)
|
|
||||||
xmin = bez->x4;
|
|
||||||
else if (bez->x4 > xmax)
|
|
||||||
xmax = bez->x4;
|
|
||||||
|
|
||||||
if (bez->y2 < ymin)
|
|
||||||
ymin = bez->y2;
|
|
||||||
else if (bez->y2 > ymax)
|
|
||||||
ymax = bez->y2;
|
|
||||||
if (bez->y3 < ymin)
|
|
||||||
ymin = bez->y3;
|
|
||||||
else if (bez->y3 > ymax)
|
|
||||||
ymax = bez->y3;
|
|
||||||
if (bez->y4 < ymin)
|
|
||||||
ymin = bez->y4;
|
|
||||||
else if (bez->y4 > ymax)
|
|
||||||
ymax = bez->y4;
|
|
||||||
|
|
||||||
bounds[0] = xmin; /* x */
|
|
||||||
bounds[1] = ymin; /* y */
|
|
||||||
bounds[2] = xmax - xmin; /* width */
|
|
||||||
bounds[3] = ymax - ymin; /* height */
|
|
||||||
}
|
|
||||||
|
|
||||||
void bezier_start_tangent(const struct bezier *bez,
|
|
||||||
float *tangent)
|
|
||||||
{
|
|
||||||
tangent[0] = bez->x1;
|
|
||||||
tangent[1] = bez->y1;
|
|
||||||
tangent[2] = bez->x2;
|
|
||||||
tangent[3] = bez->y2;
|
|
||||||
|
|
||||||
if (null_line(tangent)) {
|
|
||||||
tangent[0] = bez->x1;
|
|
||||||
tangent[1] = bez->y1;
|
|
||||||
tangent[2] = bez->x3;
|
|
||||||
tangent[3] = bez->y3;
|
|
||||||
}
|
|
||||||
if (null_line(tangent)) {
|
|
||||||
tangent[0] = bez->x1;
|
|
||||||
tangent[1] = bez->y1;
|
|
||||||
tangent[2] = bez->x4;
|
|
||||||
tangent[3] = bez->y4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE VGfloat bezier_t_at_length(struct bezier *bez,
|
|
||||||
VGfloat at_length,
|
|
||||||
VGfloat error)
|
|
||||||
{
|
|
||||||
VGfloat len = bezier_length(bez, error);
|
|
||||||
VGfloat t = 1.0;
|
|
||||||
VGfloat last_bigger = 1.;
|
|
||||||
|
|
||||||
if (at_length > len || floatsEqual(at_length, len))
|
|
||||||
return t;
|
|
||||||
|
|
||||||
if (floatIsZero(at_length))
|
|
||||||
return 0.f;
|
|
||||||
|
|
||||||
t *= 0.5;
|
|
||||||
while (1) {
|
|
||||||
struct bezier right = *bez;
|
|
||||||
struct bezier left;
|
|
||||||
VGfloat tmp_len;
|
|
||||||
split_left(&right, t, &left);
|
|
||||||
tmp_len = bezier_length(&left, error);
|
|
||||||
if (ABS(tmp_len - at_length) < error)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (tmp_len < at_length) {
|
|
||||||
t += (last_bigger - t)*.5;
|
|
||||||
} else {
|
|
||||||
last_bigger = t;
|
|
||||||
t -= t*.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bezier_point_at_length(struct bezier *bez,
|
|
||||||
float length,
|
|
||||||
float *point,
|
|
||||||
float *normal)
|
|
||||||
{
|
|
||||||
/* ~0.000001 seems to be required to pass G2080x tests */
|
|
||||||
VGfloat t = bezier_t_at_length(bez, length, 0.000001);
|
|
||||||
bezier_point_at(bez, t, point);
|
|
||||||
bezier_normal_at(bez, t, normal);
|
|
||||||
vector_unit(normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bezier_point_at_t(struct bezier *bez, float t,
|
|
||||||
float *point, float *normal)
|
|
||||||
{
|
|
||||||
bezier_point_at(bez, t, point);
|
|
||||||
bezier_normal_at(bez, t, normal);
|
|
||||||
vector_unit(normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bezier_exact_bounds(const struct bezier *bez,
|
|
||||||
float *bounds/*x/y/width/height*/)
|
|
||||||
{
|
|
||||||
struct polygon *poly = polygon_create(64);
|
|
||||||
polygon_vertex_append(poly, bez->x1, bez->y1);
|
|
||||||
bezier_add_to_polygon(bez, poly);
|
|
||||||
polygon_bounding_rect(poly, bounds);
|
|
||||||
polygon_destroy(poly);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef BEZIER_H
|
|
||||||
#define BEZIER_H
|
|
||||||
|
|
||||||
struct polygon;
|
|
||||||
struct matrix;
|
|
||||||
|
|
||||||
struct bezier {
|
|
||||||
float x1, y1;
|
|
||||||
float x2, y2;
|
|
||||||
float x3, y3;
|
|
||||||
float x4, y4;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define BEZIER_DEFAULT_ERROR 0.01
|
|
||||||
|
|
||||||
/* kappa as being l of a circle with r = 1, we can emulate any
|
|
||||||
* circle of radius r by using the formula
|
|
||||||
* l = r . kappa
|
|
||||||
* More at:
|
|
||||||
* http://www.whizkidtech.redprince.net/bezier/circle/ */
|
|
||||||
#define KAPPA 0.5522847498
|
|
||||||
|
|
||||||
void bezier_init(struct bezier *bez,
|
|
||||||
float x1, float y1,
|
|
||||||
float x2, float y2,
|
|
||||||
float x3, float y3,
|
|
||||||
float x4, float y4);
|
|
||||||
|
|
||||||
struct polygon *bezier_to_polygon(struct bezier *bez);
|
|
||||||
void bezier_add_to_polygon(const struct bezier *bez,
|
|
||||||
struct polygon *poly);
|
|
||||||
float bezier_length(struct bezier *bez, float error);
|
|
||||||
void bezier_transform(struct bezier *bez,
|
|
||||||
struct matrix *mat);
|
|
||||||
|
|
||||||
int bezier_translate_by_normal(struct bezier *b,
|
|
||||||
struct bezier *curves,
|
|
||||||
int max_curves,
|
|
||||||
float normal_len,
|
|
||||||
float threshold);
|
|
||||||
void bezier_bounds(const struct bezier *bez,
|
|
||||||
float *bounds/*x/y/width/height*/);
|
|
||||||
void bezier_exact_bounds(const struct bezier *bez,
|
|
||||||
float *bounds/*x/y/width/height*/);
|
|
||||||
|
|
||||||
void bezier_start_tangent(const struct bezier *bez,
|
|
||||||
float *tangent);
|
|
||||||
|
|
||||||
void bezier_point_at_length(struct bezier *bez, float length,
|
|
||||||
float *point, float *normal);
|
|
||||||
void bezier_point_at_t(struct bezier *bez, float t,
|
|
||||||
float *point, float *normal);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2010 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#include "handle.h"
|
|
||||||
#include "util/u_hash.h"
|
|
||||||
#include "util/u_hash_table.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hash keys are 32-bit VGHandles
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct util_hash_table *handle_hash = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned next_handle = 1;
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned
|
|
||||||
hash_func(void *key)
|
|
||||||
{
|
|
||||||
/* XXX this kind of ugly */
|
|
||||||
intptr_t ip = pointer_to_intptr(key);
|
|
||||||
return (unsigned) (ip & 0xffffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
compare(void *key1, void *key2)
|
|
||||||
{
|
|
||||||
if (key1 < key2)
|
|
||||||
return -1;
|
|
||||||
else if (key1 > key2)
|
|
||||||
return +1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
init_handles(void)
|
|
||||||
{
|
|
||||||
if (!handle_hash)
|
|
||||||
handle_hash = util_hash_table_create(hash_func, compare);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
free_handles(void)
|
|
||||||
{
|
|
||||||
/* XXX destroy */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VGHandle
|
|
||||||
create_handle(void *object)
|
|
||||||
{
|
|
||||||
VGHandle h = next_handle++;
|
|
||||||
util_hash_table_set(handle_hash, intptr_to_pointer(h), object);
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
destroy_handle(VGHandle h)
|
|
||||||
{
|
|
||||||
util_hash_table_remove(handle_hash, intptr_to_pointer(h));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,172 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2010 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert opaque VG object handles into pointers and vice versa.
|
|
||||||
* XXX This is not yet 64-bit safe! All VG handles are 32 bits in size.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef HANDLE_H
|
|
||||||
#define HANDLE_H
|
|
||||||
|
|
||||||
#include "pipe/p_compiler.h"
|
|
||||||
#include "util/u_debug.h"
|
|
||||||
#include "util/u_hash_table.h"
|
|
||||||
#include "util/u_pointer.h"
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
#include "vg_context.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern struct util_hash_table *handle_hash;
|
|
||||||
|
|
||||||
|
|
||||||
struct vg_mask_layer;
|
|
||||||
struct vg_font;
|
|
||||||
struct vg_image;
|
|
||||||
struct vg_paint;
|
|
||||||
struct path;
|
|
||||||
|
|
||||||
|
|
||||||
extern void
|
|
||||||
init_handles(void);
|
|
||||||
|
|
||||||
|
|
||||||
extern void
|
|
||||||
free_handles(void);
|
|
||||||
|
|
||||||
|
|
||||||
extern VGHandle
|
|
||||||
create_handle(void *object);
|
|
||||||
|
|
||||||
|
|
||||||
extern void
|
|
||||||
destroy_handle(VGHandle h);
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE VGHandle
|
|
||||||
object_to_handle(struct vg_object *obj)
|
|
||||||
{
|
|
||||||
return obj ? obj->handle : VG_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE VGHandle
|
|
||||||
image_to_handle(struct vg_image *img)
|
|
||||||
{
|
|
||||||
/* vg_image is derived from vg_object */
|
|
||||||
return object_to_handle((struct vg_object *) img);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE VGHandle
|
|
||||||
masklayer_to_handle(struct vg_mask_layer *mask)
|
|
||||||
{
|
|
||||||
/* vg_object is derived from vg_object */
|
|
||||||
return object_to_handle((struct vg_object *) mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE VGHandle
|
|
||||||
font_to_handle(struct vg_font *font)
|
|
||||||
{
|
|
||||||
return object_to_handle((struct vg_object *) font);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE VGHandle
|
|
||||||
paint_to_handle(struct vg_paint *paint)
|
|
||||||
{
|
|
||||||
return object_to_handle((struct vg_object *) paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE VGHandle
|
|
||||||
path_to_handle(struct path *path)
|
|
||||||
{
|
|
||||||
return object_to_handle((struct vg_object *) path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void *
|
|
||||||
handle_to_pointer(VGHandle h)
|
|
||||||
{
|
|
||||||
void *v = util_hash_table_get(handle_hash, intptr_to_pointer(h));
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (v) {
|
|
||||||
struct vg_object *obj = (struct vg_object *) v;
|
|
||||||
assert(obj->handle == h);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE struct vg_font *
|
|
||||||
handle_to_font(VGHandle h)
|
|
||||||
{
|
|
||||||
return (struct vg_font *) handle_to_pointer(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE struct vg_image *
|
|
||||||
handle_to_image(VGHandle h)
|
|
||||||
{
|
|
||||||
return (struct vg_image *) handle_to_pointer(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE struct vg_mask_layer *
|
|
||||||
handle_to_masklayer(VGHandle h)
|
|
||||||
{
|
|
||||||
return (struct vg_mask_layer *) handle_to_pointer(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE struct vg_object *
|
|
||||||
handle_to_object(VGHandle h)
|
|
||||||
{
|
|
||||||
return (struct vg_object *) handle_to_pointer(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE struct vg_paint *
|
|
||||||
handle_to_paint(VGHandle h)
|
|
||||||
{
|
|
||||||
return (struct vg_paint *) handle_to_pointer(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE struct path *
|
|
||||||
handle_to_path(VGHandle h)
|
|
||||||
{
|
|
||||||
return (struct path *) handle_to_pointer(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* HANDLE_H */
|
|
||||||
|
|
@ -1,653 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "image.h"
|
|
||||||
|
|
||||||
#include "vg_translate.h"
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "matrix.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
#include "util_array.h"
|
|
||||||
#include "api_consts.h"
|
|
||||||
#include "shader.h"
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_screen.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "util/u_format.h"
|
|
||||||
#include "util/u_tile.h"
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
#include "util/u_sampler.h"
|
|
||||||
#include "util/u_surface.h"
|
|
||||||
|
|
||||||
static enum pipe_format vg_format_to_pipe(VGImageFormat format)
|
|
||||||
{
|
|
||||||
switch(format) {
|
|
||||||
case VG_sRGB_565:
|
|
||||||
return PIPE_FORMAT_B5G6R5_UNORM;
|
|
||||||
case VG_sRGBA_5551:
|
|
||||||
return PIPE_FORMAT_B5G5R5A1_UNORM;
|
|
||||||
case VG_sRGBA_4444:
|
|
||||||
return PIPE_FORMAT_B4G4R4A4_UNORM;
|
|
||||||
case VG_sL_8:
|
|
||||||
case VG_lL_8:
|
|
||||||
return PIPE_FORMAT_L8_UNORM;
|
|
||||||
case VG_BW_1:
|
|
||||||
return PIPE_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
case VG_A_8:
|
|
||||||
return PIPE_FORMAT_A8_UNORM;
|
|
||||||
#ifdef OPENVG_VERSION_1_1
|
|
||||||
case VG_A_1:
|
|
||||||
case VG_A_4:
|
|
||||||
return PIPE_FORMAT_A8_UNORM;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return PIPE_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void vg_sync_size(VGfloat *src_loc, VGfloat *dst_loc)
|
|
||||||
{
|
|
||||||
src_loc[2] = MIN2(src_loc[2], dst_loc[2]);
|
|
||||||
src_loc[3] = MIN2(src_loc[3], dst_loc[3]);
|
|
||||||
dst_loc[2] = src_loc[2];
|
|
||||||
dst_loc[3] = src_loc[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vg_get_copy_coords(VGfloat *src_loc,
|
|
||||||
VGfloat src_width, VGfloat src_height,
|
|
||||||
VGfloat *dst_loc,
|
|
||||||
VGfloat dst_width, VGfloat dst_height)
|
|
||||||
{
|
|
||||||
VGfloat dst_bounds[4], src_bounds[4];
|
|
||||||
VGfloat src_shift[4], dst_shift[4], shift[4];
|
|
||||||
|
|
||||||
dst_bounds[0] = 0.f;
|
|
||||||
dst_bounds[1] = 0.f;
|
|
||||||
dst_bounds[2] = dst_width;
|
|
||||||
dst_bounds[3] = dst_height;
|
|
||||||
|
|
||||||
src_bounds[0] = 0.f;
|
|
||||||
src_bounds[1] = 0.f;
|
|
||||||
src_bounds[2] = src_width;
|
|
||||||
src_bounds[3] = src_height;
|
|
||||||
|
|
||||||
vg_bound_rect(src_loc, src_bounds, src_shift);
|
|
||||||
vg_bound_rect(dst_loc, dst_bounds, dst_shift);
|
|
||||||
shift[0] = src_shift[0] - dst_shift[0];
|
|
||||||
shift[1] = src_shift[1] - dst_shift[1];
|
|
||||||
|
|
||||||
if (shift[0] < 0)
|
|
||||||
vg_shift_rectx(src_loc, src_bounds, -shift[0]);
|
|
||||||
else
|
|
||||||
vg_shift_rectx(dst_loc, dst_bounds, shift[0]);
|
|
||||||
|
|
||||||
if (shift[1] < 0)
|
|
||||||
vg_shift_recty(src_loc, src_bounds, -shift[1]);
|
|
||||||
else
|
|
||||||
vg_shift_recty(dst_loc, dst_bounds, shift[1]);
|
|
||||||
|
|
||||||
vg_sync_size(src_loc, dst_loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vg_copy_texture(struct vg_context *ctx,
|
|
||||||
struct pipe_resource *dst, VGint dx, VGint dy,
|
|
||||||
struct pipe_sampler_view *src, VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
VGfloat dst_loc[4], src_loc[4];
|
|
||||||
|
|
||||||
dst_loc[0] = dx;
|
|
||||||
dst_loc[1] = dy;
|
|
||||||
dst_loc[2] = width;
|
|
||||||
dst_loc[3] = height;
|
|
||||||
|
|
||||||
src_loc[0] = sx;
|
|
||||||
src_loc[1] = sy;
|
|
||||||
src_loc[2] = width;
|
|
||||||
src_loc[3] = height;
|
|
||||||
|
|
||||||
vg_get_copy_coords(src_loc, src->texture->width0, src->texture->height0,
|
|
||||||
dst_loc, dst->width0, dst->height0);
|
|
||||||
|
|
||||||
if (src_loc[2] >= 0 && src_loc[3] >= 0 &&
|
|
||||||
dst_loc[2] >= 0 && dst_loc[3] >= 0) {
|
|
||||||
struct pipe_surface *surf, surf_tmpl;
|
|
||||||
|
|
||||||
/* get the destination surface */
|
|
||||||
u_surface_default_template(&surf_tmpl, dst);
|
|
||||||
surf = ctx->pipe->create_surface(ctx->pipe, dst, &surf_tmpl);
|
|
||||||
if (surf && renderer_copy_begin(ctx->renderer, surf, VG_TRUE, src)) {
|
|
||||||
renderer_copy(ctx->renderer,
|
|
||||||
dst_loc[0], dst_loc[1], dst_loc[2], dst_loc[3],
|
|
||||||
src_loc[0], src_loc[1], src_loc[2], src_loc[3]);
|
|
||||||
renderer_copy_end(ctx->renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe_surface_reference(&surf, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vg_copy_surface(struct vg_context *ctx,
|
|
||||||
struct pipe_surface *dst, VGint dx, VGint dy,
|
|
||||||
struct pipe_surface *src, VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
VGfloat dst_loc[4], src_loc[4];
|
|
||||||
|
|
||||||
dst_loc[0] = dx;
|
|
||||||
dst_loc[1] = dy;
|
|
||||||
dst_loc[2] = width;
|
|
||||||
dst_loc[3] = height;
|
|
||||||
|
|
||||||
src_loc[0] = sx;
|
|
||||||
src_loc[1] = sy;
|
|
||||||
src_loc[2] = width;
|
|
||||||
src_loc[3] = height;
|
|
||||||
|
|
||||||
vg_get_copy_coords(src_loc, src->width, src->height,
|
|
||||||
dst_loc, dst->width, dst->height);
|
|
||||||
|
|
||||||
if (src_loc[2] > 0 && src_loc[3] > 0 &&
|
|
||||||
dst_loc[2] > 0 && dst_loc[3] > 0) {
|
|
||||||
if (src == dst)
|
|
||||||
renderer_copy_surface(ctx->renderer,
|
|
||||||
src,
|
|
||||||
src_loc[0],
|
|
||||||
src->height - (src_loc[1] + src_loc[3]),
|
|
||||||
src_loc[0] + src_loc[2],
|
|
||||||
src->height - src_loc[1],
|
|
||||||
dst,
|
|
||||||
dst_loc[0],
|
|
||||||
dst->height - (dst_loc[1] + dst_loc[3]),
|
|
||||||
dst_loc[0] + dst_loc[2],
|
|
||||||
dst->height - dst_loc[1],
|
|
||||||
0, 0);
|
|
||||||
else
|
|
||||||
renderer_copy_surface(ctx->renderer,
|
|
||||||
src,
|
|
||||||
src_loc[0],
|
|
||||||
src->height - src_loc[1],
|
|
||||||
src_loc[0] + src_loc[2],
|
|
||||||
src->height - (src_loc[1] + src_loc[3]),
|
|
||||||
dst,
|
|
||||||
dst_loc[0],
|
|
||||||
dst->height - (dst_loc[1] + dst_loc[3]),
|
|
||||||
dst_loc[0] + dst_loc[2],
|
|
||||||
dst->height - dst_loc[1],
|
|
||||||
0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_resource *image_texture(struct vg_image *img)
|
|
||||||
{
|
|
||||||
struct pipe_resource *tex = img->sampler_view->texture;
|
|
||||||
return tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void image_cleari(struct vg_image *img, VGint clear_colori,
|
|
||||||
VGint x, VGint y, VGint width, VGint height)
|
|
||||||
{
|
|
||||||
VGint *clearbuf;
|
|
||||||
VGint i;
|
|
||||||
VGfloat dwidth, dheight;
|
|
||||||
|
|
||||||
clearbuf = malloc(sizeof(VGint)*width*height);
|
|
||||||
for (i = 0; i < width*height; ++i)
|
|
||||||
clearbuf[i] = clear_colori;
|
|
||||||
|
|
||||||
dwidth = MIN2(width, img->width);
|
|
||||||
dheight = MIN2(height, img->height);
|
|
||||||
|
|
||||||
image_sub_data(img, clearbuf, width * sizeof(VGint),
|
|
||||||
VG_sRGBA_8888,
|
|
||||||
x, y, dwidth, dheight);
|
|
||||||
free(clearbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vg_image * image_create(VGImageFormat format,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct vg_image *image = CALLOC_STRUCT(vg_image);
|
|
||||||
enum pipe_format pformat = vg_format_to_pipe(format);
|
|
||||||
struct pipe_resource pt, *newtex;
|
|
||||||
struct pipe_sampler_view view_templ;
|
|
||||||
struct pipe_sampler_view *view;
|
|
||||||
struct pipe_screen *screen = ctx->pipe->screen;
|
|
||||||
|
|
||||||
vg_init_object(&image->base, ctx, VG_OBJECT_IMAGE);
|
|
||||||
|
|
||||||
image->format = format;
|
|
||||||
image->width = width;
|
|
||||||
image->height = height;
|
|
||||||
|
|
||||||
image->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
image->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
image->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
image->sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
|
||||||
image->sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
|
||||||
image->sampler.normalized_coords = 1;
|
|
||||||
|
|
||||||
assert(screen->is_format_supported(screen, pformat, PIPE_TEXTURE_2D,
|
|
||||||
0, PIPE_BIND_SAMPLER_VIEW));
|
|
||||||
|
|
||||||
memset(&pt, 0, sizeof(pt));
|
|
||||||
pt.target = PIPE_TEXTURE_2D;
|
|
||||||
pt.format = pformat;
|
|
||||||
pt.last_level = 0;
|
|
||||||
pt.width0 = width;
|
|
||||||
pt.height0 = height;
|
|
||||||
pt.depth0 = 1;
|
|
||||||
pt.array_size = 1;
|
|
||||||
pt.bind = PIPE_BIND_SAMPLER_VIEW;
|
|
||||||
|
|
||||||
newtex = screen->resource_create(screen, &pt);
|
|
||||||
|
|
||||||
debug_assert(newtex);
|
|
||||||
|
|
||||||
u_sampler_view_default_template(&view_templ, newtex, newtex->format);
|
|
||||||
/* R, G, and B are treated as 1.0 for alpha-only formats in OpenVG */
|
|
||||||
if (newtex->format == PIPE_FORMAT_A8_UNORM) {
|
|
||||||
view_templ.swizzle_r = PIPE_SWIZZLE_ONE;
|
|
||||||
view_templ.swizzle_g = PIPE_SWIZZLE_ONE;
|
|
||||||
view_templ.swizzle_b = PIPE_SWIZZLE_ONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
view = pipe->create_sampler_view(pipe, newtex, &view_templ);
|
|
||||||
/* want the texture to go away if the view is freed */
|
|
||||||
pipe_resource_reference(&newtex, NULL);
|
|
||||||
|
|
||||||
image->sampler_view = view;
|
|
||||||
|
|
||||||
vg_context_add_object(ctx, &image->base);
|
|
||||||
|
|
||||||
image_cleari(image, 0, 0, 0, image->width, image->height);
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
void image_destroy(struct vg_image *img)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
vg_context_remove_object(ctx, &img->base);
|
|
||||||
|
|
||||||
|
|
||||||
if (img->parent) {
|
|
||||||
/* remove img from the parent child array */
|
|
||||||
int idx;
|
|
||||||
struct vg_image **array =
|
|
||||||
(struct vg_image **)img->parent->children_array->data;
|
|
||||||
|
|
||||||
for (idx = 0; idx < img->parent->children_array->num_elements; ++idx) {
|
|
||||||
struct vg_image *child = array[idx];
|
|
||||||
if (child == img) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug_assert(idx < img->parent->children_array->num_elements);
|
|
||||||
array_remove_element(img->parent->children_array, idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (img->children_array && img->children_array->num_elements) {
|
|
||||||
/* reparent the children */
|
|
||||||
VGint i;
|
|
||||||
struct vg_image *parent = img->parent;
|
|
||||||
struct vg_image **children =
|
|
||||||
(struct vg_image **)img->children_array->data;
|
|
||||||
if (!parent) {
|
|
||||||
VGint min_x = children[0]->x;
|
|
||||||
parent = children[0];
|
|
||||||
|
|
||||||
for (i = 1; i < img->children_array->num_elements; ++i) {
|
|
||||||
struct vg_image *child = children[i];
|
|
||||||
if (child->x < min_x) {
|
|
||||||
parent = child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < img->children_array->num_elements; ++i) {
|
|
||||||
struct vg_image *child = children[i];
|
|
||||||
if (child != parent) {
|
|
||||||
child->parent = parent;
|
|
||||||
if (!parent->children_array) {
|
|
||||||
parent->children_array = array_create(
|
|
||||||
sizeof(struct vg_image*));
|
|
||||||
}
|
|
||||||
array_append_data(parent->children_array,
|
|
||||||
&child, 1);
|
|
||||||
} else
|
|
||||||
child->parent = NULL;
|
|
||||||
}
|
|
||||||
array_destroy(img->children_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_free_object(&img->base);
|
|
||||||
|
|
||||||
pipe_sampler_view_reference(&img->sampler_view, NULL);
|
|
||||||
FREE(img);
|
|
||||||
}
|
|
||||||
|
|
||||||
void image_clear(struct vg_image *img,
|
|
||||||
VGint x, VGint y, VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
VGfloat *clear_colorf = ctx->state.vg.clear_color;
|
|
||||||
VGubyte r, g, b ,a;
|
|
||||||
VGint clear_colori;
|
|
||||||
/* FIXME: this is very nasty */
|
|
||||||
r = float_to_ubyte(clear_colorf[0]);
|
|
||||||
g = float_to_ubyte(clear_colorf[1]);
|
|
||||||
b = float_to_ubyte(clear_colorf[2]);
|
|
||||||
a = float_to_ubyte(clear_colorf[3]);
|
|
||||||
clear_colori = r << 24 | g << 16 | b << 8 | a;
|
|
||||||
image_cleari(img, clear_colori, x, y, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void image_sub_data(struct vg_image *image,
|
|
||||||
const void * data,
|
|
||||||
VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
const VGint yStep = 1;
|
|
||||||
VGubyte *src = (VGubyte *)data;
|
|
||||||
VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
|
|
||||||
VGfloat *df = (VGfloat*)temp;
|
|
||||||
VGint i;
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct pipe_resource *texture = image_texture(image);
|
|
||||||
VGint xoffset = 0, yoffset = 0;
|
|
||||||
|
|
||||||
if (x < 0) {
|
|
||||||
xoffset -= x;
|
|
||||||
width += x;
|
|
||||||
x = 0;
|
|
||||||
}
|
|
||||||
if (y < 0) {
|
|
||||||
yoffset -= y;
|
|
||||||
height += y;
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x > image->width || y > image->width) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x + width > image->width) {
|
|
||||||
width = image->width - x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y + height > image->height) {
|
|
||||||
height = image->height - y;
|
|
||||||
}
|
|
||||||
|
|
||||||
{ /* upload color_data */
|
|
||||||
struct pipe_transfer *transfer;
|
|
||||||
void *map = pipe_transfer_map(pipe, texture, 0, 0,
|
|
||||||
PIPE_TRANSFER_WRITE, 0, 0,
|
|
||||||
texture->width0, texture->height0,
|
|
||||||
&transfer);
|
|
||||||
src += (dataStride * yoffset);
|
|
||||||
for (i = 0; i < height; i++) {
|
|
||||||
_vega_unpack_float_span_rgba(ctx, width, xoffset, src, dataFormat, temp);
|
|
||||||
pipe_put_tile_rgba(transfer, map, x+image->x, y+image->y, width, 1, df);
|
|
||||||
y += yStep;
|
|
||||||
src += dataStride;
|
|
||||||
}
|
|
||||||
pipe->transfer_unmap(pipe, transfer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void image_get_sub_data(struct vg_image * image,
|
|
||||||
void * data,
|
|
||||||
VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
|
|
||||||
VGfloat *df = (VGfloat*)temp;
|
|
||||||
VGint y = 0, yStep = 1;
|
|
||||||
VGint i;
|
|
||||||
VGubyte *dst = (VGubyte *)data;
|
|
||||||
|
|
||||||
{
|
|
||||||
struct pipe_transfer *transfer;
|
|
||||||
void *map =
|
|
||||||
pipe_transfer_map(pipe,
|
|
||||||
image->sampler_view->texture, 0, 0,
|
|
||||||
PIPE_TRANSFER_READ,
|
|
||||||
0, 0,
|
|
||||||
image->x + image->width,
|
|
||||||
image->y + image->height, &transfer);
|
|
||||||
/* Do a row at a time to flip image data vertically */
|
|
||||||
for (i = 0; i < height; i++) {
|
|
||||||
#if 0
|
|
||||||
debug_printf("%d-%d == %d\n", sy, height, y);
|
|
||||||
#endif
|
|
||||||
pipe_get_tile_rgba(transfer, map, sx+image->x, y, width, 1, df);
|
|
||||||
y += yStep;
|
|
||||||
_vega_pack_rgba_span_float(ctx, width, temp, dataFormat, dst);
|
|
||||||
dst += dataStride;
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe->transfer_unmap(pipe, transfer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vg_image * image_child_image(struct vg_image *parent,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_image *image = CALLOC_STRUCT(vg_image);
|
|
||||||
|
|
||||||
vg_init_object(&image->base, ctx, VG_OBJECT_IMAGE);
|
|
||||||
|
|
||||||
image->x = parent->x + x;
|
|
||||||
image->y = parent->y + y;
|
|
||||||
image->width = width;
|
|
||||||
image->height = height;
|
|
||||||
image->parent = parent;
|
|
||||||
image->sampler_view = NULL;
|
|
||||||
pipe_sampler_view_reference(&image->sampler_view,
|
|
||||||
parent->sampler_view);
|
|
||||||
|
|
||||||
image->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
image->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
image->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
image->sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
|
||||||
image->sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
|
||||||
image->sampler.normalized_coords = 1;
|
|
||||||
|
|
||||||
if (!parent->children_array)
|
|
||||||
parent->children_array = array_create(
|
|
||||||
sizeof(struct vg_image*));
|
|
||||||
|
|
||||||
array_append_data(parent->children_array,
|
|
||||||
&image, 1);
|
|
||||||
|
|
||||||
vg_context_add_object(ctx, &image->base);
|
|
||||||
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
void image_copy(struct vg_image *dst, VGint dx, VGint dy,
|
|
||||||
struct vg_image *src, VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height,
|
|
||||||
VGboolean dither)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
vg_copy_texture(ctx, dst->sampler_view->texture, dst->x + dx, dst->y + dy,
|
|
||||||
src->sampler_view, src->x + sx, src->y + sy, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void image_draw(struct vg_image *img, struct matrix *matrix)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct matrix paint_matrix;
|
|
||||||
VGfloat x1, y1;
|
|
||||||
VGfloat x2, y2;
|
|
||||||
VGfloat x3, y3;
|
|
||||||
VGfloat x4, y4;
|
|
||||||
|
|
||||||
if (!vg_get_paint_matrix(ctx,
|
|
||||||
&ctx->state.vg.fill_paint_to_user_matrix,
|
|
||||||
matrix,
|
|
||||||
&paint_matrix))
|
|
||||||
return;
|
|
||||||
|
|
||||||
x1 = 0;
|
|
||||||
y1 = 0;
|
|
||||||
x2 = img->width;
|
|
||||||
y2 = 0;
|
|
||||||
x3 = img->width;
|
|
||||||
y3 = img->height;
|
|
||||||
x4 = 0;
|
|
||||||
y4 = img->height;
|
|
||||||
|
|
||||||
shader_set_surface_matrix(ctx->shader, matrix);
|
|
||||||
shader_set_drawing_image(ctx->shader, VG_TRUE);
|
|
||||||
shader_set_paint(ctx->shader, ctx->state.vg.fill_paint);
|
|
||||||
shader_set_paint_matrix(ctx->shader, &paint_matrix);
|
|
||||||
shader_set_image(ctx->shader, img);
|
|
||||||
shader_bind(ctx->shader);
|
|
||||||
|
|
||||||
renderer_texture_quad(ctx->renderer, image_texture(img),
|
|
||||||
img->x, img->y, img->x + img->width, img->y + img->height,
|
|
||||||
x1, y1, x2, y2, x3, y3, x4, y4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void image_set_pixels(VGint dx, VGint dy,
|
|
||||||
struct vg_image *src, VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct pipe_surface *surf, surf_tmpl;
|
|
||||||
struct st_renderbuffer *strb = ctx->draw_buffer->strb;
|
|
||||||
|
|
||||||
u_surface_default_template(&surf_tmpl, image_texture(src));
|
|
||||||
surf = pipe->create_surface(pipe, image_texture(src), &surf_tmpl);
|
|
||||||
|
|
||||||
vg_copy_surface(ctx, strb->surface, dx, dy,
|
|
||||||
surf, sx+src->x, sy+src->y, width, height);
|
|
||||||
|
|
||||||
pipe->surface_destroy(pipe, surf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct pipe_surface *surf, surf_tmpl;
|
|
||||||
struct st_renderbuffer *strb = ctx->draw_buffer->strb;
|
|
||||||
|
|
||||||
/* flip the y coordinates */
|
|
||||||
/*dy = dst->height - dy - height;*/
|
|
||||||
|
|
||||||
u_surface_default_template(&surf_tmpl, image_texture(dst));
|
|
||||||
surf = pipe->create_surface(pipe, image_texture(dst), &surf_tmpl);
|
|
||||||
|
|
||||||
vg_copy_surface(ctx, surf, dst->x + dx, dst->y + dy,
|
|
||||||
strb->surface, sx, sy, width, height);
|
|
||||||
|
|
||||||
pipe_surface_reference(&surf, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VGboolean vg_image_overlaps(struct vg_image *dst,
|
|
||||||
struct vg_image *src)
|
|
||||||
{
|
|
||||||
if (dst == src || dst->parent == src ||
|
|
||||||
dst == src->parent)
|
|
||||||
return VG_TRUE;
|
|
||||||
if (dst->parent && dst->parent == src->parent) {
|
|
||||||
VGfloat left1 = dst->x;
|
|
||||||
VGfloat left2 = src->x;
|
|
||||||
VGfloat right1 = dst->x + dst->width;
|
|
||||||
VGfloat right2 = src->x + src->width;
|
|
||||||
VGfloat bottom1 = dst->y;
|
|
||||||
VGfloat bottom2 = src->y;
|
|
||||||
VGfloat top1 = dst->y + dst->height;
|
|
||||||
VGfloat top2 = src->y + src->height;
|
|
||||||
|
|
||||||
return !(left2 > right1 || right2 < left1 ||
|
|
||||||
top2 > bottom1 || bottom2 < top1);
|
|
||||||
}
|
|
||||||
return VG_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGint image_bind_samplers(struct vg_image *img, struct pipe_sampler_state **samplers,
|
|
||||||
struct pipe_sampler_view **sampler_views)
|
|
||||||
{
|
|
||||||
img->sampler.min_img_filter = image_sampler_filter(img->base.ctx);
|
|
||||||
img->sampler.mag_img_filter = image_sampler_filter(img->base.ctx);
|
|
||||||
samplers[3] = &img->sampler;
|
|
||||||
sampler_views[3] = img->sampler_view;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGint image_sampler_filter(struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
switch(ctx->state.vg.image_quality) {
|
|
||||||
case VG_IMAGE_QUALITY_NONANTIALIASED:
|
|
||||||
return PIPE_TEX_FILTER_NEAREST;
|
|
||||||
break;
|
|
||||||
case VG_IMAGE_QUALITY_FASTER:
|
|
||||||
return PIPE_TEX_FILTER_NEAREST;
|
|
||||||
break;
|
|
||||||
case VG_IMAGE_QUALITY_BETTER:
|
|
||||||
/* possibly use anisotropic filtering */
|
|
||||||
return PIPE_TEX_FILTER_LINEAR;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
debug_printf("Unknown image quality");
|
|
||||||
}
|
|
||||||
return PIPE_TEX_FILTER_NEAREST;
|
|
||||||
}
|
|
||||||
|
|
@ -1,104 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef IMAGES_H
|
|
||||||
#define IMAGES_H
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
|
|
||||||
struct pipe_resource;
|
|
||||||
struct array;
|
|
||||||
struct vg_context;
|
|
||||||
struct pipe_surface;
|
|
||||||
|
|
||||||
struct vg_image {
|
|
||||||
struct vg_object base;
|
|
||||||
VGImageFormat format;
|
|
||||||
VGint x, y;
|
|
||||||
VGint width, height;
|
|
||||||
|
|
||||||
struct vg_image *parent;
|
|
||||||
|
|
||||||
struct pipe_sampler_view *sampler_view;
|
|
||||||
struct pipe_sampler_state sampler;
|
|
||||||
|
|
||||||
struct array *children_array;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vg_image *image_create(VGImageFormat format,
|
|
||||||
VGint width, VGint height);
|
|
||||||
void image_destroy(struct vg_image *img);
|
|
||||||
|
|
||||||
void image_clear(struct vg_image *img,
|
|
||||||
VGint x, VGint y, VGint width, VGint height);
|
|
||||||
|
|
||||||
void image_sub_data(struct vg_image *image,
|
|
||||||
const void * data,
|
|
||||||
VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height);
|
|
||||||
|
|
||||||
void image_get_sub_data(struct vg_image * image,
|
|
||||||
void * data,
|
|
||||||
VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height);
|
|
||||||
|
|
||||||
struct vg_image *image_child_image(struct vg_image *parent,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height);
|
|
||||||
|
|
||||||
void image_copy(struct vg_image *dst, VGint dx, VGint dy,
|
|
||||||
struct vg_image *src, VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height,
|
|
||||||
VGboolean dither);
|
|
||||||
|
|
||||||
void image_draw(struct vg_image *img, struct matrix *matrix);
|
|
||||||
|
|
||||||
void image_set_pixels(VGint dx, VGint dy,
|
|
||||||
struct vg_image *src, VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height);
|
|
||||||
void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height);
|
|
||||||
|
|
||||||
VGint image_bind_samplers(struct vg_image *dst, struct pipe_sampler_state **samplers,
|
|
||||||
struct pipe_sampler_view **sampler_views);
|
|
||||||
|
|
||||||
VGboolean vg_image_overlaps(struct vg_image *dst,
|
|
||||||
struct vg_image *src);
|
|
||||||
|
|
||||||
VGint image_sampler_filter(struct vg_context *ctx);
|
|
||||||
|
|
||||||
void vg_copy_surface(struct vg_context *ctx,
|
|
||||||
struct pipe_surface *dst, VGint dx, VGint dy,
|
|
||||||
struct pipe_surface *src, VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,523 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "mask.h"
|
|
||||||
|
|
||||||
#include "path.h"
|
|
||||||
#include "image.h"
|
|
||||||
#include "shaders_cache.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
#include "asm_util.h"
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_screen.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "util/u_format.h"
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
#include "util/u_surface.h"
|
|
||||||
#include "util/u_sampler.h"
|
|
||||||
|
|
||||||
struct vg_mask_layer {
|
|
||||||
struct vg_object base;
|
|
||||||
|
|
||||||
VGint width;
|
|
||||||
VGint height;
|
|
||||||
|
|
||||||
struct pipe_sampler_view *sampler_view;
|
|
||||||
};
|
|
||||||
|
|
||||||
static INLINE VGboolean
|
|
||||||
intersect_rectangles(VGint dwidth, VGint dheight,
|
|
||||||
VGint swidth, VGint sheight,
|
|
||||||
VGint tx, VGint ty,
|
|
||||||
VGint twidth, VGint theight,
|
|
||||||
VGint *offsets,
|
|
||||||
VGint *location)
|
|
||||||
{
|
|
||||||
if (tx + twidth <= 0 || tx >= dwidth)
|
|
||||||
return VG_FALSE;
|
|
||||||
if (ty + theight <= 0 || ty >= dheight)
|
|
||||||
return VG_FALSE;
|
|
||||||
|
|
||||||
offsets[0] = 0;
|
|
||||||
offsets[1] = 0;
|
|
||||||
location[0] = tx;
|
|
||||||
location[1] = ty;
|
|
||||||
|
|
||||||
if (tx < 0) {
|
|
||||||
offsets[0] -= tx;
|
|
||||||
location[0] = 0;
|
|
||||||
|
|
||||||
location[2] = MIN2(tx + swidth, MIN2(dwidth, tx + twidth));
|
|
||||||
offsets[2] = location[2];
|
|
||||||
} else {
|
|
||||||
offsets[2] = MIN2(twidth, MIN2(dwidth - tx, swidth ));
|
|
||||||
location[2] = offsets[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ty < 0) {
|
|
||||||
offsets[1] -= ty;
|
|
||||||
location[1] = 0;
|
|
||||||
|
|
||||||
location[3] = MIN2(ty + sheight, MIN2(dheight, ty + theight));
|
|
||||||
offsets[3] = location[3];
|
|
||||||
} else {
|
|
||||||
offsets[3] = MIN2(theight, MIN2(dheight - ty, sheight));
|
|
||||||
location[3] = offsets[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
return VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG_MASKS
|
|
||||||
static void read_alpha_mask(void * data, VGint dataStride,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
struct st_renderbuffer *strb = stfb->alpha_mask;
|
|
||||||
|
|
||||||
VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
|
|
||||||
VGfloat *df = (VGfloat*)temp;
|
|
||||||
VGint y = (stfb->height - sy) - 1, yStep = -1;
|
|
||||||
VGint i;
|
|
||||||
VGubyte *dst = (VGubyte *)data;
|
|
||||||
VGint xoffset = 0, yoffset = 0;
|
|
||||||
|
|
||||||
if (sx < 0) {
|
|
||||||
xoffset = -sx;
|
|
||||||
xoffset *= _vega_size_for_format(dataFormat);
|
|
||||||
width += sx;
|
|
||||||
sx = 0;
|
|
||||||
}
|
|
||||||
if (sy < 0) {
|
|
||||||
yoffset = -sy;
|
|
||||||
height += sy;
|
|
||||||
sy = 0;
|
|
||||||
y = (stfb->height - sy) - 1;
|
|
||||||
yoffset *= dataStride;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
struct pipe_surface *surf;
|
|
||||||
|
|
||||||
surf = pipe->create_surface(pipe, strb->texture, 0, 0, 0,
|
|
||||||
PIPE_BIND_TRANSFER_READ);
|
|
||||||
|
|
||||||
/* Do a row at a time to flip image data vertically */
|
|
||||||
for (i = 0; i < height; i++) {
|
|
||||||
#if 0
|
|
||||||
debug_printf("%d-%d == %d\n", sy, height, y);
|
|
||||||
#endif
|
|
||||||
pipe_get_tile_rgba(surf, sx, y, width, 1, df);
|
|
||||||
y += yStep;
|
|
||||||
_vega_pack_rgba_span_float(ctx, width, temp, dataFormat,
|
|
||||||
dst + yoffset + xoffset);
|
|
||||||
dst += dataStride;
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe_surface_reference(&surf, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void save_alpha_to_file(const char *filename)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
VGint *data;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
data = malloc(sizeof(int) * stfb->width * stfb->height);
|
|
||||||
read_alpha_mask(data, stfb->width * sizeof(int),
|
|
||||||
VG_sRGBA_8888,
|
|
||||||
0, 0, stfb->width, stfb->height);
|
|
||||||
fprintf(stderr, "/*---------- start */\n");
|
|
||||||
fprintf(stderr, "const int image_width = %d;\n",
|
|
||||||
stfb->width);
|
|
||||||
fprintf(stderr, "const int image_height = %d;\n",
|
|
||||||
stfb->height);
|
|
||||||
fprintf(stderr, "const int image_data = {\n");
|
|
||||||
for (i = 0; i < stfb->height; ++i) {
|
|
||||||
for (j = 0; j < stfb->width; ++j) {
|
|
||||||
int rgba = data[i * stfb->height + j];
|
|
||||||
int argb = 0;
|
|
||||||
argb = (rgba >> 8);
|
|
||||||
argb |= ((rgba & 0xff) << 24);
|
|
||||||
fprintf(stderr, "0x%x, ", argb);
|
|
||||||
}
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
|
||||||
fprintf(stderr, "};\n");
|
|
||||||
fprintf(stderr, "/*---------- end */\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* setup mask shader */
|
|
||||||
static void *setup_mask_operation(VGMaskOperation operation)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
void *shader = 0;
|
|
||||||
|
|
||||||
switch (operation) {
|
|
||||||
case VG_UNION_MASK: {
|
|
||||||
if (!ctx->mask.union_fs) {
|
|
||||||
ctx->mask.union_fs = shader_create_from_text(ctx->pipe,
|
|
||||||
union_mask_asm,
|
|
||||||
200,
|
|
||||||
PIPE_SHADER_FRAGMENT);
|
|
||||||
}
|
|
||||||
shader = ctx->mask.union_fs->driver;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VG_INTERSECT_MASK: {
|
|
||||||
if (!ctx->mask.intersect_fs) {
|
|
||||||
ctx->mask.intersect_fs = shader_create_from_text(ctx->pipe,
|
|
||||||
intersect_mask_asm,
|
|
||||||
200,
|
|
||||||
PIPE_SHADER_FRAGMENT);
|
|
||||||
}
|
|
||||||
shader = ctx->mask.intersect_fs->driver;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VG_SUBTRACT_MASK: {
|
|
||||||
if (!ctx->mask.subtract_fs) {
|
|
||||||
ctx->mask.subtract_fs = shader_create_from_text(ctx->pipe,
|
|
||||||
subtract_mask_asm,
|
|
||||||
200,
|
|
||||||
PIPE_SHADER_FRAGMENT);
|
|
||||||
}
|
|
||||||
shader = ctx->mask.subtract_fs->driver;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VG_SET_MASK: {
|
|
||||||
if (!ctx->mask.set_fs) {
|
|
||||||
ctx->mask.set_fs = shader_create_from_text(ctx->pipe,
|
|
||||||
set_mask_asm,
|
|
||||||
200,
|
|
||||||
PIPE_SHADER_FRAGMENT);
|
|
||||||
}
|
|
||||||
shader = ctx->mask.set_fs->driver;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mask_resource_fill(struct pipe_resource *dst,
|
|
||||||
int x, int y, int width, int height,
|
|
||||||
VGfloat coverage)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
VGfloat fs_consts[12] = {
|
|
||||||
0.0f, 0.0f, 0.0f, 0.0f, /* not used */
|
|
||||||
0.0f, 0.0f, 0.0f, 0.0f, /* not used */
|
|
||||||
0.0f, 0.0f, 0.0f, coverage /* color */
|
|
||||||
};
|
|
||||||
void *fs;
|
|
||||||
|
|
||||||
if (x < 0) {
|
|
||||||
width += x;
|
|
||||||
x = 0;
|
|
||||||
}
|
|
||||||
if (y < 0) {
|
|
||||||
height += y;
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fs = shaders_cache_fill(ctx->sc, VEGA_SOLID_FILL_SHADER);
|
|
||||||
|
|
||||||
if (renderer_filter_begin(ctx->renderer, dst, VG_FALSE, ~0,
|
|
||||||
NULL, NULL, 0, fs, (const void *) fs_consts, sizeof(fs_consts))) {
|
|
||||||
renderer_filter(ctx->renderer, x, y, width, height, 0, 0, 0, 0);
|
|
||||||
renderer_filter_end(ctx->renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG_MASKS
|
|
||||||
save_alpha_to_file(0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void mask_using_texture(struct pipe_sampler_view *sampler_view,
|
|
||||||
VGboolean is_layer,
|
|
||||||
VGMaskOperation operation,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_sampler_view *dst_view = vg_get_surface_mask(ctx);
|
|
||||||
struct pipe_resource *dst = dst_view->texture;
|
|
||||||
struct pipe_resource *texture = sampler_view->texture;
|
|
||||||
const struct pipe_sampler_state *samplers[2];
|
|
||||||
struct pipe_sampler_view *views[2];
|
|
||||||
struct pipe_sampler_state sampler;
|
|
||||||
VGint offsets[4], loc[4];
|
|
||||||
const VGfloat ones[4] = {1.f, 1.f, 1.f, 1.f};
|
|
||||||
void *fs;
|
|
||||||
|
|
||||||
if (!intersect_rectangles(dst->width0, dst->height0,
|
|
||||||
texture->width0, texture->height0,
|
|
||||||
x, y, width, height,
|
|
||||||
offsets, loc))
|
|
||||||
return;
|
|
||||||
#if 0
|
|
||||||
debug_printf("Offset = [%d, %d, %d, %d]\n", offsets[0],
|
|
||||||
offsets[1], offsets[2], offsets[3]);
|
|
||||||
debug_printf("Locati = [%d, %d, %d, %d]\n", loc[0],
|
|
||||||
loc[1], loc[2], loc[3]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
sampler = ctx->mask.sampler;
|
|
||||||
sampler.normalized_coords = 1;
|
|
||||||
samplers[0] = &sampler;
|
|
||||||
views[0] = sampler_view;
|
|
||||||
|
|
||||||
/* prepare our blend surface */
|
|
||||||
samplers[1] = &ctx->mask.sampler;
|
|
||||||
views[1] = vg_prepare_blend_surface_from_mask(ctx);
|
|
||||||
|
|
||||||
fs = setup_mask_operation(operation);
|
|
||||||
|
|
||||||
if (renderer_filter_begin(ctx->renderer, dst, VG_FALSE,
|
|
||||||
~0, samplers, views, 2, fs, (const void *) ones, sizeof(ones))) {
|
|
||||||
/* layer should be flipped when used as a texture */
|
|
||||||
if (is_layer) {
|
|
||||||
offsets[1] += offsets[3];
|
|
||||||
offsets[3] = -offsets[3];
|
|
||||||
}
|
|
||||||
renderer_filter(ctx->renderer,
|
|
||||||
loc[0], loc[1], loc[2], loc[3],
|
|
||||||
offsets[0], offsets[1], offsets[2], offsets[3]);
|
|
||||||
renderer_filter_end(ctx->renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef OPENVG_VERSION_1_1
|
|
||||||
|
|
||||||
struct vg_mask_layer * mask_layer_create(VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_mask_layer *mask = 0;
|
|
||||||
|
|
||||||
mask = CALLOC_STRUCT(vg_mask_layer);
|
|
||||||
vg_init_object(&mask->base, ctx, VG_OBJECT_MASK);
|
|
||||||
mask->width = width;
|
|
||||||
mask->height = height;
|
|
||||||
|
|
||||||
{
|
|
||||||
struct pipe_resource pt;
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct pipe_screen *screen = ctx->pipe->screen;
|
|
||||||
struct pipe_sampler_view view_templ;
|
|
||||||
struct pipe_sampler_view *view = NULL;
|
|
||||||
struct pipe_resource *texture;
|
|
||||||
|
|
||||||
memset(&pt, 0, sizeof(pt));
|
|
||||||
pt.target = PIPE_TEXTURE_2D;
|
|
||||||
pt.format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
pt.last_level = 0;
|
|
||||||
pt.width0 = width;
|
|
||||||
pt.height0 = height;
|
|
||||||
pt.depth0 = 1;
|
|
||||||
pt.array_size = 1;
|
|
||||||
pt.bind = PIPE_BIND_SAMPLER_VIEW;
|
|
||||||
|
|
||||||
texture = screen->resource_create(screen, &pt);
|
|
||||||
|
|
||||||
if (texture) {
|
|
||||||
u_sampler_view_default_template(&view_templ, texture, texture->format);
|
|
||||||
view = pipe->create_sampler_view(pipe, texture, &view_templ);
|
|
||||||
}
|
|
||||||
pipe_resource_reference(&texture, NULL);
|
|
||||||
mask->sampler_view = view;
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_context_add_object(ctx, &mask->base);
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mask_layer_destroy(struct vg_mask_layer *layer)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
vg_context_remove_object(ctx, &layer->base);
|
|
||||||
pipe_sampler_view_reference(&layer->sampler_view, NULL);
|
|
||||||
vg_free_object(&layer->base);
|
|
||||||
FREE(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mask_layer_fill(struct vg_mask_layer *layer,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height,
|
|
||||||
VGfloat value)
|
|
||||||
{
|
|
||||||
mask_resource_fill(layer->sampler_view->texture,
|
|
||||||
x, y, width, height, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mask_copy(struct vg_mask_layer *layer,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint dx, VGint dy,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_sampler_view *src = vg_get_surface_mask(ctx);
|
|
||||||
struct pipe_surface *surf, surf_tmpl;
|
|
||||||
|
|
||||||
/* get the destination surface */
|
|
||||||
u_surface_default_template(&surf_tmpl, layer->sampler_view->texture);
|
|
||||||
surf = ctx->pipe->create_surface(ctx->pipe, layer->sampler_view->texture,
|
|
||||||
&surf_tmpl);
|
|
||||||
if (surf && renderer_copy_begin(ctx->renderer, surf, VG_FALSE, src)) {
|
|
||||||
/* layer should be flipped when used as a texture */
|
|
||||||
sy += height;
|
|
||||||
height = -height;
|
|
||||||
|
|
||||||
renderer_copy(ctx->renderer,
|
|
||||||
dx, dy, width, height,
|
|
||||||
sx, sy, width, height);
|
|
||||||
renderer_copy_end(ctx->renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe_surface_reference(&surf, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mask_layer_render_to(struct vg_mask_layer *layer,
|
|
||||||
struct path *path,
|
|
||||||
VGbitfield paint_modes)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct pipe_sampler_view *view = vg_get_surface_mask(ctx);
|
|
||||||
struct matrix *mat = &ctx->state.vg.path_user_to_surface_matrix;
|
|
||||||
struct pipe_surface *surf, surf_tmpl;
|
|
||||||
u_surface_default_template(&surf_tmpl, view->texture);
|
|
||||||
surf = pipe->create_surface(pipe, view->texture, &surf_tmpl);
|
|
||||||
|
|
||||||
renderer_validate_for_mask_rendering(ctx->renderer, surf, mat);
|
|
||||||
|
|
||||||
if (paint_modes & VG_FILL_PATH) {
|
|
||||||
path_fill(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (paint_modes & VG_STROKE_PATH){
|
|
||||||
path_stroke(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe_surface_reference(&surf, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mask_render_to(struct path *path,
|
|
||||||
VGbitfield paint_modes,
|
|
||||||
VGMaskOperation operation)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
struct vg_mask_layer *temp_layer;
|
|
||||||
VGint width, height;
|
|
||||||
|
|
||||||
width = stfb->width;
|
|
||||||
height = stfb->height;
|
|
||||||
|
|
||||||
temp_layer = mask_layer_create(width, height);
|
|
||||||
mask_layer_fill(temp_layer, 0, 0, width, height, 0.0f);
|
|
||||||
|
|
||||||
mask_layer_render_to(temp_layer, path, paint_modes);
|
|
||||||
|
|
||||||
mask_using_layer(temp_layer, operation, 0, 0, width, height);
|
|
||||||
|
|
||||||
mask_layer_destroy(temp_layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mask_using_layer(struct vg_mask_layer *layer,
|
|
||||||
VGMaskOperation operation,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
mask_using_texture(layer->sampler_view, VG_TRUE, operation,
|
|
||||||
x, y, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
VGint mask_layer_width(struct vg_mask_layer *layer)
|
|
||||||
{
|
|
||||||
return layer->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGint mask_layer_height(struct vg_mask_layer *layer)
|
|
||||||
{
|
|
||||||
return layer->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void mask_using_image(struct vg_image *image,
|
|
||||||
VGMaskOperation operation,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
mask_using_texture(image->sampler_view, VG_FALSE, operation,
|
|
||||||
x, y, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mask_fill(VGint x, VGint y, VGint width, VGint height,
|
|
||||||
VGfloat value)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct pipe_sampler_view *view = vg_get_surface_mask(ctx);
|
|
||||||
|
|
||||||
#if DEBUG_MASKS
|
|
||||||
debug_printf("mask_fill(%d, %d, %d, %d) with rgba(%f, %f, %f, %f)\n",
|
|
||||||
x, y, width, height,
|
|
||||||
0.0f, 0.0f, 0.0f, value);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mask_resource_fill(view->texture, x, y, width, height, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
|
|
||||||
struct pipe_sampler_view **sampler_views)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
if (ctx->state.vg.masking) {
|
|
||||||
samplers[1] = &ctx->mask.sampler;
|
|
||||||
sampler_views[1] = vg_get_surface_mask(ctx);
|
|
||||||
return 1;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef MASK_H
|
|
||||||
#define MASK_H
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
|
|
||||||
struct path;
|
|
||||||
struct vg_image;
|
|
||||||
struct pipe_resource;
|
|
||||||
|
|
||||||
struct vg_mask_layer *mask_layer_create(VGint width, VGint height);
|
|
||||||
void mask_layer_destroy(struct vg_mask_layer *layer);
|
|
||||||
void mask_layer_fill(struct vg_mask_layer *layer,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height,
|
|
||||||
VGfloat value);
|
|
||||||
VGint mask_layer_width(struct vg_mask_layer *layer);
|
|
||||||
VGint mask_layer_height(struct vg_mask_layer *layer);
|
|
||||||
void mask_copy(struct vg_mask_layer *layer,
|
|
||||||
VGint sx, VGint sy,
|
|
||||||
VGint dx, VGint dy,
|
|
||||||
VGint width, VGint height);
|
|
||||||
|
|
||||||
void mask_render_to(struct path *path,
|
|
||||||
VGbitfield paint_modes,
|
|
||||||
VGMaskOperation operation);
|
|
||||||
|
|
||||||
void mask_using_layer(struct vg_mask_layer *layer,
|
|
||||||
VGMaskOperation operation,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height);
|
|
||||||
void mask_using_image(struct vg_image *image,
|
|
||||||
VGMaskOperation operation,
|
|
||||||
VGint x, VGint y,
|
|
||||||
VGint width, VGint height);
|
|
||||||
void mask_fill(VGint x, VGint y,
|
|
||||||
VGint width, VGint height,
|
|
||||||
VGfloat value);
|
|
||||||
|
|
||||||
VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
|
|
||||||
struct pipe_sampler_view **sampler_views);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,462 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef MATRIX_H
|
|
||||||
#define MATRIX_H
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "pipe/p_compiler.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#define floatsEqual(x, y) (fabs(x - y) <= 0.00001f * MIN2(fabs(x), fabs(y)))
|
|
||||||
#define floatIsZero(x) (floatsEqual((x) + 1, 1))
|
|
||||||
#define ABS(x) (fabsf(x))
|
|
||||||
|
|
||||||
#define DEGREES_TO_RADIANS(d) (0.0174532925199 * (d))
|
|
||||||
#define FLT_TO_INT(flt) float_to_int_floor(((VGuint*)&(flt))[0])
|
|
||||||
|
|
||||||
static INLINE VGint float_to_int_floor(VGuint bits)
|
|
||||||
{
|
|
||||||
int sign = (bits >> 31) ? -1 : 1;
|
|
||||||
int exp = ((bits >> 23) & 255) - 127;
|
|
||||||
int mant = bits & 0x007fffff;
|
|
||||||
int sh = 23 - exp;
|
|
||||||
|
|
||||||
/* abs(value) >= 2^31 -> clamp. */
|
|
||||||
|
|
||||||
if (exp >= 31)
|
|
||||||
return (VGint)((sign < 0) ? 0x80000000u : 0x7fffffffu);
|
|
||||||
|
|
||||||
/* abs(value) < 1 -> return -1 or 0. */
|
|
||||||
|
|
||||||
if (exp < 0)
|
|
||||||
return (sign < 0 && (exp > -127 || mant != 0)) ? -1 : 0;
|
|
||||||
|
|
||||||
/* abs(value) >= 2^23 -> shift left. */
|
|
||||||
|
|
||||||
mant |= 0x00800000;
|
|
||||||
if (sh <= 0)
|
|
||||||
return sign * (mant << -sh);
|
|
||||||
|
|
||||||
/* Negative -> add a rounding term. */
|
|
||||||
|
|
||||||
if (sign < 0)
|
|
||||||
mant += (1 << sh) - 1;
|
|
||||||
|
|
||||||
/* Shift right to obtain the result. */
|
|
||||||
|
|
||||||
return sign * (mant >> sh);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct matrix {
|
|
||||||
VGfloat m[9];
|
|
||||||
};
|
|
||||||
|
|
||||||
static INLINE void matrix_init(struct matrix *mat,
|
|
||||||
const VGfloat *val)
|
|
||||||
{
|
|
||||||
memcpy(mat->m, val, sizeof(VGfloat) * 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void matrix_inits(struct matrix *mat,
|
|
||||||
VGfloat m11, VGfloat m12, VGfloat m13,
|
|
||||||
VGfloat m21, VGfloat m22, VGfloat m23,
|
|
||||||
VGfloat m31, VGfloat m32, VGfloat m33)
|
|
||||||
{
|
|
||||||
mat->m[0] = m11; mat->m[1] = m12; mat->m[2] = m13;
|
|
||||||
mat->m[3] = m21; mat->m[4] = m22; mat->m[5] = m23;
|
|
||||||
mat->m[6] = m31; mat->m[7] = m32; mat->m[8] = m33;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void matrix_load_identity(struct matrix *matrix)
|
|
||||||
{
|
|
||||||
static const VGfloat identity[9] = {1.f, 0.f, 0.f,
|
|
||||||
0.f, 1.f, 0.f,
|
|
||||||
0.f, 0.f, 1.f};
|
|
||||||
memcpy(matrix->m, identity, sizeof(identity));
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGboolean matrix_is_identity(struct matrix *matrix)
|
|
||||||
{
|
|
||||||
return floatsEqual(matrix->m[0], 1) && floatIsZero(matrix->m[1]) &&
|
|
||||||
floatIsZero(matrix->m[2]) &&
|
|
||||||
floatIsZero(matrix->m[3]) && floatsEqual(matrix->m[4], 1) &&
|
|
||||||
floatIsZero(matrix->m[5]) &&
|
|
||||||
floatIsZero(matrix->m[6]) && floatIsZero(matrix->m[7]) &&
|
|
||||||
floatIsZero(matrix->m[8]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGboolean matrix_is_affine(struct matrix *matrix)
|
|
||||||
{
|
|
||||||
return floatIsZero(matrix->m[2]) && floatIsZero(matrix->m[5])
|
|
||||||
&& floatsEqual(matrix->m[8], 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void matrix_make_affine(struct matrix *matrix)
|
|
||||||
{
|
|
||||||
matrix->m[2] = 0.f;
|
|
||||||
matrix->m[5] = 0.f;
|
|
||||||
matrix->m[8] = 1.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void matrix_mult(struct matrix *dst,
|
|
||||||
const struct matrix *src)
|
|
||||||
{
|
|
||||||
VGfloat m11 = dst->m[0]*src->m[0] + dst->m[3]*src->m[1] + dst->m[6]*src->m[2];
|
|
||||||
VGfloat m12 = dst->m[0]*src->m[3] + dst->m[3]*src->m[4] + dst->m[6]*src->m[5];
|
|
||||||
VGfloat m13 = dst->m[0]*src->m[6] + dst->m[3]*src->m[7] + dst->m[6]*src->m[8];
|
|
||||||
|
|
||||||
VGfloat m21 = dst->m[1]*src->m[0] + dst->m[4]*src->m[1] + dst->m[7]*src->m[2];
|
|
||||||
VGfloat m22 = dst->m[1]*src->m[3] + dst->m[4]*src->m[4] + dst->m[7]*src->m[5];
|
|
||||||
VGfloat m23 = dst->m[1]*src->m[6] + dst->m[4]*src->m[7] + dst->m[7]*src->m[8];
|
|
||||||
|
|
||||||
VGfloat m31 = dst->m[2]*src->m[0] + dst->m[5]*src->m[1] + dst->m[8]*src->m[2];
|
|
||||||
VGfloat m32 = dst->m[2]*src->m[3] + dst->m[5]*src->m[4] + dst->m[8]*src->m[5];
|
|
||||||
VGfloat m33 = dst->m[2]*src->m[6] + dst->m[5]*src->m[7] + dst->m[8]*src->m[8];
|
|
||||||
|
|
||||||
dst->m[0] = m11; dst->m[1] = m21; dst->m[2] = m31;
|
|
||||||
dst->m[3] = m12; dst->m[4] = m22; dst->m[5] = m32;
|
|
||||||
dst->m[6] = m13; dst->m[7] = m23; dst->m[8] = m33;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void matrix_map_point(struct matrix *mat,
|
|
||||||
VGfloat x, VGfloat y,
|
|
||||||
VGfloat *out_x, VGfloat *out_y)
|
|
||||||
{
|
|
||||||
/* to be able to do matrix_map_point(m, x, y, &x, &y) use
|
|
||||||
* temporaries */
|
|
||||||
VGfloat tmp_x = x, tmp_y = y;
|
|
||||||
|
|
||||||
*out_x = mat->m[0]*tmp_x + mat->m[3]*tmp_y + mat->m[6];
|
|
||||||
*out_y = mat->m[1]*tmp_x + mat->m[4]*tmp_y + mat->m[7];
|
|
||||||
if (!matrix_is_affine(mat)) {
|
|
||||||
VGfloat w = 1/(mat->m[2]*tmp_x + mat->m[5]*tmp_y + mat->m[8]);
|
|
||||||
*out_x *= w;
|
|
||||||
*out_y *= w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void matrix_translate(struct matrix *dst,
|
|
||||||
VGfloat tx, VGfloat ty)
|
|
||||||
{
|
|
||||||
if (!matrix_is_affine(dst)) {
|
|
||||||
struct matrix trans_matrix;
|
|
||||||
matrix_load_identity(&trans_matrix);
|
|
||||||
trans_matrix.m[6] = tx;
|
|
||||||
trans_matrix.m[7] = ty;
|
|
||||||
matrix_mult(dst, &trans_matrix);
|
|
||||||
} else {
|
|
||||||
dst->m[6] += tx*dst->m[0] + ty*dst->m[3];
|
|
||||||
dst->m[7] += ty*dst->m[4] + tx*dst->m[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void matrix_scale(struct matrix *dst,
|
|
||||||
VGfloat sx, VGfloat sy)
|
|
||||||
{
|
|
||||||
if (!matrix_is_affine(dst)) {
|
|
||||||
struct matrix scale_matrix;
|
|
||||||
matrix_load_identity(&scale_matrix);
|
|
||||||
scale_matrix.m[0] = sx;
|
|
||||||
scale_matrix.m[4] = sy;
|
|
||||||
matrix_mult(dst, &scale_matrix);
|
|
||||||
} else {
|
|
||||||
dst->m[0] *= sx; dst->m[1] *= sx;
|
|
||||||
dst->m[3] *= sy; dst->m[4] *= sy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void matrix_shear(struct matrix *dst,
|
|
||||||
VGfloat shx, VGfloat shy)
|
|
||||||
{
|
|
||||||
struct matrix shear_matrix;
|
|
||||||
matrix_load_identity(&shear_matrix);
|
|
||||||
shear_matrix.m[1] = shy;
|
|
||||||
shear_matrix.m[3] = shx;
|
|
||||||
matrix_mult(dst, &shear_matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void matrix_rotate(struct matrix *dst,
|
|
||||||
VGfloat angle)
|
|
||||||
{
|
|
||||||
struct matrix mat;
|
|
||||||
float sin_val = 0;
|
|
||||||
float cos_val = 0;
|
|
||||||
|
|
||||||
|
|
||||||
if (floatsEqual(angle, 90) || floatsEqual(angle, -270))
|
|
||||||
sin_val = 1.f;
|
|
||||||
else if (floatsEqual(angle, 270) || floatsEqual(angle, -90))
|
|
||||||
sin_val = -1.f;
|
|
||||||
else if (floatsEqual(angle, 180))
|
|
||||||
cos_val = -1.f;
|
|
||||||
else {
|
|
||||||
double radians = DEGREES_TO_RADIANS(angle);
|
|
||||||
sin_val = (float) sin(radians);
|
|
||||||
cos_val = (float) cos(radians);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!matrix_is_affine(dst)) {
|
|
||||||
matrix_load_identity(&mat);
|
|
||||||
mat.m[0] = cos_val; mat.m[1] = sin_val;
|
|
||||||
mat.m[3] = -sin_val; mat.m[4] = cos_val;
|
|
||||||
|
|
||||||
matrix_mult(dst, &mat);
|
|
||||||
} else {
|
|
||||||
VGfloat m11 = cos_val*dst->m[0] + sin_val*dst->m[3];
|
|
||||||
VGfloat m12 = cos_val*dst->m[1] + sin_val*dst->m[4];
|
|
||||||
VGfloat m21 = -sin_val*dst->m[0] + cos_val*dst->m[3];
|
|
||||||
VGfloat m22 = -sin_val*dst->m[1] + cos_val*dst->m[4];
|
|
||||||
dst->m[0] = m11; dst->m[1] = m12;
|
|
||||||
dst->m[3] = m21; dst->m[4] = m22;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE VGfloat matrix_determinant(struct matrix *mat)
|
|
||||||
{
|
|
||||||
return mat->m[0]*(mat->m[8]*mat->m[4]-mat->m[7]*mat->m[5]) -
|
|
||||||
mat->m[3]*(mat->m[8]*mat->m[1]-mat->m[7]*mat->m[2])+
|
|
||||||
mat->m[6]*(mat->m[5]*mat->m[1]-mat->m[4]*mat->m[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void matrix_adjoint(struct matrix *mat)
|
|
||||||
{
|
|
||||||
VGfloat h[9];
|
|
||||||
h[0] = mat->m[4]*mat->m[8] - mat->m[5]*mat->m[7];
|
|
||||||
h[3] = mat->m[5]*mat->m[6] - mat->m[3]*mat->m[8];
|
|
||||||
h[6] = mat->m[3]*mat->m[7] - mat->m[4]*mat->m[6];
|
|
||||||
h[1] = mat->m[2]*mat->m[7] - mat->m[1]*mat->m[8];
|
|
||||||
h[4] = mat->m[0]*mat->m[8] - mat->m[2]*mat->m[6];
|
|
||||||
h[7] = mat->m[1]*mat->m[6] - mat->m[0]*mat->m[7];
|
|
||||||
h[2] = mat->m[1]*mat->m[5] - mat->m[2]*mat->m[4];
|
|
||||||
h[5] = mat->m[2]*mat->m[3] - mat->m[0]*mat->m[5];
|
|
||||||
h[8] = mat->m[0]*mat->m[4] - mat->m[1]*mat->m[3];
|
|
||||||
|
|
||||||
|
|
||||||
memcpy(mat->m, h, sizeof(VGfloat) * 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void matrix_divs(struct matrix *mat,
|
|
||||||
VGfloat s)
|
|
||||||
{
|
|
||||||
mat->m[0] /= s;
|
|
||||||
mat->m[1] /= s;
|
|
||||||
mat->m[2] /= s;
|
|
||||||
mat->m[3] /= s;
|
|
||||||
mat->m[4] /= s;
|
|
||||||
mat->m[5] /= s;
|
|
||||||
mat->m[6] /= s;
|
|
||||||
mat->m[7] /= s;
|
|
||||||
mat->m[8] /= s;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGboolean matrix_invert(struct matrix *mat)
|
|
||||||
{
|
|
||||||
VGfloat det = matrix_determinant(mat);
|
|
||||||
|
|
||||||
if (floatIsZero(det))
|
|
||||||
return VG_FALSE;
|
|
||||||
|
|
||||||
matrix_adjoint(mat);
|
|
||||||
matrix_divs(mat, det);
|
|
||||||
return VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGboolean matrix_is_invertible(struct matrix *mat)
|
|
||||||
{
|
|
||||||
return !floatIsZero(matrix_determinant(mat));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE VGboolean matrix_square_to_quad(VGfloat dx0, VGfloat dy0,
|
|
||||||
VGfloat dx1, VGfloat dy1,
|
|
||||||
VGfloat dx3, VGfloat dy3,
|
|
||||||
VGfloat dx2, VGfloat dy2,
|
|
||||||
struct matrix *mat)
|
|
||||||
{
|
|
||||||
VGfloat ax = dx0 - dx1 + dx2 - dx3;
|
|
||||||
VGfloat ay = dy0 - dy1 + dy2 - dy3;
|
|
||||||
|
|
||||||
if (floatIsZero(ax) && floatIsZero(ay)) {
|
|
||||||
/* affine case */
|
|
||||||
matrix_inits(mat,
|
|
||||||
dx1 - dx0, dy1 - dy0, 0,
|
|
||||||
dx2 - dx1, dy2 - dy1, 0,
|
|
||||||
dx0, dy0, 1);
|
|
||||||
} else {
|
|
||||||
VGfloat a, b, c, d, e, f, g, h;
|
|
||||||
VGfloat ax1 = dx1 - dx2;
|
|
||||||
VGfloat ax2 = dx3 - dx2;
|
|
||||||
VGfloat ay1 = dy1 - dy2;
|
|
||||||
VGfloat ay2 = dy3 - dy2;
|
|
||||||
|
|
||||||
/* determinants */
|
|
||||||
VGfloat gtop = ax * ay2 - ax2 * ay;
|
|
||||||
VGfloat htop = ax1 * ay - ax * ay1;
|
|
||||||
VGfloat bottom = ax1 * ay2 - ax2 * ay1;
|
|
||||||
|
|
||||||
if (!bottom)
|
|
||||||
return VG_FALSE;
|
|
||||||
|
|
||||||
g = gtop / bottom;
|
|
||||||
h = htop / bottom;
|
|
||||||
|
|
||||||
a = dx1 - dx0 + g * dx1;
|
|
||||||
b = dx3 - dx0 + h * dx3;
|
|
||||||
c = dx0;
|
|
||||||
d = dy1 - dy0 + g * dy1;
|
|
||||||
e = dy3 - dy0 + h * dy3;
|
|
||||||
f = dy0;
|
|
||||||
|
|
||||||
matrix_inits(mat,
|
|
||||||
a, d, g,
|
|
||||||
b, e, h,
|
|
||||||
c, f, 1.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGboolean matrix_quad_to_square(VGfloat sx0, VGfloat sy0,
|
|
||||||
VGfloat sx1, VGfloat sy1,
|
|
||||||
VGfloat sx2, VGfloat sy2,
|
|
||||||
VGfloat sx3, VGfloat sy3,
|
|
||||||
struct matrix *mat)
|
|
||||||
{
|
|
||||||
if (!matrix_square_to_quad(sx0, sy0, sx1, sy1,
|
|
||||||
sx2, sy2, sx3, sy3,
|
|
||||||
mat))
|
|
||||||
return VG_FALSE;
|
|
||||||
|
|
||||||
return matrix_invert(mat);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE VGboolean matrix_quad_to_quad(VGfloat dx0, VGfloat dy0,
|
|
||||||
VGfloat dx1, VGfloat dy1,
|
|
||||||
VGfloat dx2, VGfloat dy2,
|
|
||||||
VGfloat dx3, VGfloat dy3,
|
|
||||||
VGfloat sx0, VGfloat sy0,
|
|
||||||
VGfloat sx1, VGfloat sy1,
|
|
||||||
VGfloat sx2, VGfloat sy2,
|
|
||||||
VGfloat sx3, VGfloat sy3,
|
|
||||||
struct matrix *mat)
|
|
||||||
{
|
|
||||||
struct matrix sqr_to_qd;
|
|
||||||
|
|
||||||
if (!matrix_square_to_quad(dx0, dy0, dx1, dy1,
|
|
||||||
dx2, dy2, dx3, dy3,
|
|
||||||
mat))
|
|
||||||
return VG_FALSE;
|
|
||||||
|
|
||||||
if (!matrix_quad_to_square(sx0, sy0, sx1, sy1,
|
|
||||||
sx2, sy2, sx3, sy3,
|
|
||||||
&sqr_to_qd))
|
|
||||||
return VG_FALSE;
|
|
||||||
|
|
||||||
matrix_mult(mat, &sqr_to_qd);
|
|
||||||
|
|
||||||
return VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE VGboolean null_line(const VGfloat *l)
|
|
||||||
{
|
|
||||||
return floatsEqual(l[0], l[2]) && floatsEqual(l[1], l[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void line_normal(float *l, float *norm)
|
|
||||||
{
|
|
||||||
norm[0] = l[0];
|
|
||||||
norm[1] = l[1];
|
|
||||||
|
|
||||||
norm[2] = l[0] + (l[3] - l[1]);
|
|
||||||
norm[3] = l[1] - (l[2] - l[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void line_normalize(float *l)
|
|
||||||
{
|
|
||||||
float x = l[2] - l[0];
|
|
||||||
float y = l[3] - l[1];
|
|
||||||
float len = (float) sqrt(x*x + y*y);
|
|
||||||
l[2] = l[0] + x/len;
|
|
||||||
l[3] = l[1] + y/len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGfloat line_length(VGfloat x1, VGfloat y1,
|
|
||||||
VGfloat x2, VGfloat y2)
|
|
||||||
{
|
|
||||||
VGfloat x = x2 - x1;
|
|
||||||
VGfloat y = y2 - y1;
|
|
||||||
return (VGfloat) sqrt(x*x + y*y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGfloat line_lengthv(const VGfloat *l)
|
|
||||||
{
|
|
||||||
VGfloat x = l[2] - l[0];
|
|
||||||
VGfloat y = l[3] - l[1];
|
|
||||||
return (VGfloat) sqrt(x*x + y*y);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void line_point_at(float *l, float t, float *pt)
|
|
||||||
{
|
|
||||||
float dx = l[2] - l[0];
|
|
||||||
float dy = l[3] - l[1];
|
|
||||||
|
|
||||||
pt[0] = l[0] + dx * t;
|
|
||||||
pt[1] = l[1] + dy * t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void vector_unit(float *vec)
|
|
||||||
{
|
|
||||||
float len = (float) sqrt(vec[0] * vec[0] + vec[1] * vec[1]);
|
|
||||||
vec[0] /= len;
|
|
||||||
vec[1] /= len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void line_normal_vector(float *line, float *vec)
|
|
||||||
{
|
|
||||||
VGfloat normal[4];
|
|
||||||
|
|
||||||
line_normal(line, normal);
|
|
||||||
|
|
||||||
vec[0] = normal[2] - normal[0];
|
|
||||||
vec[1] = normal[3] - normal[1];
|
|
||||||
|
|
||||||
vector_unit(vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,759 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "paint.h"
|
|
||||||
|
|
||||||
#include "matrix.h"
|
|
||||||
#include "image.h"
|
|
||||||
|
|
||||||
#include "pipe/p_compiler.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
#include "util/u_sampler.h"
|
|
||||||
|
|
||||||
#include "cso_cache/cso_context.h"
|
|
||||||
|
|
||||||
struct vg_paint {
|
|
||||||
struct vg_object base;
|
|
||||||
|
|
||||||
VGPaintType type;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
VGfloat color[4];
|
|
||||||
VGint colori[4];
|
|
||||||
} solid;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
VGColorRampSpreadMode spread;
|
|
||||||
VGuint color_data[1024];
|
|
||||||
struct {
|
|
||||||
VGfloat coords[4];
|
|
||||||
VGint coordsi[4];
|
|
||||||
} linear;
|
|
||||||
struct {
|
|
||||||
VGfloat vals[5];
|
|
||||||
VGint valsi[5];
|
|
||||||
} radial;
|
|
||||||
struct pipe_sampler_view *sampler_view;
|
|
||||||
struct pipe_sampler_state sampler;
|
|
||||||
|
|
||||||
VGfloat *ramp_stops;
|
|
||||||
VGint *ramp_stopsi;
|
|
||||||
VGint num_stops;
|
|
||||||
|
|
||||||
VGboolean color_ramps_premultiplied;
|
|
||||||
} gradient;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct pipe_sampler_view *sampler_view;
|
|
||||||
VGTilingMode tiling_mode;
|
|
||||||
struct pipe_sampler_state sampler;
|
|
||||||
} pattern;
|
|
||||||
|
|
||||||
/* XXX next 3 all unneded? */
|
|
||||||
struct pipe_resource *cbuf;
|
|
||||||
struct pipe_shader_state fs_state;
|
|
||||||
void *fs;
|
|
||||||
};
|
|
||||||
|
|
||||||
static INLINE VGuint mix_pixels(VGuint p1, VGuint a, VGuint p2, VGuint b)
|
|
||||||
{
|
|
||||||
VGuint t = (p1 & 0xff00ff) * a + (p2 & 0xff00ff) * b;
|
|
||||||
t >>= 8; t &= 0xff00ff;
|
|
||||||
|
|
||||||
p1 = ((p1 >> 8) & 0xff00ff) * a + ((p2 >> 8) & 0xff00ff) * b;
|
|
||||||
p1 &= 0xff00ff00; p1 |= t;
|
|
||||||
|
|
||||||
return p1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGuint float4_to_argb(const VGfloat *clr)
|
|
||||||
{
|
|
||||||
return float_to_ubyte(clr[3]) << 24 |
|
|
||||||
float_to_ubyte(clr[0]) << 16 |
|
|
||||||
float_to_ubyte(clr[1]) << 8 |
|
|
||||||
float_to_ubyte(clr[2]) << 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void create_gradient_data(const VGfloat *ramp_stops,
|
|
||||||
VGint num,
|
|
||||||
VGuint *data,
|
|
||||||
VGint size)
|
|
||||||
{
|
|
||||||
VGint i;
|
|
||||||
VGint pos = 0;
|
|
||||||
VGfloat fpos = 0, incr = 1.f / size;
|
|
||||||
VGuint last_color;
|
|
||||||
|
|
||||||
while (fpos < ramp_stops[0]) {
|
|
||||||
data[pos] = float4_to_argb(ramp_stops + 1);
|
|
||||||
fpos += incr;
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < num - 1; ++i) {
|
|
||||||
VGint rcur = 5 * i;
|
|
||||||
VGint rnext = 5 * (i + 1);
|
|
||||||
VGfloat delta = 1.f/(ramp_stops[rnext] - ramp_stops[rcur]);
|
|
||||||
while (fpos < ramp_stops[rnext] && pos < size) {
|
|
||||||
VGint dist = 256 * ((fpos - ramp_stops[rcur]) * delta);
|
|
||||||
VGint idist = 256 - dist;
|
|
||||||
VGuint current_color = float4_to_argb(ramp_stops + rcur + 1);
|
|
||||||
VGuint next_color = float4_to_argb(ramp_stops + rnext + 1);
|
|
||||||
data[pos] = mix_pixels(current_color, idist,
|
|
||||||
next_color, dist);
|
|
||||||
fpos += incr;
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
last_color = float4_to_argb(ramp_stops + ((num - 1) * 5 + 1));
|
|
||||||
while (pos < size) {
|
|
||||||
data[pos] = last_color;
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
data[size-1] = last_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE struct pipe_resource *create_gradient_texture(struct vg_paint *p)
|
|
||||||
{
|
|
||||||
struct pipe_context *pipe = p->base.ctx->pipe;
|
|
||||||
struct pipe_screen *screen = pipe->screen;
|
|
||||||
struct pipe_resource *tex = 0;
|
|
||||||
struct pipe_resource templ;
|
|
||||||
|
|
||||||
memset(&templ, 0, sizeof(templ));
|
|
||||||
templ.target = PIPE_TEXTURE_1D;
|
|
||||||
templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
templ.last_level = 0;
|
|
||||||
templ.width0 = 1024;
|
|
||||||
templ.height0 = 1;
|
|
||||||
templ.depth0 = 1;
|
|
||||||
templ.array_size = 1;
|
|
||||||
templ.bind = PIPE_BIND_SAMPLER_VIEW;
|
|
||||||
|
|
||||||
tex = screen->resource_create(screen, &templ);
|
|
||||||
|
|
||||||
{ /* upload color_data */
|
|
||||||
struct pipe_transfer *transfer;
|
|
||||||
void *map =
|
|
||||||
pipe_transfer_map(p->base.ctx->pipe, tex, 0, 0,
|
|
||||||
PIPE_TRANSFER_WRITE, 0, 0, 1024, 1,
|
|
||||||
&transfer);
|
|
||||||
memcpy(map, p->gradient.color_data, sizeof(VGint)*1024);
|
|
||||||
pipe->transfer_unmap(pipe, transfer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE struct pipe_sampler_view *create_gradient_sampler_view(struct vg_paint *p)
|
|
||||||
{
|
|
||||||
struct pipe_context *pipe = p->base.ctx->pipe;
|
|
||||||
struct pipe_resource *texture;
|
|
||||||
struct pipe_sampler_view view_templ;
|
|
||||||
struct pipe_sampler_view *view;
|
|
||||||
|
|
||||||
texture = create_gradient_texture(p);
|
|
||||||
|
|
||||||
if (!texture)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
u_sampler_view_default_template(&view_templ, texture, texture->format);
|
|
||||||
view = pipe->create_sampler_view(pipe, texture, &view_templ);
|
|
||||||
/* want the texture to go away if the view is freed */
|
|
||||||
pipe_resource_reference(&texture, NULL);
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vg_paint * paint_create(struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
struct vg_paint *paint = CALLOC_STRUCT(vg_paint);
|
|
||||||
const VGfloat default_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
|
||||||
const VGfloat def_ling[] = {0.0f, 0.0f, 1.0f, 0.0f};
|
|
||||||
const VGfloat def_radg[] = {0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
|
|
||||||
vg_init_object(&paint->base, ctx, VG_OBJECT_PAINT);
|
|
||||||
vg_context_add_object(ctx, &paint->base);
|
|
||||||
|
|
||||||
paint->type = VG_PAINT_TYPE_COLOR;
|
|
||||||
memcpy(paint->solid.color, default_color,
|
|
||||||
4 * sizeof(VGfloat));
|
|
||||||
paint->gradient.spread = VG_COLOR_RAMP_SPREAD_PAD;
|
|
||||||
memcpy(paint->gradient.linear.coords, def_ling,
|
|
||||||
4 * sizeof(VGfloat));
|
|
||||||
memcpy(paint->gradient.radial.vals, def_radg,
|
|
||||||
5 * sizeof(VGfloat));
|
|
||||||
|
|
||||||
paint->gradient.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
paint->gradient.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
paint->gradient.sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
|
||||||
paint->gradient.sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
|
||||||
paint->gradient.sampler.normalized_coords = 1;
|
|
||||||
|
|
||||||
memcpy(&paint->pattern.sampler,
|
|
||||||
&paint->gradient.sampler,
|
|
||||||
sizeof(struct pipe_sampler_state));
|
|
||||||
|
|
||||||
return paint;
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_destroy(struct vg_paint *paint)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = paint->base.ctx;
|
|
||||||
pipe_sampler_view_reference(&paint->gradient.sampler_view, NULL);
|
|
||||||
if (paint->pattern.sampler_view)
|
|
||||||
pipe_sampler_view_reference(&paint->pattern.sampler_view, NULL);
|
|
||||||
if (ctx) {
|
|
||||||
vg_context_remove_object(ctx, &paint->base);
|
|
||||||
vg_free_object(&paint->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(paint->gradient.ramp_stopsi);
|
|
||||||
free(paint->gradient.ramp_stops);
|
|
||||||
FREE(paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_color(struct vg_paint *paint,
|
|
||||||
const VGfloat *color)
|
|
||||||
{
|
|
||||||
paint->solid.color[0] = color[0];
|
|
||||||
paint->solid.color[1] = color[1];
|
|
||||||
paint->solid.color[2] = color[2];
|
|
||||||
paint->solid.color[3] = color[3];
|
|
||||||
|
|
||||||
paint->solid.colori[0] = FLT_TO_INT(color[0]);
|
|
||||||
paint->solid.colori[1] = FLT_TO_INT(color[1]);
|
|
||||||
paint->solid.colori[2] = FLT_TO_INT(color[2]);
|
|
||||||
paint->solid.colori[3] = FLT_TO_INT(color[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void paint_color_buffer(struct vg_paint *paint, void *buffer)
|
|
||||||
{
|
|
||||||
VGfloat *map = (VGfloat*)buffer;
|
|
||||||
memcpy(buffer, paint->solid.color, 4 * sizeof(VGfloat));
|
|
||||||
map[4] = 0.f;
|
|
||||||
map[5] = 1.f;
|
|
||||||
map[6] = 2.f;
|
|
||||||
map[7] = 4.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint,
|
|
||||||
const struct matrix *inv,
|
|
||||||
void *buffer)
|
|
||||||
{
|
|
||||||
VGfloat *map = (VGfloat*)buffer;
|
|
||||||
VGfloat dd;
|
|
||||||
|
|
||||||
map[0] = paint->gradient.linear.coords[2] - paint->gradient.linear.coords[0];
|
|
||||||
map[1] = paint->gradient.linear.coords[3] - paint->gradient.linear.coords[1];
|
|
||||||
dd = (map[0] * map[0] + map[1] * map[1]);
|
|
||||||
|
|
||||||
map[2] = (dd > 0.0f) ? 1.f / dd : 0.f;
|
|
||||||
map[3] = 1.f;
|
|
||||||
|
|
||||||
map[4] = 0.f;
|
|
||||||
map[5] = 1.f;
|
|
||||||
map[6] = 2.f;
|
|
||||||
map[7] = 4.f;
|
|
||||||
{
|
|
||||||
struct matrix mat;
|
|
||||||
matrix_load_identity(&mat);
|
|
||||||
/* VEGA_LINEAR_GRADIENT_SHADER expects the first point to be at (0, 0) */
|
|
||||||
matrix_translate(&mat, -paint->gradient.linear.coords[0], -paint->gradient.linear.coords[1]);
|
|
||||||
matrix_mult(&mat, inv);
|
|
||||||
|
|
||||||
map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
|
|
||||||
map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
|
|
||||||
map[16] = mat.m[2]; map[17] = mat.m[5]; map[18] = mat.m[8]; map[19] = 0.f;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
debug_printf("Coords (%f, %f, %f, %f)\n",
|
|
||||||
map[0], map[1], map[2], map[3]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint,
|
|
||||||
const struct matrix *inv,
|
|
||||||
void *buffer)
|
|
||||||
{
|
|
||||||
const VGfloat *center = &paint->gradient.radial.vals[0];
|
|
||||||
const VGfloat *focal = &paint->gradient.radial.vals[2];
|
|
||||||
VGfloat rr = paint->gradient.radial.vals[4];
|
|
||||||
VGfloat *map = (VGfloat*)buffer;
|
|
||||||
VGfloat dd, new_focal[2];
|
|
||||||
|
|
||||||
rr *= rr;
|
|
||||||
|
|
||||||
map[0] = center[0] - focal[0];
|
|
||||||
map[1] = center[1] - focal[1];
|
|
||||||
dd = map[0] * map[0] + map[1] * map[1];
|
|
||||||
|
|
||||||
/* focal point must lie inside the circle */
|
|
||||||
if (0.998f * rr < dd) {
|
|
||||||
VGfloat scale;
|
|
||||||
|
|
||||||
scale = (dd > 0.0f) ? sqrt(0.998f * rr / dd) : 0.0f;
|
|
||||||
map[0] *= scale;
|
|
||||||
map[1] *= scale;
|
|
||||||
|
|
||||||
new_focal[0] = center[0] - map[0];
|
|
||||||
new_focal[1] = center[1] - map[1];
|
|
||||||
dd = map[0] * map[0] + map[1] * map[1];
|
|
||||||
focal = new_focal;
|
|
||||||
}
|
|
||||||
|
|
||||||
map[2] = (rr > dd) ? rr - dd : 1.0f;
|
|
||||||
map[3] = 1.f;
|
|
||||||
|
|
||||||
map[4] = 0.f;
|
|
||||||
map[5] = 1.f;
|
|
||||||
map[6] = 2.f;
|
|
||||||
map[7] = 4.f;
|
|
||||||
|
|
||||||
{
|
|
||||||
struct matrix mat;
|
|
||||||
matrix_load_identity(&mat);
|
|
||||||
matrix_translate(&mat, -focal[0], -focal[1]);
|
|
||||||
matrix_mult(&mat, inv);
|
|
||||||
|
|
||||||
map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
|
|
||||||
map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
|
|
||||||
map[16] = mat.m[2]; map[17] = mat.m[5]; map[18] = mat.m[8]; map[19] = 0.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
debug_printf("Coords (%f, %f, %f, %f)\n",
|
|
||||||
map[0], map[1], map[2], map[3]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void paint_pattern_buffer(struct vg_paint *paint,
|
|
||||||
const struct matrix *inv,
|
|
||||||
void *buffer)
|
|
||||||
{
|
|
||||||
VGfloat *map = (VGfloat *)buffer;
|
|
||||||
memcpy(map, paint->solid.color, 4 * sizeof(VGfloat));
|
|
||||||
|
|
||||||
map[4] = 0.f;
|
|
||||||
map[5] = 1.f;
|
|
||||||
map[6] = paint->pattern.sampler_view->texture->width0;
|
|
||||||
map[7] = paint->pattern.sampler_view->texture->height0;
|
|
||||||
{
|
|
||||||
struct matrix mat;
|
|
||||||
|
|
||||||
memcpy(&mat, inv, sizeof(*inv));
|
|
||||||
|
|
||||||
map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
|
|
||||||
map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
|
|
||||||
map[16] = mat.m[2]; map[17] = mat.m[5]; map[18] = mat.m[8]; map[19] = 0.f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_type(struct vg_paint *paint, VGPaintType type)
|
|
||||||
{
|
|
||||||
paint->type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_ramp_stops(struct vg_paint *paint, const VGfloat *stops,
|
|
||||||
int num)
|
|
||||||
{
|
|
||||||
const VGfloat default_stops[] = {0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
|
||||||
1.0f, 1.0f, 1.0f, 1.0f, 1.0f};
|
|
||||||
VGint i;
|
|
||||||
const VGint num_stops = num / 5;
|
|
||||||
VGfloat last_coord;
|
|
||||||
|
|
||||||
paint->gradient.num_stops = num;
|
|
||||||
if (num) {
|
|
||||||
free(paint->gradient.ramp_stops);
|
|
||||||
paint->gradient.ramp_stops = malloc(sizeof(VGfloat)*num);
|
|
||||||
memcpy(paint->gradient.ramp_stops, stops, sizeof(VGfloat)*num);
|
|
||||||
} else
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* stops must be in increasing order. the last stop is 1.0. if the
|
|
||||||
* first one is bigger than 1 then the whole sequence is invalid*/
|
|
||||||
if (stops[0] > 1) {
|
|
||||||
stops = default_stops;
|
|
||||||
num = 10;
|
|
||||||
}
|
|
||||||
last_coord = stops[0];
|
|
||||||
for (i = 1; i < num_stops; ++i) {
|
|
||||||
VGint idx = 5 * i;
|
|
||||||
VGfloat coord = stops[idx];
|
|
||||||
if (!floatsEqual(last_coord, coord) && coord < last_coord) {
|
|
||||||
stops = default_stops;
|
|
||||||
num = 10;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
last_coord = coord;
|
|
||||||
}
|
|
||||||
|
|
||||||
create_gradient_data(stops, num / 5, paint->gradient.color_data,
|
|
||||||
1024);
|
|
||||||
|
|
||||||
if (paint->gradient.sampler_view) {
|
|
||||||
pipe_sampler_view_reference(&paint->gradient.sampler_view, NULL);
|
|
||||||
paint->gradient.sampler_view = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
paint->gradient.sampler_view = create_gradient_sampler_view(paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_colori(struct vg_paint *p,
|
|
||||||
VGuint rgba)
|
|
||||||
{
|
|
||||||
p->solid.color[0] = ((rgba >> 24) & 0xff) / 255.f;
|
|
||||||
p->solid.color[1] = ((rgba >> 16) & 0xff) / 255.f;
|
|
||||||
p->solid.color[2] = ((rgba >> 8) & 0xff) / 255.f;
|
|
||||||
p->solid.color[3] = ((rgba >> 0) & 0xff) / 255.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGuint paint_colori(struct vg_paint *p)
|
|
||||||
{
|
|
||||||
#define F2B(f) (float_to_ubyte(f))
|
|
||||||
|
|
||||||
return ((F2B(p->solid.color[0]) << 24) |
|
|
||||||
(F2B(p->solid.color[1]) << 16) |
|
|
||||||
(F2B(p->solid.color[2]) << 8) |
|
|
||||||
(F2B(p->solid.color[3]) << 0));
|
|
||||||
#undef F2B
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_linear_gradient(struct vg_paint *paint,
|
|
||||||
const VGfloat *coords)
|
|
||||||
{
|
|
||||||
memcpy(paint->gradient.linear.coords, coords, sizeof(VGfloat) * 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_spread_mode(struct vg_paint *paint,
|
|
||||||
VGint mode)
|
|
||||||
{
|
|
||||||
paint->gradient.spread = mode;
|
|
||||||
switch(mode) {
|
|
||||||
case VG_COLOR_RAMP_SPREAD_PAD:
|
|
||||||
paint->gradient.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
break;
|
|
||||||
case VG_COLOR_RAMP_SPREAD_REPEAT:
|
|
||||||
paint->gradient.sampler.wrap_s = PIPE_TEX_WRAP_REPEAT;
|
|
||||||
break;
|
|
||||||
case VG_COLOR_RAMP_SPREAD_REFLECT:
|
|
||||||
paint->gradient.sampler.wrap_s = PIPE_TEX_WRAP_MIRROR_REPEAT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VGColorRampSpreadMode paint_spread_mode(struct vg_paint *paint)
|
|
||||||
{
|
|
||||||
return paint->gradient.spread;
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_radial_gradient(struct vg_paint *paint,
|
|
||||||
const VGfloat *values)
|
|
||||||
{
|
|
||||||
memcpy(paint->gradient.radial.vals, values, sizeof(VGfloat) * 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_pattern(struct vg_paint *paint,
|
|
||||||
struct vg_image *img)
|
|
||||||
{
|
|
||||||
if (paint->pattern.sampler_view)
|
|
||||||
pipe_sampler_view_reference(&paint->pattern.sampler_view, NULL);
|
|
||||||
|
|
||||||
paint->pattern.sampler_view = NULL;
|
|
||||||
pipe_sampler_view_reference(&paint->pattern.sampler_view,
|
|
||||||
img->sampler_view);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_pattern_tiling(struct vg_paint *paint,
|
|
||||||
VGTilingMode mode)
|
|
||||||
{
|
|
||||||
paint->pattern.tiling_mode = mode;
|
|
||||||
|
|
||||||
switch(mode) {
|
|
||||||
case VG_TILE_FILL:
|
|
||||||
paint->pattern.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
|
|
||||||
paint->pattern.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
|
|
||||||
break;
|
|
||||||
case VG_TILE_PAD:
|
|
||||||
paint->pattern.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
paint->pattern.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
break;
|
|
||||||
case VG_TILE_REPEAT:
|
|
||||||
paint->pattern.sampler.wrap_s = PIPE_TEX_WRAP_REPEAT;
|
|
||||||
paint->pattern.sampler.wrap_t = PIPE_TEX_WRAP_REPEAT;
|
|
||||||
break;
|
|
||||||
case VG_TILE_REFLECT:
|
|
||||||
paint->pattern.sampler.wrap_s = PIPE_TEX_WRAP_MIRROR_REPEAT;
|
|
||||||
paint->pattern.sampler.wrap_t = PIPE_TEX_WRAP_MIRROR_REPEAT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
debug_assert(!"Unknown tiling mode");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_get_color(struct vg_paint *paint,
|
|
||||||
VGfloat *color)
|
|
||||||
{
|
|
||||||
color[0] = paint->solid.color[0];
|
|
||||||
color[1] = paint->solid.color[1];
|
|
||||||
color[2] = paint->solid.color[2];
|
|
||||||
color[3] = paint->solid.color[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_ramp_stops(struct vg_paint *paint, VGfloat *stops,
|
|
||||||
int num)
|
|
||||||
{
|
|
||||||
memcpy(stops, paint->gradient.ramp_stops, sizeof(VGfloat)*num);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_linear_gradient(struct vg_paint *paint,
|
|
||||||
VGfloat *coords)
|
|
||||||
{
|
|
||||||
memcpy(coords, paint->gradient.linear.coords, sizeof(VGfloat)*4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_radial_gradient(struct vg_paint *paint,
|
|
||||||
VGfloat *coords)
|
|
||||||
{
|
|
||||||
memcpy(coords, paint->gradient.radial.vals, sizeof(VGfloat)*5);
|
|
||||||
}
|
|
||||||
|
|
||||||
int paint_num_ramp_stops(struct vg_paint *paint)
|
|
||||||
{
|
|
||||||
return paint->gradient.num_stops;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGPaintType paint_type(struct vg_paint *paint)
|
|
||||||
{
|
|
||||||
return paint->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_coloriv(struct vg_paint *paint,
|
|
||||||
const VGint *color)
|
|
||||||
{
|
|
||||||
paint->solid.color[0] = color[0];
|
|
||||||
paint->solid.color[1] = color[1];
|
|
||||||
paint->solid.color[2] = color[2];
|
|
||||||
paint->solid.color[3] = color[3];
|
|
||||||
|
|
||||||
paint->solid.colori[0] = color[0];
|
|
||||||
paint->solid.colori[1] = color[1];
|
|
||||||
paint->solid.colori[2] = color[2];
|
|
||||||
paint->solid.colori[3] = color[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_get_coloriv(struct vg_paint *paint,
|
|
||||||
VGint *color)
|
|
||||||
{
|
|
||||||
color[0] = paint->solid.colori[0];
|
|
||||||
color[1] = paint->solid.colori[1];
|
|
||||||
color[2] = paint->solid.colori[2];
|
|
||||||
color[3] = paint->solid.colori[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_color_ramp_premultiplied(struct vg_paint *paint,
|
|
||||||
VGboolean set)
|
|
||||||
{
|
|
||||||
paint->gradient.color_ramps_premultiplied = set;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGboolean paint_color_ramp_premultiplied(struct vg_paint *paint)
|
|
||||||
{
|
|
||||||
return paint->gradient.color_ramps_premultiplied;
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_ramp_stopsi(struct vg_paint *paint, const VGint *stops,
|
|
||||||
int num)
|
|
||||||
{
|
|
||||||
if (num) {
|
|
||||||
free(paint->gradient.ramp_stopsi);
|
|
||||||
paint->gradient.ramp_stopsi = malloc(sizeof(VGint)*num);
|
|
||||||
memcpy(paint->gradient.ramp_stopsi, stops, sizeof(VGint)*num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_ramp_stopsi(struct vg_paint *paint, VGint *stops,
|
|
||||||
int num)
|
|
||||||
{
|
|
||||||
memcpy(stops, paint->gradient.ramp_stopsi, sizeof(VGint)*num);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_linear_gradienti(struct vg_paint *paint,
|
|
||||||
const VGint *coords)
|
|
||||||
{
|
|
||||||
memcpy(paint->gradient.linear.coordsi, coords, sizeof(VGint) * 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_linear_gradienti(struct vg_paint *paint,
|
|
||||||
VGint *coords)
|
|
||||||
{
|
|
||||||
memcpy(coords, paint->gradient.linear.coordsi, sizeof(VGint)*4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_set_radial_gradienti(struct vg_paint *paint,
|
|
||||||
const VGint *values)
|
|
||||||
{
|
|
||||||
memcpy(paint->gradient.radial.valsi, values, sizeof(VGint) * 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_radial_gradienti(struct vg_paint *paint,
|
|
||||||
VGint *coords)
|
|
||||||
{
|
|
||||||
memcpy(coords, paint->gradient.radial.valsi, sizeof(VGint)*5);
|
|
||||||
}
|
|
||||||
|
|
||||||
VGTilingMode paint_pattern_tiling(struct vg_paint *paint)
|
|
||||||
{
|
|
||||||
return paint->pattern.tiling_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers,
|
|
||||||
struct pipe_sampler_view **sampler_views)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
switch(paint->type) {
|
|
||||||
case VG_PAINT_TYPE_LINEAR_GRADIENT:
|
|
||||||
case VG_PAINT_TYPE_RADIAL_GRADIENT: {
|
|
||||||
if (paint->gradient.sampler_view) {
|
|
||||||
paint->gradient.sampler.min_img_filter = image_sampler_filter(ctx);
|
|
||||||
paint->gradient.sampler.mag_img_filter = image_sampler_filter(ctx);
|
|
||||||
samplers[0] = &paint->gradient.sampler;
|
|
||||||
sampler_views[0] = paint->gradient.sampler_view;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VG_PAINT_TYPE_PATTERN: {
|
|
||||||
memcpy(paint->pattern.sampler.border_color.f,
|
|
||||||
ctx->state.vg.tile_fill_color,
|
|
||||||
sizeof(VGfloat) * 4);
|
|
||||||
paint->pattern.sampler.min_img_filter = image_sampler_filter(ctx);
|
|
||||||
paint->pattern.sampler.mag_img_filter = image_sampler_filter(ctx);
|
|
||||||
samplers[0] = &paint->pattern.sampler;
|
|
||||||
sampler_views[0] = paint->pattern.sampler_view;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_resolve_type(struct vg_paint *paint)
|
|
||||||
{
|
|
||||||
if (paint->type == VG_PAINT_TYPE_PATTERN &&
|
|
||||||
!paint->pattern.sampler_view) {
|
|
||||||
paint->type = VG_PAINT_TYPE_COLOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VGboolean paint_is_degenerate(struct vg_paint *paint)
|
|
||||||
{
|
|
||||||
VGboolean degen;
|
|
||||||
VGfloat *vals;
|
|
||||||
|
|
||||||
|
|
||||||
switch (paint->type) {
|
|
||||||
case VG_PAINT_TYPE_LINEAR_GRADIENT:
|
|
||||||
vals = paint->gradient.linear.coords;
|
|
||||||
/* two points are coincident */
|
|
||||||
degen = (floatsEqual(vals[0], vals[2]) &&
|
|
||||||
floatsEqual(vals[1], vals[3]));
|
|
||||||
break;
|
|
||||||
case VG_PAINT_TYPE_RADIAL_GRADIENT:
|
|
||||||
vals = paint->gradient.radial.vals;
|
|
||||||
/* radius <= 0 */
|
|
||||||
degen = (vals[4] <= 0.0f);
|
|
||||||
break;
|
|
||||||
case VG_PAINT_TYPE_COLOR:
|
|
||||||
case VG_PAINT_TYPE_PATTERN:
|
|
||||||
default:
|
|
||||||
degen = VG_FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return degen;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGint paint_constant_buffer_size(struct vg_paint *paint)
|
|
||||||
{
|
|
||||||
switch(paint->type) {
|
|
||||||
case VG_PAINT_TYPE_COLOR:
|
|
||||||
return 8 * sizeof(VGfloat);/*4 color + 4 constants (0.f,1.f,2.f,4.f)*/
|
|
||||||
break;
|
|
||||||
case VG_PAINT_TYPE_LINEAR_GRADIENT:
|
|
||||||
return 20 * sizeof(VGfloat);
|
|
||||||
break;
|
|
||||||
case VG_PAINT_TYPE_RADIAL_GRADIENT:
|
|
||||||
return 20 * sizeof(VGfloat);
|
|
||||||
break;
|
|
||||||
case VG_PAINT_TYPE_PATTERN:
|
|
||||||
return 20 * sizeof(VGfloat);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
debug_printf("Uknown paint type: %d\n", paint->type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void paint_fill_constant_buffer(struct vg_paint *paint,
|
|
||||||
const struct matrix *mat,
|
|
||||||
void *buffer)
|
|
||||||
{
|
|
||||||
switch(paint->type) {
|
|
||||||
case VG_PAINT_TYPE_COLOR:
|
|
||||||
paint_color_buffer(paint, buffer);
|
|
||||||
break;
|
|
||||||
case VG_PAINT_TYPE_LINEAR_GRADIENT:
|
|
||||||
paint_linear_gradient_buffer(paint, mat, buffer);
|
|
||||||
break;
|
|
||||||
case VG_PAINT_TYPE_RADIAL_GRADIENT:
|
|
||||||
paint_radial_gradient_buffer(paint, mat, buffer);
|
|
||||||
break;
|
|
||||||
case VG_PAINT_TYPE_PATTERN:
|
|
||||||
paint_pattern_buffer(paint, mat, buffer);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VGboolean paint_is_opaque(struct vg_paint *paint)
|
|
||||||
{
|
|
||||||
/* TODO add other paint types and make sure PAINT_DIRTY gets set */
|
|
||||||
return (paint->type == VG_PAINT_TYPE_COLOR &&
|
|
||||||
floatsEqual(paint->solid.color[3], 1.0f));
|
|
||||||
}
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef PAINT_H
|
|
||||||
#define PAINT_H
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
|
|
||||||
struct vg_paint;
|
|
||||||
struct vg_image;
|
|
||||||
struct pipe_sampler_state;
|
|
||||||
struct pipe_resource;
|
|
||||||
|
|
||||||
struct vg_paint *paint_create(struct vg_context *ctx);
|
|
||||||
void paint_destroy(struct vg_paint *paint);
|
|
||||||
|
|
||||||
void paint_set_color(struct vg_paint *paint,
|
|
||||||
const VGfloat *color);
|
|
||||||
void paint_get_color(struct vg_paint *paint,
|
|
||||||
VGfloat *color);
|
|
||||||
|
|
||||||
void paint_set_coloriv(struct vg_paint *paint,
|
|
||||||
const VGint *color);
|
|
||||||
void paint_get_coloriv(struct vg_paint *paint,
|
|
||||||
VGint *color);
|
|
||||||
|
|
||||||
void paint_set_colori(struct vg_paint *paint,
|
|
||||||
VGuint rgba);
|
|
||||||
|
|
||||||
VGuint paint_colori(struct vg_paint *paint);
|
|
||||||
|
|
||||||
void paint_set_type(struct vg_paint *paint, VGPaintType type);
|
|
||||||
VGPaintType paint_type(struct vg_paint *paint);
|
|
||||||
void paint_resolve_type(struct vg_paint *paint);
|
|
||||||
|
|
||||||
void paint_set_linear_gradient(struct vg_paint *paint,
|
|
||||||
const VGfloat *coords);
|
|
||||||
void paint_linear_gradient(struct vg_paint *paint,
|
|
||||||
VGfloat *coords);
|
|
||||||
void paint_set_linear_gradienti(struct vg_paint *paint,
|
|
||||||
const VGint *coords);
|
|
||||||
void paint_linear_gradienti(struct vg_paint *paint,
|
|
||||||
VGint *coords);
|
|
||||||
|
|
||||||
|
|
||||||
void paint_set_radial_gradient(struct vg_paint *paint,
|
|
||||||
const VGfloat *values);
|
|
||||||
void paint_radial_gradient(struct vg_paint *paint,
|
|
||||||
VGfloat *coords);
|
|
||||||
void paint_set_radial_gradienti(struct vg_paint *paint,
|
|
||||||
const VGint *values);
|
|
||||||
void paint_radial_gradienti(struct vg_paint *paint,
|
|
||||||
VGint *coords);
|
|
||||||
|
|
||||||
|
|
||||||
void paint_set_ramp_stops(struct vg_paint *paint, const VGfloat *stops,
|
|
||||||
int num);
|
|
||||||
void paint_ramp_stops(struct vg_paint *paint, VGfloat *stops,
|
|
||||||
int num);
|
|
||||||
|
|
||||||
void paint_set_ramp_stopsi(struct vg_paint *paint, const VGint *stops,
|
|
||||||
int num);
|
|
||||||
void paint_ramp_stopsi(struct vg_paint *paint, VGint *stops,
|
|
||||||
int num);
|
|
||||||
|
|
||||||
int paint_num_ramp_stops(struct vg_paint *paint);
|
|
||||||
|
|
||||||
void paint_set_spread_mode(struct vg_paint *paint,
|
|
||||||
VGint mode);
|
|
||||||
VGColorRampSpreadMode paint_spread_mode(struct vg_paint *paint);
|
|
||||||
|
|
||||||
|
|
||||||
void paint_set_pattern(struct vg_paint *paint,
|
|
||||||
struct vg_image *img);
|
|
||||||
void paint_set_pattern_tiling(struct vg_paint *paint,
|
|
||||||
VGTilingMode mode);
|
|
||||||
VGTilingMode paint_pattern_tiling(struct vg_paint *paint);
|
|
||||||
|
|
||||||
void paint_set_color_ramp_premultiplied(struct vg_paint *paint,
|
|
||||||
VGboolean set);
|
|
||||||
VGboolean paint_color_ramp_premultiplied(struct vg_paint *paint);
|
|
||||||
|
|
||||||
|
|
||||||
VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers,
|
|
||||||
struct pipe_sampler_view **sampler_views);
|
|
||||||
|
|
||||||
VGboolean paint_is_degenerate(struct vg_paint *paint);
|
|
||||||
|
|
||||||
VGint paint_constant_buffer_size(struct vg_paint *paint);
|
|
||||||
|
|
||||||
void paint_fill_constant_buffer(struct vg_paint *paint,
|
|
||||||
const struct matrix *mat,
|
|
||||||
void *buffer);
|
|
||||||
|
|
||||||
VGboolean paint_is_opaque(struct vg_paint *paint);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,126 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _PATH_H
|
|
||||||
#define _PATH_H
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
struct path;
|
|
||||||
struct polygon;
|
|
||||||
struct matrix;
|
|
||||||
|
|
||||||
enum fill_rule {
|
|
||||||
ODD_EVEN_FILL,
|
|
||||||
WINDING_FILL
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct path_for_each_data {
|
|
||||||
VGubyte segment;
|
|
||||||
/* all coords are absolute, even if segment is relative */
|
|
||||||
const VGfloat *coords;
|
|
||||||
VGfloat sx, sy, ox, oy, px, py;
|
|
||||||
void *user_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef VGboolean (*path_for_each_cb)(struct path *p,
|
|
||||||
struct path_for_each_data *data);
|
|
||||||
|
|
||||||
|
|
||||||
struct path *path_create(VGPathDatatype dt, VGfloat scale, VGfloat bias,
|
|
||||||
VGint segmentCapacityHint,
|
|
||||||
VGint coordCapacityHint,
|
|
||||||
VGbitfield capabilities);
|
|
||||||
void path_destroy(struct path *p);
|
|
||||||
|
|
||||||
VGbitfield path_capabilities(struct path *p);
|
|
||||||
void path_set_capabilities(struct path *p, VGbitfield bf);
|
|
||||||
|
|
||||||
void path_append_data(struct path *p,
|
|
||||||
VGint numSegments,
|
|
||||||
const VGubyte * pathSegments,
|
|
||||||
const void * pathData);
|
|
||||||
|
|
||||||
void path_append_path(struct path *dst,
|
|
||||||
struct path *src);
|
|
||||||
|
|
||||||
VGint path_num_segments(struct path *p);
|
|
||||||
|
|
||||||
void path_bounding_rect(struct path *p, float *x, float *y,
|
|
||||||
float *w, float *h);
|
|
||||||
float path_length(struct path *p, int start_segment, int num_segments);
|
|
||||||
|
|
||||||
void path_set_fill_rule(enum fill_rule fill);
|
|
||||||
enum fill_rule path_fill_rule(enum fill_rule fill);
|
|
||||||
|
|
||||||
VGboolean path_is_empty(struct path *p);
|
|
||||||
|
|
||||||
VGbyte path_datatype_size(struct path *p);
|
|
||||||
|
|
||||||
VGPathDatatype path_datatype(struct path *p);
|
|
||||||
VGfloat path_scale(struct path *p);
|
|
||||||
VGfloat path_bias(struct path *p);
|
|
||||||
VGint path_num_coords(struct path *p);
|
|
||||||
|
|
||||||
void path_modify_coords(struct path *p,
|
|
||||||
VGint startIndex,
|
|
||||||
VGint numSegments,
|
|
||||||
const void * pathData);
|
|
||||||
|
|
||||||
struct path *path_create_stroke(struct path *p,
|
|
||||||
struct matrix *m);
|
|
||||||
|
|
||||||
void path_for_each_segment(struct path *path,
|
|
||||||
path_for_each_cb cb,
|
|
||||||
void *user_data);
|
|
||||||
|
|
||||||
void path_transform(struct path *dst, struct path *src);
|
|
||||||
VGboolean path_interpolate(struct path *dst,
|
|
||||||
struct path *start, struct path *end,
|
|
||||||
VGfloat amount);
|
|
||||||
|
|
||||||
void path_clear(struct path *p, VGbitfield capabilities);
|
|
||||||
void path_render(struct path *p, VGbitfield paintModes, struct matrix *mat);
|
|
||||||
void path_fill(struct path *p);
|
|
||||||
void path_stroke(struct path *p);
|
|
||||||
|
|
||||||
void path_move_to(struct path *p, float x, float y);
|
|
||||||
void path_line_to(struct path *p, float x, float y);
|
|
||||||
void path_cubic_to(struct path *p, float px1, float py1,
|
|
||||||
float px2, float py2,
|
|
||||||
float x, float y);
|
|
||||||
|
|
||||||
void path_point(struct path *p, VGint startSegment, VGint numSegments,
|
|
||||||
VGfloat distance, VGfloat *point, VGfloat *normal);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void vg_float_to_datatype(VGPathDatatype datatype,
|
|
||||||
VGubyte *common_data,
|
|
||||||
const VGfloat *data,
|
|
||||||
VGint num_coords);
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef PATH_UTILS_H
|
|
||||||
#define PATH_UTILS_H
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#define SEGMENT_COMMAND(command) /* Extract segment type */ \
|
|
||||||
((command) & 0x1e)
|
|
||||||
#define SEGMENT_ABS_REL(command) /* Extract absolute/relative bit */ \
|
|
||||||
((command) & 0x1)
|
|
||||||
|
|
||||||
static INLINE VGint size_for_datatype(VGPathDatatype datatype)
|
|
||||||
{
|
|
||||||
switch(datatype) {
|
|
||||||
case VG_PATH_DATATYPE_S_8:
|
|
||||||
return 1;
|
|
||||||
case VG_PATH_DATATYPE_S_16:
|
|
||||||
return 2;
|
|
||||||
case VG_PATH_DATATYPE_S_32:
|
|
||||||
return 4;
|
|
||||||
case VG_PATH_DATATYPE_F:
|
|
||||||
return 4;
|
|
||||||
default:
|
|
||||||
assert(!"unknown datatype");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGint num_elements_for_segments(const VGubyte *segments,
|
|
||||||
VGint num_segments)
|
|
||||||
{
|
|
||||||
VGint i;
|
|
||||||
VGint count = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < num_segments; ++i) {
|
|
||||||
VGubyte segment = segments[i];
|
|
||||||
VGint command = SEGMENT_COMMAND(segment);
|
|
||||||
switch(command) {
|
|
||||||
case VG_CLOSE_PATH:
|
|
||||||
break;
|
|
||||||
case VG_MOVE_TO:
|
|
||||||
count += 2;
|
|
||||||
break;
|
|
||||||
case VG_LINE_TO:
|
|
||||||
count += 2;
|
|
||||||
break;
|
|
||||||
case VG_HLINE_TO:
|
|
||||||
count += 1;
|
|
||||||
break;
|
|
||||||
case VG_VLINE_TO:
|
|
||||||
count += 1;
|
|
||||||
break;
|
|
||||||
case VG_QUAD_TO:
|
|
||||||
count += 4;
|
|
||||||
break;
|
|
||||||
case VG_CUBIC_TO:
|
|
||||||
count += 6;
|
|
||||||
break;
|
|
||||||
case VG_SQUAD_TO:
|
|
||||||
count += 2;
|
|
||||||
break;
|
|
||||||
case VG_SCUBIC_TO:
|
|
||||||
count += 4;
|
|
||||||
break;
|
|
||||||
case VG_SCCWARC_TO:
|
|
||||||
count += 5;
|
|
||||||
break;
|
|
||||||
case VG_SCWARC_TO:
|
|
||||||
count += 5;
|
|
||||||
break;
|
|
||||||
case VG_LCCWARC_TO:
|
|
||||||
count += 5;
|
|
||||||
break;
|
|
||||||
case VG_LCWARC_TO:
|
|
||||||
count += 5;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(!"Unknown segment!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,351 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "polygon.h"
|
|
||||||
|
|
||||||
#include "matrix.h" /*for floatsEqual*/
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "vg_state.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
#include "util_array.h"
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "pipe/p_screen.h"
|
|
||||||
|
|
||||||
#include "util/u_draw_quad.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define DEBUG_POLYGON 0
|
|
||||||
|
|
||||||
#define COMPONENTS 2
|
|
||||||
|
|
||||||
struct polygon
|
|
||||||
{
|
|
||||||
VGfloat *data;
|
|
||||||
VGint size;
|
|
||||||
|
|
||||||
VGint num_verts;
|
|
||||||
|
|
||||||
VGboolean dirty;
|
|
||||||
void *user_vbuf;
|
|
||||||
struct pipe_screen *screen;
|
|
||||||
};
|
|
||||||
|
|
||||||
static float *ptr_to_vertex(float *data, int idx)
|
|
||||||
{
|
|
||||||
return data + (idx * COMPONENTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void polygon_print(struct polygon *poly)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float *vert;
|
|
||||||
debug_printf("Polygon %p, size = %d\n", poly, poly->num_verts);
|
|
||||||
for (i = 0; i < poly->num_verts; ++i) {
|
|
||||||
vert = ptr_to_vertex(poly->data, i);
|
|
||||||
debug_printf("%f, %f, ", vert[0], vert[1]);
|
|
||||||
}
|
|
||||||
debug_printf("\nend\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
struct polygon * polygon_create(int size)
|
|
||||||
{
|
|
||||||
struct polygon *poly = malloc(sizeof(struct polygon));
|
|
||||||
|
|
||||||
poly->data = malloc(sizeof(float) * COMPONENTS * size);
|
|
||||||
poly->size = size;
|
|
||||||
poly->num_verts = 0;
|
|
||||||
poly->dirty = VG_TRUE;
|
|
||||||
poly->user_vbuf = NULL;
|
|
||||||
|
|
||||||
return poly;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct polygon * polygon_create_from_data(float *data, int size)
|
|
||||||
{
|
|
||||||
struct polygon *poly = polygon_create(size);
|
|
||||||
|
|
||||||
memcpy(poly->data, data, sizeof(float) * COMPONENTS * size);
|
|
||||||
poly->num_verts = size;
|
|
||||||
poly->dirty = VG_TRUE;
|
|
||||||
poly->user_vbuf = NULL;
|
|
||||||
|
|
||||||
return poly;
|
|
||||||
}
|
|
||||||
|
|
||||||
void polygon_destroy(struct polygon *poly)
|
|
||||||
{
|
|
||||||
free(poly->data);
|
|
||||||
free(poly);
|
|
||||||
}
|
|
||||||
|
|
||||||
void polygon_resize(struct polygon *poly, int new_size)
|
|
||||||
{
|
|
||||||
float *data = malloc(sizeof(float) * COMPONENTS * new_size);
|
|
||||||
int size = MIN2(sizeof(float) * COMPONENTS * new_size,
|
|
||||||
sizeof(float) * COMPONENTS * poly->size);
|
|
||||||
memcpy(data, poly->data, size);
|
|
||||||
free(poly->data);
|
|
||||||
poly->data = data;
|
|
||||||
poly->size = new_size;
|
|
||||||
poly->dirty = VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int polygon_size(struct polygon *poly)
|
|
||||||
{
|
|
||||||
return poly->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int polygon_vertex_count(struct polygon *poly)
|
|
||||||
{
|
|
||||||
return poly->num_verts;
|
|
||||||
}
|
|
||||||
|
|
||||||
float * polygon_data(struct polygon *poly)
|
|
||||||
{
|
|
||||||
return poly->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void polygon_vertex_append(struct polygon *p,
|
|
||||||
float x, float y)
|
|
||||||
{
|
|
||||||
float *vert;
|
|
||||||
#if DEBUG_POLYGON
|
|
||||||
debug_printf("Append vertex [%f, %f]\n", x, y);
|
|
||||||
#endif
|
|
||||||
if (p->num_verts >= p->size) {
|
|
||||||
polygon_resize(p, p->size * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
vert = ptr_to_vertex(p->data, p->num_verts);
|
|
||||||
vert[0] = x;
|
|
||||||
vert[1] = y;
|
|
||||||
++p->num_verts;
|
|
||||||
p->dirty = VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void polygon_set_vertex(struct polygon *p, int idx,
|
|
||||||
float x, float y)
|
|
||||||
{
|
|
||||||
float *vert;
|
|
||||||
if (idx >= p->num_verts) {
|
|
||||||
/*fixme: error reporting*/
|
|
||||||
abort();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vert = ptr_to_vertex(p->data, idx);
|
|
||||||
vert[0] = x;
|
|
||||||
vert[1] = y;
|
|
||||||
p->dirty = VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void polygon_vertex(struct polygon *p, int idx,
|
|
||||||
float *vertex)
|
|
||||||
{
|
|
||||||
float *vert;
|
|
||||||
if (idx >= p->num_verts) {
|
|
||||||
/*fixme: error reporting*/
|
|
||||||
abort();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vert = ptr_to_vertex(p->data, idx);
|
|
||||||
vertex[0] = vert[0];
|
|
||||||
vertex[1] = vert[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
void polygon_bounding_rect(struct polygon *p,
|
|
||||||
float *rect)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float minx, miny, maxx, maxy;
|
|
||||||
float *vert = ptr_to_vertex(p->data, 0);
|
|
||||||
minx = vert[0];
|
|
||||||
maxx = vert[0];
|
|
||||||
miny = vert[1];
|
|
||||||
maxy = vert[1];
|
|
||||||
|
|
||||||
for (i = 1; i < p->num_verts; ++i) {
|
|
||||||
vert = ptr_to_vertex(p->data, i);
|
|
||||||
minx = MIN2(vert[0], minx);
|
|
||||||
miny = MIN2(vert[1], miny);
|
|
||||||
|
|
||||||
maxx = MAX2(vert[0], maxx);
|
|
||||||
maxy = MAX2(vert[1], maxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
rect[0] = minx;
|
|
||||||
rect[1] = miny;
|
|
||||||
rect[2] = maxx - minx;
|
|
||||||
rect[3] = maxy - miny;
|
|
||||||
}
|
|
||||||
|
|
||||||
int polygon_contains_point(struct polygon *p,
|
|
||||||
float x, float y)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void polygon_append_polygon(struct polygon *dst,
|
|
||||||
struct polygon *src)
|
|
||||||
{
|
|
||||||
if (dst->num_verts + src->num_verts >= dst->size) {
|
|
||||||
polygon_resize(dst, dst->num_verts + src->num_verts * 1.5);
|
|
||||||
}
|
|
||||||
memcpy(ptr_to_vertex(dst->data, dst->num_verts),
|
|
||||||
src->data, src->num_verts * COMPONENTS * sizeof(VGfloat));
|
|
||||||
dst->num_verts += src->num_verts;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGboolean polygon_is_closed(struct polygon *p)
|
|
||||||
{
|
|
||||||
VGfloat start[2], end[2];
|
|
||||||
|
|
||||||
polygon_vertex(p, 0, start);
|
|
||||||
polygon_vertex(p, p->num_verts - 1, end);
|
|
||||||
|
|
||||||
return floatsEqual(start[0], end[0]) && floatsEqual(start[1], end[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void polygon_prepare_buffer(struct vg_context *ctx,
|
|
||||||
struct polygon *poly)
|
|
||||||
{
|
|
||||||
struct pipe_context *pipe;
|
|
||||||
|
|
||||||
/*polygon_print(poly);*/
|
|
||||||
|
|
||||||
pipe = ctx->pipe;
|
|
||||||
|
|
||||||
if (poly->user_vbuf == NULL || poly->dirty) {
|
|
||||||
poly->screen = pipe->screen;
|
|
||||||
poly->user_vbuf = poly->data;
|
|
||||||
poly->dirty = VG_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void polygon_fill(struct polygon *poly, struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
struct pipe_vertex_element velement;
|
|
||||||
struct pipe_vertex_buffer vbuffer;
|
|
||||||
VGfloat bounds[4];
|
|
||||||
VGfloat min_x, min_y, max_x, max_y;
|
|
||||||
|
|
||||||
assert(poly);
|
|
||||||
polygon_bounding_rect(poly, bounds);
|
|
||||||
min_x = bounds[0];
|
|
||||||
min_y = bounds[1];
|
|
||||||
max_x = bounds[0] + bounds[2];
|
|
||||||
max_y = bounds[1] + bounds[3];
|
|
||||||
|
|
||||||
#if DEBUG_POLYGON
|
|
||||||
debug_printf("Poly bounds are [%f, %f], [%f, %f]\n",
|
|
||||||
min_x, min_y, max_x, max_y);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
polygon_prepare_buffer(ctx, poly);
|
|
||||||
|
|
||||||
/* tell renderer about the vertex attributes */
|
|
||||||
memset(&velement, 0, sizeof(velement));
|
|
||||||
velement.src_offset = 0;
|
|
||||||
velement.instance_divisor = 0;
|
|
||||||
velement.vertex_buffer_index = 0;
|
|
||||||
velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
|
|
||||||
|
|
||||||
/* tell renderer about the vertex buffer */
|
|
||||||
memset(&vbuffer, 0, sizeof(vbuffer));
|
|
||||||
vbuffer.user_buffer = poly->user_vbuf;
|
|
||||||
vbuffer.stride = COMPONENTS * sizeof(float); /* vertex size */
|
|
||||||
|
|
||||||
renderer_polygon_stencil_begin(ctx->renderer,
|
|
||||||
&velement, ctx->state.vg.fill_rule, VG_FALSE);
|
|
||||||
renderer_polygon_stencil(ctx->renderer, &vbuffer,
|
|
||||||
PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
|
|
||||||
renderer_polygon_stencil_end(ctx->renderer);
|
|
||||||
|
|
||||||
renderer_polygon_fill_begin(ctx->renderer, VG_FALSE);
|
|
||||||
renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y);
|
|
||||||
renderer_polygon_fill_end(ctx->renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
struct array *polys = polyarray->array;
|
|
||||||
VGfloat min_x = polyarray->min_x;
|
|
||||||
VGfloat min_y = polyarray->min_y;
|
|
||||||
VGfloat max_x = polyarray->max_x;
|
|
||||||
VGfloat max_y = polyarray->max_y;
|
|
||||||
struct pipe_vertex_element velement;
|
|
||||||
struct pipe_vertex_buffer vbuffer;
|
|
||||||
VGint i;
|
|
||||||
|
|
||||||
|
|
||||||
#if DEBUG_POLYGON
|
|
||||||
debug_printf("%s: Poly bounds are [%f, %f], [%f, %f]\n",
|
|
||||||
__FUNCTION__,
|
|
||||||
min_x, min_y, max_x, max_y);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* tell renderer about the vertex attributes */
|
|
||||||
memset(&velement, 0, sizeof(velement));
|
|
||||||
velement.src_offset = 0;
|
|
||||||
velement.instance_divisor = 0;
|
|
||||||
velement.vertex_buffer_index = 0;
|
|
||||||
velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
|
|
||||||
|
|
||||||
/* tell renderer about the vertex buffer */
|
|
||||||
memset(&vbuffer, 0, sizeof(vbuffer));
|
|
||||||
vbuffer.stride = COMPONENTS * sizeof(float); /* vertex size */
|
|
||||||
|
|
||||||
/* prepare the stencil buffer */
|
|
||||||
renderer_polygon_stencil_begin(ctx->renderer,
|
|
||||||
&velement, ctx->state.vg.fill_rule, VG_FALSE);
|
|
||||||
for (i = 0; i < polys->num_elements; ++i) {
|
|
||||||
struct polygon *poly = (((struct polygon**)polys->data)[i]);
|
|
||||||
|
|
||||||
polygon_prepare_buffer(ctx, poly);
|
|
||||||
vbuffer.user_buffer = poly->user_vbuf;
|
|
||||||
|
|
||||||
renderer_polygon_stencil(ctx->renderer, &vbuffer,
|
|
||||||
PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
|
|
||||||
}
|
|
||||||
renderer_polygon_stencil_end(ctx->renderer);
|
|
||||||
|
|
||||||
/* fill it */
|
|
||||||
renderer_polygon_fill_begin(ctx->renderer, VG_FALSE);
|
|
||||||
renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y);
|
|
||||||
renderer_polygon_fill_end(ctx->renderer);
|
|
||||||
}
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef POLYGON_H
|
|
||||||
#define POLYGON_H
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
struct polygon;
|
|
||||||
struct vg_context;
|
|
||||||
struct vg_paint;
|
|
||||||
struct array;
|
|
||||||
|
|
||||||
struct polygon *polygon_create(int size);
|
|
||||||
struct polygon *polygon_create_from_data(float *data, int size);
|
|
||||||
void polygon_destroy(struct polygon *poly);
|
|
||||||
|
|
||||||
void polygon_resize(struct polygon *poly, int new_size);
|
|
||||||
int polygon_size(struct polygon *poly);
|
|
||||||
|
|
||||||
int polygon_vertex_count(struct polygon *poly);
|
|
||||||
float * polygon_data(struct polygon *poly);
|
|
||||||
|
|
||||||
void polygon_vertex_append(struct polygon *p,
|
|
||||||
float x, float y);
|
|
||||||
void polygon_append_polygon(struct polygon *dst,
|
|
||||||
struct polygon *src);
|
|
||||||
void polygon_set_vertex(struct polygon *p, int idx,
|
|
||||||
float x, float y);
|
|
||||||
void polygon_vertex(struct polygon *p, int idx,
|
|
||||||
float *vertex);
|
|
||||||
|
|
||||||
void polygon_bounding_rect(struct polygon *p,
|
|
||||||
float *rect);
|
|
||||||
int polygon_contains_point(struct polygon *p,
|
|
||||||
float x, float y);
|
|
||||||
|
|
||||||
VGboolean polygon_is_closed(struct polygon *p);
|
|
||||||
|
|
||||||
void polygon_fill(struct polygon *p, struct vg_context *pipe);
|
|
||||||
|
|
||||||
/* TODO: make a file/module around this struct
|
|
||||||
*/
|
|
||||||
struct polygon_array {
|
|
||||||
struct array *array;
|
|
||||||
VGfloat min_x, max_x;
|
|
||||||
VGfloat min_y, max_y;
|
|
||||||
};
|
|
||||||
|
|
||||||
void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,159 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
* Copyright 2010 LunarG, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef RENDERER_H
|
|
||||||
#define RENDERER_H
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
struct renderer;
|
|
||||||
|
|
||||||
struct vg_context;
|
|
||||||
struct vg_state;
|
|
||||||
struct st_framebuffer;
|
|
||||||
struct pipe_resource;
|
|
||||||
struct pipe_sampler_state;
|
|
||||||
struct pipe_sampler_view;
|
|
||||||
struct pipe_surface;
|
|
||||||
struct pipe_vertex_element;
|
|
||||||
struct pipe_vertex_buffer;
|
|
||||||
struct matrix;
|
|
||||||
|
|
||||||
struct renderer *renderer_create(struct vg_context *owner);
|
|
||||||
void renderer_destroy(struct renderer *);
|
|
||||||
|
|
||||||
void renderer_validate(struct renderer *renderer,
|
|
||||||
VGbitfield dirty,
|
|
||||||
const struct st_framebuffer *stfb,
|
|
||||||
const struct vg_state *state);
|
|
||||||
|
|
||||||
void renderer_validate_for_shader(struct renderer *renderer,
|
|
||||||
const struct pipe_sampler_state **samplers,
|
|
||||||
struct pipe_sampler_view **views,
|
|
||||||
VGint num_samplers,
|
|
||||||
const struct matrix *modelview,
|
|
||||||
void *fs,
|
|
||||||
const void *const_buffer,
|
|
||||||
VGint const_buffer_len);
|
|
||||||
|
|
||||||
void renderer_validate_for_mask_rendering(struct renderer *renderer,
|
|
||||||
struct pipe_surface *dst,
|
|
||||||
const struct matrix *modelview);
|
|
||||||
|
|
||||||
VGboolean renderer_copy_begin(struct renderer *renderer,
|
|
||||||
struct pipe_surface *dst,
|
|
||||||
VGboolean y0_top,
|
|
||||||
struct pipe_sampler_view *src);
|
|
||||||
|
|
||||||
void renderer_copy(struct renderer *renderer,
|
|
||||||
VGint x, VGint y, VGint w, VGint h,
|
|
||||||
VGint sx, VGint sy, VGint sw, VGint sh);
|
|
||||||
|
|
||||||
void renderer_copy_end(struct renderer *renderer);
|
|
||||||
|
|
||||||
VGboolean renderer_drawtex_begin(struct renderer *renderer,
|
|
||||||
struct pipe_sampler_view *src);
|
|
||||||
|
|
||||||
void renderer_drawtex(struct renderer *renderer,
|
|
||||||
VGint x, VGint y, VGint w, VGint h,
|
|
||||||
VGint sx, VGint sy, VGint sw, VGint sh);
|
|
||||||
|
|
||||||
void renderer_drawtex_end(struct renderer *renderer);
|
|
||||||
|
|
||||||
VGboolean renderer_scissor_begin(struct renderer *renderer,
|
|
||||||
VGboolean restore_dsa);
|
|
||||||
|
|
||||||
void renderer_scissor(struct renderer *renderer,
|
|
||||||
VGint x, VGint y, VGint width, VGint height);
|
|
||||||
|
|
||||||
void renderer_scissor_end(struct renderer *renderer);
|
|
||||||
|
|
||||||
VGboolean renderer_clear_begin(struct renderer *renderer);
|
|
||||||
|
|
||||||
void renderer_clear(struct renderer *renderer,
|
|
||||||
VGint x, VGint y, VGint width, VGint height,
|
|
||||||
const VGfloat color[4]);
|
|
||||||
|
|
||||||
void renderer_clear_end(struct renderer *renderer);
|
|
||||||
|
|
||||||
VGboolean renderer_filter_begin(struct renderer *renderer,
|
|
||||||
struct pipe_resource *dst,
|
|
||||||
VGboolean y0_top,
|
|
||||||
VGbitfield channel_mask,
|
|
||||||
const struct pipe_sampler_state **samplers,
|
|
||||||
struct pipe_sampler_view **views,
|
|
||||||
VGint num_samplers,
|
|
||||||
void *fs,
|
|
||||||
const void *const_buffer,
|
|
||||||
VGint const_buffer_len);
|
|
||||||
|
|
||||||
void renderer_filter(struct renderer *renderer,
|
|
||||||
VGint x, VGint y, VGint w, VGint h,
|
|
||||||
VGint sx, VGint sy, VGint sw, VGint sh);
|
|
||||||
|
|
||||||
void renderer_filter_end(struct renderer *renderer);
|
|
||||||
|
|
||||||
VGboolean renderer_polygon_stencil_begin(struct renderer *renderer,
|
|
||||||
struct pipe_vertex_element *velem,
|
|
||||||
VGFillRule rule,
|
|
||||||
VGboolean restore_dsa);
|
|
||||||
|
|
||||||
void renderer_polygon_stencil(struct renderer *renderer,
|
|
||||||
struct pipe_vertex_buffer *vbuf,
|
|
||||||
VGuint mode, VGuint start, VGuint count);
|
|
||||||
|
|
||||||
void renderer_polygon_stencil_end(struct renderer *renderer);
|
|
||||||
|
|
||||||
VGboolean renderer_polygon_fill_begin(struct renderer *renderer,
|
|
||||||
VGboolean save_dsa);
|
|
||||||
|
|
||||||
void renderer_polygon_fill(struct renderer *renderer,
|
|
||||||
VGfloat min_x, VGfloat min_y,
|
|
||||||
VGfloat max_x, VGfloat max_y);
|
|
||||||
|
|
||||||
void renderer_polygon_fill_end(struct renderer *renderer);
|
|
||||||
|
|
||||||
void renderer_texture_quad(struct renderer *,
|
|
||||||
struct pipe_resource *texture,
|
|
||||||
VGfloat x1offset, VGfloat y1offset,
|
|
||||||
VGfloat x2offset, VGfloat y2offset,
|
|
||||||
VGfloat x1, VGfloat y1,
|
|
||||||
VGfloat x2, VGfloat y2,
|
|
||||||
VGfloat x3, VGfloat y3,
|
|
||||||
VGfloat x4, VGfloat y4);
|
|
||||||
|
|
||||||
void renderer_copy_surface(struct renderer *r,
|
|
||||||
struct pipe_surface *src,
|
|
||||||
int sx1, int sy1,
|
|
||||||
int sx2, int sy2,
|
|
||||||
struct pipe_surface *dst,
|
|
||||||
int dx1, int dy1,
|
|
||||||
int dx2, int dy2,
|
|
||||||
float z, unsigned filter);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,414 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "shader.h"
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "shaders_cache.h"
|
|
||||||
#include "paint.h"
|
|
||||||
#include "mask.h"
|
|
||||||
#include "image.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
#include "util/u_format.h"
|
|
||||||
|
|
||||||
#define MAX_CONSTANTS 28
|
|
||||||
|
|
||||||
struct shader {
|
|
||||||
struct vg_context *context;
|
|
||||||
|
|
||||||
VGboolean color_transform;
|
|
||||||
VGboolean masking;
|
|
||||||
struct vg_paint *paint;
|
|
||||||
struct vg_image *image;
|
|
||||||
|
|
||||||
struct matrix modelview;
|
|
||||||
struct matrix paint_matrix;
|
|
||||||
|
|
||||||
VGboolean drawing_image;
|
|
||||||
VGImageMode image_mode;
|
|
||||||
|
|
||||||
float constants[MAX_CONSTANTS];
|
|
||||||
struct pipe_resource *cbuf;
|
|
||||||
struct pipe_shader_state fs_state;
|
|
||||||
void *fs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct shader * shader_create(struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
struct shader *shader = 0;
|
|
||||||
|
|
||||||
shader = CALLOC_STRUCT(shader);
|
|
||||||
shader->context = ctx;
|
|
||||||
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader_destroy(struct shader *shader)
|
|
||||||
{
|
|
||||||
FREE(shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader_set_color_transform(struct shader *shader, VGboolean set)
|
|
||||||
{
|
|
||||||
shader->color_transform = set;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader_set_masking(struct shader *shader, VGboolean set)
|
|
||||||
{
|
|
||||||
shader->masking = set;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGboolean shader_is_masking(struct shader *shader)
|
|
||||||
{
|
|
||||||
return shader->masking;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader_set_paint(struct shader *shader, struct vg_paint *paint)
|
|
||||||
{
|
|
||||||
shader->paint = paint;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vg_paint * shader_paint(struct shader *shader)
|
|
||||||
{
|
|
||||||
return shader->paint;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VGint setup_constant_buffer(struct shader *shader)
|
|
||||||
{
|
|
||||||
const struct vg_state *state = &shader->context->state.vg;
|
|
||||||
VGint param_bytes = paint_constant_buffer_size(shader->paint);
|
|
||||||
VGint i;
|
|
||||||
|
|
||||||
param_bytes += sizeof(VGfloat) * 8;
|
|
||||||
assert(param_bytes <= sizeof(shader->constants));
|
|
||||||
|
|
||||||
if (state->color_transform) {
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
VGfloat val = (i < 4) ? 127.0f : 1.0f;
|
|
||||||
shader->constants[i] =
|
|
||||||
CLAMP(state->color_transform_values[i], -val, val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
memset(shader->constants, 0, sizeof(VGfloat) * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
paint_fill_constant_buffer(shader->paint,
|
|
||||||
&shader->paint_matrix, shader->constants + 8);
|
|
||||||
|
|
||||||
return param_bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VGboolean blend_use_shader(struct shader *shader)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = shader->context;
|
|
||||||
VGboolean advanced_blending;
|
|
||||||
|
|
||||||
switch (ctx->state.vg.blend_mode) {
|
|
||||||
case VG_BLEND_DST_OVER:
|
|
||||||
case VG_BLEND_MULTIPLY:
|
|
||||||
case VG_BLEND_SCREEN:
|
|
||||||
case VG_BLEND_DARKEN:
|
|
||||||
case VG_BLEND_LIGHTEN:
|
|
||||||
case VG_BLEND_ADDITIVE:
|
|
||||||
advanced_blending = VG_TRUE;
|
|
||||||
break;
|
|
||||||
case VG_BLEND_SRC_OVER:
|
|
||||||
if (util_format_has_alpha(ctx->draw_buffer->strb->format)) {
|
|
||||||
/* no blending is required if the paints and the image are opaque */
|
|
||||||
advanced_blending = !paint_is_opaque(ctx->state.vg.fill_paint) ||
|
|
||||||
!paint_is_opaque(ctx->state.vg.stroke_paint);
|
|
||||||
if (!advanced_blending && shader->drawing_image) {
|
|
||||||
advanced_blending =
|
|
||||||
util_format_has_alpha(shader->image->sampler_view->format);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* fall through */
|
|
||||||
default:
|
|
||||||
advanced_blending = VG_FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return advanced_blending;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VGint blend_bind_samplers(struct shader *shader,
|
|
||||||
struct pipe_sampler_state **samplers,
|
|
||||||
struct pipe_sampler_view **sampler_views)
|
|
||||||
{
|
|
||||||
if (blend_use_shader(shader)) {
|
|
||||||
struct vg_context *ctx = shader->context;
|
|
||||||
|
|
||||||
samplers[2] = &ctx->blend_sampler;
|
|
||||||
sampler_views[2] = vg_prepare_blend_surface(ctx);
|
|
||||||
|
|
||||||
if (!samplers[0] || !sampler_views[0]) {
|
|
||||||
samplers[0] = samplers[2];
|
|
||||||
sampler_views[0] = sampler_views[2];
|
|
||||||
}
|
|
||||||
if (!samplers[1] || !sampler_views[1]) {
|
|
||||||
samplers[1] = samplers[0];
|
|
||||||
sampler_views[1] = sampler_views[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VGint setup_samplers(struct shader *shader,
|
|
||||||
struct pipe_sampler_state **samplers,
|
|
||||||
struct pipe_sampler_view **sampler_views)
|
|
||||||
{
|
|
||||||
/* a little wonky: we use the num as a boolean that just says
|
|
||||||
* whether any sampler/textures have been set. the actual numbering
|
|
||||||
* for samplers is always the same:
|
|
||||||
* 0 - paint sampler/texture for gradient/pattern
|
|
||||||
* 1 - mask sampler/texture
|
|
||||||
* 2 - blend sampler/texture
|
|
||||||
* 3 - image sampler/texture
|
|
||||||
* */
|
|
||||||
VGint num = 0;
|
|
||||||
|
|
||||||
samplers[0] = NULL;
|
|
||||||
samplers[1] = NULL;
|
|
||||||
samplers[2] = NULL;
|
|
||||||
samplers[3] = NULL;
|
|
||||||
sampler_views[0] = NULL;
|
|
||||||
sampler_views[1] = NULL;
|
|
||||||
sampler_views[2] = NULL;
|
|
||||||
sampler_views[3] = NULL;
|
|
||||||
|
|
||||||
num += paint_bind_samplers(shader->paint, samplers, sampler_views);
|
|
||||||
num += mask_bind_samplers(samplers, sampler_views);
|
|
||||||
num += blend_bind_samplers(shader, samplers, sampler_views);
|
|
||||||
if (shader->drawing_image && shader->image)
|
|
||||||
num += image_bind_samplers(shader->image, samplers, sampler_views);
|
|
||||||
|
|
||||||
return (num) ? 4 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGboolean is_format_bw(struct shader *shader)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
struct vg_context *ctx = shader->context;
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (shader->drawing_image && shader->image) {
|
|
||||||
if (shader->image->format == VG_BW_1)
|
|
||||||
return VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return VG_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setup_shader_program(struct shader *shader)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = shader->context;
|
|
||||||
VGint shader_id = 0;
|
|
||||||
VGBlendMode blend_mode = ctx->state.vg.blend_mode;
|
|
||||||
VGboolean black_white = is_format_bw(shader);
|
|
||||||
|
|
||||||
/* 1st stage: fill */
|
|
||||||
if (!shader->drawing_image ||
|
|
||||||
(shader->image_mode == VG_DRAW_IMAGE_MULTIPLY || shader->image_mode == VG_DRAW_IMAGE_STENCIL)) {
|
|
||||||
switch(paint_type(shader->paint)) {
|
|
||||||
case VG_PAINT_TYPE_COLOR:
|
|
||||||
shader_id |= VEGA_SOLID_FILL_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_PAINT_TYPE_LINEAR_GRADIENT:
|
|
||||||
shader_id |= VEGA_LINEAR_GRADIENT_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_PAINT_TYPE_RADIAL_GRADIENT:
|
|
||||||
shader_id |= VEGA_RADIAL_GRADIENT_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_PAINT_TYPE_PATTERN:
|
|
||||||
shader_id |= VEGA_PATTERN_SHADER;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (paint_is_degenerate(shader->paint))
|
|
||||||
shader_id = VEGA_PAINT_DEGENERATE_SHADER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* second stage image */
|
|
||||||
if (shader->drawing_image) {
|
|
||||||
switch(shader->image_mode) {
|
|
||||||
case VG_DRAW_IMAGE_NORMAL:
|
|
||||||
shader_id |= VEGA_IMAGE_NORMAL_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_DRAW_IMAGE_MULTIPLY:
|
|
||||||
shader_id |= VEGA_IMAGE_MULTIPLY_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_DRAW_IMAGE_STENCIL:
|
|
||||||
shader_id |= VEGA_IMAGE_STENCIL_SHADER;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
debug_printf("Unknown image mode!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shader->color_transform)
|
|
||||||
shader_id |= VEGA_COLOR_TRANSFORM_SHADER;
|
|
||||||
|
|
||||||
if (blend_use_shader(shader)) {
|
|
||||||
if (shader->drawing_image && shader->image_mode == VG_DRAW_IMAGE_STENCIL)
|
|
||||||
shader_id |= VEGA_ALPHA_PER_CHANNEL_SHADER;
|
|
||||||
else
|
|
||||||
shader_id |= VEGA_ALPHA_NORMAL_SHADER;
|
|
||||||
|
|
||||||
switch(blend_mode) {
|
|
||||||
case VG_BLEND_SRC:
|
|
||||||
shader_id |= VEGA_BLEND_SRC_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_BLEND_SRC_OVER:
|
|
||||||
shader_id |= VEGA_BLEND_SRC_OVER_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_BLEND_DST_OVER:
|
|
||||||
shader_id |= VEGA_BLEND_DST_OVER_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_BLEND_SRC_IN:
|
|
||||||
shader_id |= VEGA_BLEND_SRC_IN_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_BLEND_DST_IN:
|
|
||||||
shader_id |= VEGA_BLEND_DST_IN_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_BLEND_MULTIPLY:
|
|
||||||
shader_id |= VEGA_BLEND_MULTIPLY_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_BLEND_SCREEN:
|
|
||||||
shader_id |= VEGA_BLEND_SCREEN_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_BLEND_DARKEN:
|
|
||||||
shader_id |= VEGA_BLEND_DARKEN_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_BLEND_LIGHTEN:
|
|
||||||
shader_id |= VEGA_BLEND_LIGHTEN_SHADER;
|
|
||||||
break;
|
|
||||||
case VG_BLEND_ADDITIVE:
|
|
||||||
shader_id |= VEGA_BLEND_ADDITIVE_SHADER;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* update alpha of the source */
|
|
||||||
if (shader->drawing_image && shader->image_mode == VG_DRAW_IMAGE_STENCIL)
|
|
||||||
shader_id |= VEGA_ALPHA_PER_CHANNEL_SHADER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shader->masking)
|
|
||||||
shader_id |= VEGA_MASK_SHADER;
|
|
||||||
|
|
||||||
if (black_white)
|
|
||||||
shader_id |= VEGA_BW_SHADER;
|
|
||||||
|
|
||||||
shader->fs = shaders_cache_fill(ctx->sc, shader_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void shader_bind(struct shader *shader)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = shader->context;
|
|
||||||
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
|
|
||||||
struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
|
|
||||||
VGint num_samplers, param_bytes;
|
|
||||||
|
|
||||||
/* first resolve the real paint type */
|
|
||||||
paint_resolve_type(shader->paint);
|
|
||||||
|
|
||||||
num_samplers = setup_samplers(shader, samplers, sampler_views);
|
|
||||||
param_bytes = setup_constant_buffer(shader);
|
|
||||||
setup_shader_program(shader);
|
|
||||||
|
|
||||||
renderer_validate_for_shader(ctx->renderer,
|
|
||||||
(const struct pipe_sampler_state **) samplers,
|
|
||||||
sampler_views, num_samplers,
|
|
||||||
&shader->modelview,
|
|
||||||
shader->fs, (const void *) shader->constants, param_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader_set_image_mode(struct shader *shader, VGImageMode image_mode)
|
|
||||||
{
|
|
||||||
shader->image_mode = image_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGImageMode shader_image_mode(struct shader *shader)
|
|
||||||
{
|
|
||||||
return shader->image_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader_set_drawing_image(struct shader *shader, VGboolean drawing_image)
|
|
||||||
{
|
|
||||||
shader->drawing_image = drawing_image;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGboolean shader_drawing_image(struct shader *shader)
|
|
||||||
{
|
|
||||||
return shader->drawing_image;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader_set_image(struct shader *shader, struct vg_image *img)
|
|
||||||
{
|
|
||||||
shader->image = img;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the transformation to map a vertex to the surface coordinates.
|
|
||||||
*/
|
|
||||||
void shader_set_surface_matrix(struct shader *shader,
|
|
||||||
const struct matrix *mat)
|
|
||||||
{
|
|
||||||
shader->modelview = *mat;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the transformation to map a pixel to the paint coordinates.
|
|
||||||
*/
|
|
||||||
void shader_set_paint_matrix(struct shader *shader, const struct matrix *mat)
|
|
||||||
{
|
|
||||||
const struct st_framebuffer *stfb = shader->context->draw_buffer;
|
|
||||||
const VGfloat px_center_offset = 0.5f;
|
|
||||||
|
|
||||||
memcpy(&shader->paint_matrix, mat, sizeof(*mat));
|
|
||||||
|
|
||||||
/* make it window-to-paint for the shaders */
|
|
||||||
matrix_translate(&shader->paint_matrix, px_center_offset,
|
|
||||||
stfb->height - 1.0f + px_center_offset);
|
|
||||||
matrix_scale(&shader->paint_matrix, 1.0f, -1.0f);
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef SHADER_H
|
|
||||||
#define SHADER_H
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
struct shader;
|
|
||||||
struct vg_paint;
|
|
||||||
struct vg_context;
|
|
||||||
struct vg_image;
|
|
||||||
struct matrix;
|
|
||||||
|
|
||||||
struct shader *shader_create(struct vg_context *context);
|
|
||||||
void shader_destroy(struct shader *shader);
|
|
||||||
|
|
||||||
void shader_set_color_transform(struct shader *shader, VGboolean set);
|
|
||||||
|
|
||||||
void shader_set_masking(struct shader *shader, VGboolean set);
|
|
||||||
VGboolean shader_is_masking(struct shader *shader);
|
|
||||||
|
|
||||||
void shader_set_paint(struct shader *shader, struct vg_paint *paint);
|
|
||||||
struct vg_paint *shader_paint(struct shader *shader);
|
|
||||||
|
|
||||||
void shader_set_image_mode(struct shader *shader, VGImageMode image_mode);
|
|
||||||
VGImageMode shader_image_mode(struct shader *shader);
|
|
||||||
|
|
||||||
void shader_set_drawing_image(struct shader *shader, VGboolean drawing_image);
|
|
||||||
VGboolean shader_drawing_image(struct shader *shader);
|
|
||||||
|
|
||||||
void shader_set_image(struct shader *shader, struct vg_image *img);
|
|
||||||
|
|
||||||
void shader_set_surface_matrix(struct shader *shader,
|
|
||||||
const struct matrix *mat);
|
|
||||||
void shader_set_paint_matrix(struct shader *shader, const struct matrix *mat);
|
|
||||||
|
|
||||||
void shader_bind(struct shader *shader);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,462 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "shaders_cache.h"
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_shader_tokens.h"
|
|
||||||
|
|
||||||
#include "tgsi/tgsi_build.h"
|
|
||||||
#include "tgsi/tgsi_dump.h"
|
|
||||||
#include "tgsi/tgsi_parse.h"
|
|
||||||
#include "tgsi/tgsi_util.h"
|
|
||||||
#include "tgsi/tgsi_text.h"
|
|
||||||
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
#include "util/u_debug.h"
|
|
||||||
#include "cso_cache/cso_hash.h"
|
|
||||||
#include "cso_cache/cso_context.h"
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "asm_fill.h"
|
|
||||||
|
|
||||||
/* Essentially we construct an ubber-shader based on the state
|
|
||||||
* of the pipeline. The stages are:
|
|
||||||
* 1) Paint generation (color/gradient/pattern)
|
|
||||||
* 2) Image composition (normal/multiply/stencil)
|
|
||||||
* 3) Color transform
|
|
||||||
* 4) Per-channel alpha generation
|
|
||||||
* 5) Extended blend (multiply/screen/darken/lighten)
|
|
||||||
* 6) Mask
|
|
||||||
* 7) Premultiply/Unpremultiply
|
|
||||||
* 8) Color transform (to black and white)
|
|
||||||
*/
|
|
||||||
#define SHADER_STAGES 8
|
|
||||||
|
|
||||||
struct cached_shader {
|
|
||||||
void *driver_shader;
|
|
||||||
struct pipe_shader_state state;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct shaders_cache {
|
|
||||||
struct vg_context *pipe;
|
|
||||||
|
|
||||||
struct cso_hash *hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE struct tgsi_token *tokens_from_assembly(const char *txt, int num_tokens)
|
|
||||||
{
|
|
||||||
struct tgsi_token *tokens;
|
|
||||||
|
|
||||||
tokens = (struct tgsi_token *) MALLOC(num_tokens * sizeof(tokens[0]));
|
|
||||||
|
|
||||||
tgsi_text_translate(txt, tokens, num_tokens);
|
|
||||||
|
|
||||||
#if DEBUG_SHADERS
|
|
||||||
tgsi_dump(tokens, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
static const char max_shader_preamble[] =
|
|
||||||
"FRAG\n"
|
|
||||||
"DCL IN[0], POSITION, LINEAR\n"
|
|
||||||
"DCL IN[1], GENERIC[0], PERSPECTIVE\n"
|
|
||||||
"DCL OUT[0], COLOR, CONSTANT\n"
|
|
||||||
"DCL CONST[0..9], CONSTANT\n"
|
|
||||||
"DCL TEMP[0..9], CONSTANT\n"
|
|
||||||
"DCL SAMP[0..9], CONSTANT\n";
|
|
||||||
|
|
||||||
max_shader_preamble strlen == 175
|
|
||||||
*/
|
|
||||||
#define MAX_PREAMBLE 175
|
|
||||||
|
|
||||||
static INLINE VGint range_min(VGint min, VGint current)
|
|
||||||
{
|
|
||||||
if (min < 0)
|
|
||||||
min = current;
|
|
||||||
else
|
|
||||||
min = MIN2(min, current);
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGint range_max(VGint max, VGint current)
|
|
||||||
{
|
|
||||||
return MAX2(max, current);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
combine_shaders(const struct shader_asm_info *shaders[SHADER_STAGES], int num_shaders,
|
|
||||||
struct pipe_context *pipe,
|
|
||||||
struct pipe_shader_state *shader)
|
|
||||||
{
|
|
||||||
VGboolean declare_input = VG_FALSE;
|
|
||||||
VGint start_const = -1, end_const = 0;
|
|
||||||
VGint start_temp = -1, end_temp = 0;
|
|
||||||
VGint start_sampler = -1, end_sampler = 0;
|
|
||||||
VGint i, current_shader = 0;
|
|
||||||
VGint num_consts, num_temps, num_samplers;
|
|
||||||
struct ureg_program *ureg;
|
|
||||||
struct ureg_src in[2];
|
|
||||||
struct ureg_src *sampler = NULL;
|
|
||||||
struct ureg_src *constant = NULL;
|
|
||||||
struct ureg_dst out, *temp = NULL;
|
|
||||||
void *p = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < num_shaders; ++i) {
|
|
||||||
if (shaders[i]->num_consts)
|
|
||||||
start_const = range_min(start_const, shaders[i]->start_const);
|
|
||||||
if (shaders[i]->num_temps)
|
|
||||||
start_temp = range_min(start_temp, shaders[i]->start_temp);
|
|
||||||
if (shaders[i]->num_samplers)
|
|
||||||
start_sampler = range_min(start_sampler, shaders[i]->start_sampler);
|
|
||||||
|
|
||||||
end_const = range_max(end_const, shaders[i]->start_const +
|
|
||||||
shaders[i]->num_consts);
|
|
||||||
end_temp = range_max(end_temp, shaders[i]->start_temp +
|
|
||||||
shaders[i]->num_temps);
|
|
||||||
end_sampler = range_max(end_sampler, shaders[i]->start_sampler +
|
|
||||||
shaders[i]->num_samplers);
|
|
||||||
if (shaders[i]->needs_position)
|
|
||||||
declare_input = VG_TRUE;
|
|
||||||
}
|
|
||||||
/* if they're still unitialized, initialize them */
|
|
||||||
if (start_const < 0)
|
|
||||||
start_const = 0;
|
|
||||||
if (start_temp < 0)
|
|
||||||
start_temp = 0;
|
|
||||||
if (start_sampler < 0)
|
|
||||||
start_sampler = 0;
|
|
||||||
|
|
||||||
num_consts = end_const - start_const;
|
|
||||||
num_temps = end_temp - start_temp;
|
|
||||||
num_samplers = end_sampler - start_sampler;
|
|
||||||
|
|
||||||
ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
|
|
||||||
if (!ureg)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (declare_input) {
|
|
||||||
in[0] = ureg_DECL_fs_input(ureg,
|
|
||||||
TGSI_SEMANTIC_POSITION,
|
|
||||||
0,
|
|
||||||
TGSI_INTERPOLATE_LINEAR);
|
|
||||||
in[1] = ureg_DECL_fs_input(ureg,
|
|
||||||
TGSI_SEMANTIC_GENERIC,
|
|
||||||
0,
|
|
||||||
TGSI_INTERPOLATE_PERSPECTIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we always have a color output */
|
|
||||||
out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
|
|
||||||
|
|
||||||
if (num_consts >= 1) {
|
|
||||||
constant = malloc(sizeof(struct ureg_src) * end_const);
|
|
||||||
for (i = start_const; i < end_const; i++) {
|
|
||||||
constant[i] = ureg_DECL_constant(ureg, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_temps >= 1) {
|
|
||||||
temp = malloc(sizeof(struct ureg_dst) * end_temp);
|
|
||||||
for (i = start_temp; i < end_temp; i++) {
|
|
||||||
temp[i] = ureg_DECL_temporary(ureg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_samplers >= 1) {
|
|
||||||
sampler = malloc(sizeof(struct ureg_src) * end_sampler);
|
|
||||||
for (i = start_sampler; i < end_sampler; i++) {
|
|
||||||
sampler[i] = ureg_DECL_sampler(ureg, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (current_shader < num_shaders) {
|
|
||||||
if ((current_shader + 1) == num_shaders) {
|
|
||||||
shaders[current_shader]->func(ureg,
|
|
||||||
&out,
|
|
||||||
in,
|
|
||||||
sampler,
|
|
||||||
temp,
|
|
||||||
constant);
|
|
||||||
} else {
|
|
||||||
shaders[current_shader]->func(ureg,
|
|
||||||
&temp[0],
|
|
||||||
in,
|
|
||||||
sampler,
|
|
||||||
temp,
|
|
||||||
constant);
|
|
||||||
}
|
|
||||||
current_shader++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ureg_END(ureg);
|
|
||||||
|
|
||||||
shader->tokens = ureg_finalize(ureg);
|
|
||||||
if (!shader->tokens) {
|
|
||||||
ureg_destroy(ureg);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = pipe->create_fs_state(pipe, shader);
|
|
||||||
|
|
||||||
if (num_temps >= 1) {
|
|
||||||
for (i = start_temp; i < end_temp; i++) {
|
|
||||||
ureg_release_temporary(ureg, temp[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ureg_destroy(ureg);
|
|
||||||
|
|
||||||
free(temp);
|
|
||||||
free(constant);
|
|
||||||
free(sampler);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
create_shader(struct pipe_context *pipe,
|
|
||||||
int id,
|
|
||||||
struct pipe_shader_state *shader)
|
|
||||||
{
|
|
||||||
int idx = 0, sh;
|
|
||||||
const struct shader_asm_info * shaders[SHADER_STAGES];
|
|
||||||
|
|
||||||
/* first stage */
|
|
||||||
sh = SHADERS_GET_PAINT_SHADER(id);
|
|
||||||
switch (sh << SHADERS_PAINT_SHIFT) {
|
|
||||||
case VEGA_SOLID_FILL_SHADER:
|
|
||||||
case VEGA_LINEAR_GRADIENT_SHADER:
|
|
||||||
case VEGA_RADIAL_GRADIENT_SHADER:
|
|
||||||
case VEGA_PATTERN_SHADER:
|
|
||||||
case VEGA_PAINT_DEGENERATE_SHADER:
|
|
||||||
shaders[idx] = &shaders_paint_asm[(sh >> SHADERS_PAINT_SHIFT) - 1];
|
|
||||||
assert(shaders[idx]->id == sh);
|
|
||||||
idx++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* second stage */
|
|
||||||
sh = SHADERS_GET_IMAGE_SHADER(id);
|
|
||||||
switch (sh) {
|
|
||||||
case VEGA_IMAGE_NORMAL_SHADER:
|
|
||||||
case VEGA_IMAGE_MULTIPLY_SHADER:
|
|
||||||
case VEGA_IMAGE_STENCIL_SHADER:
|
|
||||||
shaders[idx] = &shaders_image_asm[(sh >> SHADERS_IMAGE_SHIFT) - 1];
|
|
||||||
assert(shaders[idx]->id == sh);
|
|
||||||
idx++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sanity check */
|
|
||||||
assert(idx == ((!sh || sh == VEGA_IMAGE_NORMAL_SHADER) ? 1 : 2));
|
|
||||||
|
|
||||||
/* third stage */
|
|
||||||
sh = SHADERS_GET_COLOR_TRANSFORM_SHADER(id);
|
|
||||||
switch (sh) {
|
|
||||||
case VEGA_COLOR_TRANSFORM_SHADER:
|
|
||||||
shaders[idx] = &shaders_color_transform_asm[
|
|
||||||
(sh >> SHADERS_COLOR_TRANSFORM_SHIFT) - 1];
|
|
||||||
assert(shaders[idx]->id == sh);
|
|
||||||
idx++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fourth stage */
|
|
||||||
sh = SHADERS_GET_ALPHA_SHADER(id);
|
|
||||||
switch (sh) {
|
|
||||||
case VEGA_ALPHA_NORMAL_SHADER:
|
|
||||||
case VEGA_ALPHA_PER_CHANNEL_SHADER:
|
|
||||||
shaders[idx] = &shaders_alpha_asm[
|
|
||||||
(sh >> SHADERS_ALPHA_SHIFT) - 1];
|
|
||||||
assert(shaders[idx]->id == sh);
|
|
||||||
idx++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fifth stage */
|
|
||||||
sh = SHADERS_GET_BLEND_SHADER(id);
|
|
||||||
switch (sh) {
|
|
||||||
case VEGA_BLEND_SRC_SHADER:
|
|
||||||
case VEGA_BLEND_SRC_OVER_SHADER:
|
|
||||||
case VEGA_BLEND_DST_OVER_SHADER:
|
|
||||||
case VEGA_BLEND_SRC_IN_SHADER:
|
|
||||||
case VEGA_BLEND_DST_IN_SHADER:
|
|
||||||
case VEGA_BLEND_MULTIPLY_SHADER:
|
|
||||||
case VEGA_BLEND_SCREEN_SHADER:
|
|
||||||
case VEGA_BLEND_DARKEN_SHADER:
|
|
||||||
case VEGA_BLEND_LIGHTEN_SHADER:
|
|
||||||
case VEGA_BLEND_ADDITIVE_SHADER:
|
|
||||||
shaders[idx] = &shaders_blend_asm[(sh >> SHADERS_BLEND_SHIFT) - 1];
|
|
||||||
assert(shaders[idx]->id == sh);
|
|
||||||
idx++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sixth stage */
|
|
||||||
sh = SHADERS_GET_MASK_SHADER(id);
|
|
||||||
switch (sh) {
|
|
||||||
case VEGA_MASK_SHADER:
|
|
||||||
shaders[idx] = &shaders_mask_asm[(sh >> SHADERS_MASK_SHIFT) - 1];
|
|
||||||
assert(shaders[idx]->id == sh);
|
|
||||||
idx++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* seventh stage */
|
|
||||||
sh = SHADERS_GET_PREMULTIPLY_SHADER(id);
|
|
||||||
switch (sh) {
|
|
||||||
case VEGA_PREMULTIPLY_SHADER:
|
|
||||||
case VEGA_UNPREMULTIPLY_SHADER:
|
|
||||||
shaders[idx] = &shaders_premultiply_asm[
|
|
||||||
(sh >> SHADERS_PREMULTIPLY_SHIFT) - 1];
|
|
||||||
assert(shaders[idx]->id == sh);
|
|
||||||
idx++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* eighth stage */
|
|
||||||
sh = SHADERS_GET_BW_SHADER(id);
|
|
||||||
switch (sh) {
|
|
||||||
case VEGA_BW_SHADER:
|
|
||||||
shaders[idx] = &shaders_bw_asm[(sh >> SHADERS_BW_SHIFT) - 1];
|
|
||||||
assert(shaders[idx]->id == sh);
|
|
||||||
idx++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return combine_shaders(shaders, idx, pipe, shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************/
|
|
||||||
|
|
||||||
struct shaders_cache * shaders_cache_create(struct vg_context *vg)
|
|
||||||
{
|
|
||||||
struct shaders_cache *sc = CALLOC_STRUCT(shaders_cache);
|
|
||||||
|
|
||||||
sc->pipe = vg;
|
|
||||||
sc->hash = cso_hash_create();
|
|
||||||
|
|
||||||
return sc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shaders_cache_destroy(struct shaders_cache *sc)
|
|
||||||
{
|
|
||||||
struct cso_hash_iter iter = cso_hash_first_node(sc->hash);
|
|
||||||
|
|
||||||
while (!cso_hash_iter_is_null(iter)) {
|
|
||||||
struct cached_shader *cached =
|
|
||||||
(struct cached_shader *)cso_hash_iter_data(iter);
|
|
||||||
cso_delete_fragment_shader(sc->pipe->cso_context,
|
|
||||||
cached->driver_shader);
|
|
||||||
iter = cso_hash_erase(sc->hash, iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
cso_hash_delete(sc->hash);
|
|
||||||
FREE(sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void * shaders_cache_fill(struct shaders_cache *sc,
|
|
||||||
int shader_key)
|
|
||||||
{
|
|
||||||
VGint key = shader_key;
|
|
||||||
struct cached_shader *cached;
|
|
||||||
struct cso_hash_iter iter = cso_hash_find(sc->hash, key);
|
|
||||||
|
|
||||||
if (cso_hash_iter_is_null(iter)) {
|
|
||||||
cached = CALLOC_STRUCT(cached_shader);
|
|
||||||
cached->driver_shader = create_shader(sc->pipe->pipe, key, &cached->state);
|
|
||||||
|
|
||||||
cso_hash_insert(sc->hash, key, cached);
|
|
||||||
|
|
||||||
return cached->driver_shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
cached = (struct cached_shader *)cso_hash_iter_data(iter);
|
|
||||||
|
|
||||||
assert(cached->driver_shader);
|
|
||||||
return cached->driver_shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vg_shader * shader_create_from_text(struct pipe_context *pipe,
|
|
||||||
const char *txt, int num_tokens,
|
|
||||||
int type)
|
|
||||||
{
|
|
||||||
struct vg_shader *shader = (struct vg_shader *)MALLOC(
|
|
||||||
sizeof(struct vg_shader));
|
|
||||||
struct tgsi_token *tokens = tokens_from_assembly(txt, num_tokens);
|
|
||||||
struct pipe_shader_state state;
|
|
||||||
|
|
||||||
debug_assert(type == PIPE_SHADER_VERTEX ||
|
|
||||||
type == PIPE_SHADER_FRAGMENT);
|
|
||||||
|
|
||||||
state.tokens = tokens;
|
|
||||||
memset(&state.stream_output, 0, sizeof(state.stream_output));
|
|
||||||
shader->type = type;
|
|
||||||
shader->tokens = tokens;
|
|
||||||
|
|
||||||
if (type == PIPE_SHADER_FRAGMENT)
|
|
||||||
shader->driver = pipe->create_fs_state(pipe, &state);
|
|
||||||
else
|
|
||||||
shader->driver = pipe->create_vs_state(pipe, &state);
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vg_shader_destroy(struct vg_context *ctx, struct vg_shader *shader)
|
|
||||||
{
|
|
||||||
if (shader->type == PIPE_SHADER_FRAGMENT)
|
|
||||||
cso_delete_fragment_shader(ctx->cso_context, shader->driver);
|
|
||||||
else
|
|
||||||
cso_delete_vertex_shader(ctx->cso_context, shader->driver);
|
|
||||||
FREE(shader->tokens);
|
|
||||||
FREE(shader);
|
|
||||||
}
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef SHADERS_CACHE_H
|
|
||||||
#define SHADERS_CACHE_H
|
|
||||||
|
|
||||||
|
|
||||||
struct vg_context;
|
|
||||||
struct pipe_context;
|
|
||||||
struct tgsi_token;
|
|
||||||
struct shaders_cache;
|
|
||||||
|
|
||||||
#define _SHADERS_PAINT_BITS 3
|
|
||||||
#define _SHADERS_IMAGE_BITS 2
|
|
||||||
#define _SHADERS_COLOR_TRANSFORM_BITS 1
|
|
||||||
#define _SHADERS_ALPHA_BITS 2
|
|
||||||
#define _SHADERS_BLEND_BITS 4
|
|
||||||
#define _SHADERS_MASK_BITS 1
|
|
||||||
#define _SHADERS_PREMULTIPLY_BITS 2
|
|
||||||
#define _SHADERS_BW_BITS 1
|
|
||||||
|
|
||||||
#define SHADERS_PAINT_SHIFT (0)
|
|
||||||
#define SHADERS_IMAGE_SHIFT (SHADERS_PAINT_SHIFT + _SHADERS_PAINT_BITS)
|
|
||||||
#define SHADERS_COLOR_TRANSFORM_SHIFT (SHADERS_IMAGE_SHIFT + _SHADERS_IMAGE_BITS)
|
|
||||||
#define SHADERS_ALPHA_SHIFT (SHADERS_COLOR_TRANSFORM_SHIFT + _SHADERS_COLOR_TRANSFORM_BITS)
|
|
||||||
#define SHADERS_BLEND_SHIFT (SHADERS_ALPHA_SHIFT + _SHADERS_ALPHA_BITS)
|
|
||||||
#define SHADERS_MASK_SHIFT (SHADERS_BLEND_SHIFT + _SHADERS_BLEND_BITS)
|
|
||||||
#define SHADERS_PREMULTIPLY_SHIFT (SHADERS_MASK_SHIFT + _SHADERS_MASK_BITS)
|
|
||||||
#define SHADERS_BW_SHIFT (SHADERS_PREMULTIPLY_SHIFT + _SHADERS_PREMULTIPLY_BITS)
|
|
||||||
|
|
||||||
#define _SHADERS_GET_STAGE(stage, id) \
|
|
||||||
((id) & (((1 << _SHADERS_ ## stage ## _BITS) - 1) << SHADERS_ ## stage ## _SHIFT))
|
|
||||||
|
|
||||||
#define SHADERS_GET_PAINT_SHADER(id) _SHADERS_GET_STAGE(PAINT, id)
|
|
||||||
#define SHADERS_GET_IMAGE_SHADER(id) _SHADERS_GET_STAGE(IMAGE, id)
|
|
||||||
#define SHADERS_GET_COLOR_TRANSFORM_SHADER(id) _SHADERS_GET_STAGE(COLOR_TRANSFORM, id)
|
|
||||||
#define SHADERS_GET_ALPHA_SHADER(id) _SHADERS_GET_STAGE(ALPHA, id)
|
|
||||||
#define SHADERS_GET_BLEND_SHADER(id) _SHADERS_GET_STAGE(BLEND, id)
|
|
||||||
#define SHADERS_GET_MASK_SHADER(id) _SHADERS_GET_STAGE(MASK, id)
|
|
||||||
#define SHADERS_GET_PREMULTIPLY_SHADER(id) _SHADERS_GET_STAGE(PREMULTIPLY, id)
|
|
||||||
#define SHADERS_GET_BW_SHADER(id) _SHADERS_GET_STAGE(BW, id)
|
|
||||||
|
|
||||||
enum VegaShaderType {
|
|
||||||
VEGA_SOLID_FILL_SHADER = 1 << SHADERS_PAINT_SHIFT,
|
|
||||||
VEGA_LINEAR_GRADIENT_SHADER = 2 << SHADERS_PAINT_SHIFT,
|
|
||||||
VEGA_RADIAL_GRADIENT_SHADER = 3 << SHADERS_PAINT_SHIFT,
|
|
||||||
VEGA_PATTERN_SHADER = 4 << SHADERS_PAINT_SHIFT,
|
|
||||||
VEGA_PAINT_DEGENERATE_SHADER = 5 << SHADERS_PAINT_SHIFT,
|
|
||||||
|
|
||||||
VEGA_IMAGE_NORMAL_SHADER = 1 << SHADERS_IMAGE_SHIFT,
|
|
||||||
VEGA_IMAGE_MULTIPLY_SHADER = 2 << SHADERS_IMAGE_SHIFT,
|
|
||||||
VEGA_IMAGE_STENCIL_SHADER = 3 << SHADERS_IMAGE_SHIFT,
|
|
||||||
|
|
||||||
VEGA_COLOR_TRANSFORM_SHADER = 1 << SHADERS_COLOR_TRANSFORM_SHIFT,
|
|
||||||
|
|
||||||
VEGA_ALPHA_NORMAL_SHADER = 1 << SHADERS_ALPHA_SHIFT,
|
|
||||||
VEGA_ALPHA_PER_CHANNEL_SHADER = 2 << SHADERS_ALPHA_SHIFT,
|
|
||||||
|
|
||||||
VEGA_BLEND_SRC_SHADER = 1 << SHADERS_BLEND_SHIFT,
|
|
||||||
VEGA_BLEND_SRC_OVER_SHADER = 2 << SHADERS_BLEND_SHIFT,
|
|
||||||
VEGA_BLEND_DST_OVER_SHADER = 3 << SHADERS_BLEND_SHIFT,
|
|
||||||
VEGA_BLEND_SRC_IN_SHADER = 4 << SHADERS_BLEND_SHIFT,
|
|
||||||
VEGA_BLEND_DST_IN_SHADER = 5 << SHADERS_BLEND_SHIFT,
|
|
||||||
VEGA_BLEND_MULTIPLY_SHADER = 6 << SHADERS_BLEND_SHIFT,
|
|
||||||
VEGA_BLEND_SCREEN_SHADER = 7 << SHADERS_BLEND_SHIFT,
|
|
||||||
VEGA_BLEND_DARKEN_SHADER = 8 << SHADERS_BLEND_SHIFT,
|
|
||||||
VEGA_BLEND_LIGHTEN_SHADER = 9 << SHADERS_BLEND_SHIFT,
|
|
||||||
VEGA_BLEND_ADDITIVE_SHADER = 10<< SHADERS_BLEND_SHIFT,
|
|
||||||
|
|
||||||
VEGA_MASK_SHADER = 1 << SHADERS_MASK_SHIFT,
|
|
||||||
|
|
||||||
VEGA_PREMULTIPLY_SHADER = 1 << SHADERS_PREMULTIPLY_SHIFT,
|
|
||||||
VEGA_UNPREMULTIPLY_SHADER = 2 << SHADERS_PREMULTIPLY_SHIFT,
|
|
||||||
|
|
||||||
VEGA_BW_SHADER = 1 << SHADERS_BW_SHIFT
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vg_shader {
|
|
||||||
void *driver;
|
|
||||||
struct tgsi_token *tokens;
|
|
||||||
int type;/* PIPE_SHADER_VERTEX, PIPE_SHADER_FRAGMENT */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct shaders_cache *shaders_cache_create(struct vg_context *pipe);
|
|
||||||
void shaders_cache_destroy(struct shaders_cache *sc);
|
|
||||||
void *shaders_cache_fill(struct shaders_cache *sc,
|
|
||||||
int shader_key);
|
|
||||||
|
|
||||||
struct vg_shader *shader_create_from_text(struct pipe_context *pipe,
|
|
||||||
const char *txt, int num_tokens,
|
|
||||||
int type);
|
|
||||||
|
|
||||||
void vg_shader_destroy(struct vg_context *ctx, struct vg_shader *shader);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,89 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef STROKER_H
|
|
||||||
#define STROKER_H
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
#include "api_consts.h"
|
|
||||||
|
|
||||||
struct path;
|
|
||||||
struct vg_state;
|
|
||||||
struct array;
|
|
||||||
|
|
||||||
struct stroker {
|
|
||||||
void (*begin)(struct stroker *stroker);
|
|
||||||
void (*process_subpath)(struct stroker *stroker);
|
|
||||||
void (*end)(struct stroker *stroker);
|
|
||||||
|
|
||||||
struct array *segments;
|
|
||||||
struct array *control_points;
|
|
||||||
struct path *path;
|
|
||||||
|
|
||||||
VGfloat back1_x, back1_y;
|
|
||||||
VGfloat back2_x, back2_y;
|
|
||||||
|
|
||||||
VGfloat stroke_width;
|
|
||||||
VGfloat miter_limit;
|
|
||||||
VGCapStyle cap_style;
|
|
||||||
VGJoinStyle join_style;
|
|
||||||
|
|
||||||
VGPathCommand last_cmd;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dash_stroker {
|
|
||||||
struct stroker base;
|
|
||||||
|
|
||||||
struct stroker stroker;
|
|
||||||
|
|
||||||
VGfloat dash_pattern[VEGA_MAX_DASH_COUNT];
|
|
||||||
VGint dash_pattern_num;
|
|
||||||
VGfloat dash_phase;
|
|
||||||
VGboolean dash_phase_reset;
|
|
||||||
};
|
|
||||||
|
|
||||||
void stroker_init(struct stroker *stroker,
|
|
||||||
struct vg_state *state);
|
|
||||||
void dash_stroker_init(struct stroker *stroker,
|
|
||||||
struct vg_state *state);
|
|
||||||
void dash_stroker_cleanup(struct dash_stroker *stroker);
|
|
||||||
void stroker_cleanup(struct stroker *stroker);
|
|
||||||
|
|
||||||
void stroker_begin(struct stroker *stroker);
|
|
||||||
void stroker_move_to(struct stroker *stroker, VGfloat x, VGfloat y);
|
|
||||||
void stroker_line_to(struct stroker *stroker, VGfloat x, VGfloat y);
|
|
||||||
void stroker_curve_to(struct stroker *stroker, VGfloat px1, VGfloat py1,
|
|
||||||
VGfloat px2, VGfloat py2,
|
|
||||||
VGfloat x, VGfloat y);
|
|
||||||
void stroker_end(struct stroker *stroker);
|
|
||||||
|
|
||||||
void stroker_emit_move_to(struct stroker *stroker, VGfloat x, VGfloat y);
|
|
||||||
void stroker_emit_line_to(struct stroker *stroker, VGfloat x, VGfloat y);
|
|
||||||
void stroker_emit_curve_to(struct stroker *stroker, VGfloat px1, VGfloat py1,
|
|
||||||
VGfloat px2, VGfloat py2,
|
|
||||||
VGfloat x, VGfloat y);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,250 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2010 LunarG, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
#include "cso_cache/cso_hash.h"
|
|
||||||
|
|
||||||
#include "text.h"
|
|
||||||
#include "image.h"
|
|
||||||
#include "path.h"
|
|
||||||
|
|
||||||
#ifdef OPENVG_VERSION_1_1
|
|
||||||
|
|
||||||
struct vg_font {
|
|
||||||
struct vg_object base;
|
|
||||||
struct cso_hash *glyphs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vg_glyph {
|
|
||||||
struct vg_object *object; /* it could be NULL */
|
|
||||||
VGboolean is_hinted;
|
|
||||||
VGfloat glyph_origin[2];
|
|
||||||
VGfloat escapement[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
static VGboolean del_glyph(struct vg_font *font,
|
|
||||||
VGuint glyphIndex)
|
|
||||||
{
|
|
||||||
struct vg_glyph *glyph;
|
|
||||||
|
|
||||||
glyph = (struct vg_glyph *)
|
|
||||||
cso_hash_take(font->glyphs, (unsigned) glyphIndex);
|
|
||||||
FREE(glyph);
|
|
||||||
|
|
||||||
return (glyph != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_glyph(struct vg_font *font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
struct vg_object *obj,
|
|
||||||
VGboolean isHinted,
|
|
||||||
const VGfloat glyphOrigin[2],
|
|
||||||
const VGfloat escapement[2])
|
|
||||||
{
|
|
||||||
struct vg_glyph *glyph;
|
|
||||||
|
|
||||||
/* remove the existing one */
|
|
||||||
del_glyph(font, glyphIndex);
|
|
||||||
|
|
||||||
glyph = CALLOC_STRUCT(vg_glyph);
|
|
||||||
glyph->object = obj;
|
|
||||||
glyph->is_hinted = isHinted;
|
|
||||||
memcpy(glyph->glyph_origin, glyphOrigin, sizeof(glyph->glyph_origin));
|
|
||||||
memcpy(glyph->escapement, escapement, sizeof(glyph->glyph_origin));
|
|
||||||
|
|
||||||
cso_hash_insert(font->glyphs, (unsigned) glyphIndex, glyph);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct vg_glyph *get_glyph(struct vg_font *font,
|
|
||||||
VGuint glyphIndex)
|
|
||||||
{
|
|
||||||
struct cso_hash_iter iter;
|
|
||||||
|
|
||||||
iter = cso_hash_find(font->glyphs, (unsigned) glyphIndex);
|
|
||||||
return (struct vg_glyph *) cso_hash_iter_data(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vg_render_glyph(struct vg_context *ctx,
|
|
||||||
struct vg_glyph *glyph,
|
|
||||||
VGbitfield paintModes,
|
|
||||||
VGboolean allowAutoHinting)
|
|
||||||
{
|
|
||||||
if (glyph->object && paintModes) {
|
|
||||||
struct vg_state *state = &ctx->state.vg;
|
|
||||||
struct matrix m;
|
|
||||||
|
|
||||||
m = state->glyph_user_to_surface_matrix;
|
|
||||||
matrix_translate(&m,
|
|
||||||
state->glyph_origin[0].f - glyph->glyph_origin[0],
|
|
||||||
state->glyph_origin[1].f - glyph->glyph_origin[1]);
|
|
||||||
|
|
||||||
if (glyph->object->type == VG_OBJECT_PATH) {
|
|
||||||
path_render((struct path *) glyph->object, paintModes, &m);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(glyph->object->type == VG_OBJECT_IMAGE);
|
|
||||||
image_draw((struct vg_image *) glyph->object, &m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vg_advance_glyph(struct vg_context *ctx,
|
|
||||||
struct vg_glyph *glyph,
|
|
||||||
VGfloat adjustment_x,
|
|
||||||
VGfloat adjustment_y,
|
|
||||||
VGboolean last)
|
|
||||||
{
|
|
||||||
struct vg_value *glyph_origin = ctx->state.vg.glyph_origin;
|
|
||||||
|
|
||||||
glyph_origin[0].f += glyph->escapement[0] + adjustment_x;
|
|
||||||
glyph_origin[1].f += glyph->escapement[1] + adjustment_y;
|
|
||||||
|
|
||||||
if (last) {
|
|
||||||
glyph_origin[0].i = float_to_int_floor(glyph_origin[0].f);
|
|
||||||
glyph_origin[1].i = float_to_int_floor(glyph_origin[1].f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vg_font *font_create(VGint glyphCapacityHint)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_font *font;
|
|
||||||
|
|
||||||
font = CALLOC_STRUCT(vg_font);
|
|
||||||
vg_init_object(&font->base, ctx, VG_OBJECT_FONT);
|
|
||||||
font->glyphs = cso_hash_create();
|
|
||||||
|
|
||||||
vg_context_add_object(ctx, &font->base);
|
|
||||||
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
|
|
||||||
void font_destroy(struct vg_font *font)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct cso_hash_iter iter;
|
|
||||||
|
|
||||||
vg_context_remove_object(ctx, &font->base);
|
|
||||||
|
|
||||||
iter = cso_hash_first_node(font->glyphs);
|
|
||||||
while (!cso_hash_iter_is_null(iter)) {
|
|
||||||
struct vg_glyph *glyph = (struct vg_glyph *) cso_hash_iter_data(iter);
|
|
||||||
FREE(glyph);
|
|
||||||
iter = cso_hash_iter_next(iter);
|
|
||||||
}
|
|
||||||
cso_hash_delete(font->glyphs);
|
|
||||||
|
|
||||||
vg_free_object(&font->base);
|
|
||||||
|
|
||||||
FREE(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
void font_set_glyph_to_path(struct vg_font *font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
struct path *path,
|
|
||||||
VGboolean isHinted,
|
|
||||||
const VGfloat glyphOrigin[2],
|
|
||||||
const VGfloat escapement[2])
|
|
||||||
{
|
|
||||||
add_glyph(font, glyphIndex, (struct vg_object *) path,
|
|
||||||
isHinted, glyphOrigin, escapement);
|
|
||||||
}
|
|
||||||
|
|
||||||
void font_set_glyph_to_image(struct vg_font *font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
struct vg_image *image,
|
|
||||||
const VGfloat glyphOrigin[2],
|
|
||||||
const VGfloat escapement[2])
|
|
||||||
{
|
|
||||||
add_glyph(font, glyphIndex, (struct vg_object *) image,
|
|
||||||
VG_TRUE, glyphOrigin, escapement);
|
|
||||||
}
|
|
||||||
|
|
||||||
void font_clear_glyph(struct vg_font *font,
|
|
||||||
VGuint glyphIndex)
|
|
||||||
{
|
|
||||||
if (!del_glyph(font, glyphIndex)) {
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void font_draw_glyph(struct vg_font *font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
VGbitfield paintModes,
|
|
||||||
VGboolean allowAutoHinting)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
struct vg_glyph *glyph;
|
|
||||||
|
|
||||||
glyph = get_glyph(font, glyphIndex);
|
|
||||||
if (!glyph) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_render_glyph(ctx, glyph, paintModes, allowAutoHinting);
|
|
||||||
vg_advance_glyph(ctx, glyph, 0.0f, 0.0f, VG_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void font_draw_glyphs(struct vg_font *font,
|
|
||||||
VGint glyphCount,
|
|
||||||
const VGuint *glyphIndices,
|
|
||||||
const VGfloat *adjustments_x,
|
|
||||||
const VGfloat *adjustments_y,
|
|
||||||
VGbitfield paintModes,
|
|
||||||
VGboolean allowAutoHinting)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
VGint i;
|
|
||||||
|
|
||||||
for (i = 0; i < glyphCount; ++i) {
|
|
||||||
if (!get_glyph(font, glyphIndices[i])) {
|
|
||||||
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < glyphCount; ++i) {
|
|
||||||
struct vg_glyph *glyph;
|
|
||||||
VGfloat adj_x, adj_y;
|
|
||||||
|
|
||||||
glyph = get_glyph(font, glyphIndices[i]);
|
|
||||||
|
|
||||||
vg_render_glyph(ctx, glyph, paintModes, allowAutoHinting);
|
|
||||||
|
|
||||||
adj_x = (adjustments_x) ? adjustments_x[i] : 0.0f;
|
|
||||||
adj_y = (adjustments_y) ? adjustments_y[i] : 0.0f;
|
|
||||||
vg_advance_glyph(ctx, glyph, adj_x, adj_y, (i == glyphCount - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VGint font_num_glyphs(struct vg_font *font)
|
|
||||||
{
|
|
||||||
return cso_hash_size(font->glyphs);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* OPENVG_VERSION_1_1 */
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2010 LunarG, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _TEXT_H
|
|
||||||
#define _TEXT_H
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "cso_cache/cso_hash.h"
|
|
||||||
|
|
||||||
struct vg_font;
|
|
||||||
struct vg_image;
|
|
||||||
struct path;
|
|
||||||
|
|
||||||
struct vg_font *font_create(VGint glyphCapacityHint);
|
|
||||||
void font_destroy(struct vg_font *font);
|
|
||||||
|
|
||||||
void font_set_glyph_to_path(struct vg_font *font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
struct path *path,
|
|
||||||
VGboolean isHinted,
|
|
||||||
const VGfloat glyphOrigin[2],
|
|
||||||
const VGfloat escapement[2]);
|
|
||||||
|
|
||||||
void font_set_glyph_to_image(struct vg_font *font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
struct vg_image *image,
|
|
||||||
const VGfloat glyphOrigin[2],
|
|
||||||
const VGfloat escapement[2]);
|
|
||||||
|
|
||||||
void font_clear_glyph(struct vg_font *font,
|
|
||||||
VGuint glyphIndex);
|
|
||||||
|
|
||||||
void font_draw_glyph(struct vg_font *font,
|
|
||||||
VGuint glyphIndex,
|
|
||||||
VGbitfield paintModes,
|
|
||||||
VGboolean allowAutoHinting);
|
|
||||||
|
|
||||||
void font_draw_glyphs(struct vg_font *font,
|
|
||||||
VGint glyphCount,
|
|
||||||
const VGuint *glyphIndices,
|
|
||||||
const VGfloat *adjustments_x,
|
|
||||||
const VGfloat *adjustments_y,
|
|
||||||
VGbitfield paintModes,
|
|
||||||
VGboolean allowAutoHinting);
|
|
||||||
|
|
||||||
VGint font_num_glyphs(struct vg_font *font);
|
|
||||||
|
|
||||||
#endif /* _TEXT_H */
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef UTIL_ARRAY_H
|
|
||||||
#define UTIL_ARRAY_H
|
|
||||||
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
|
|
||||||
#define DEFAULT_ARRAY_SIZE 256
|
|
||||||
|
|
||||||
struct array {
|
|
||||||
VGint datatype_size;
|
|
||||||
void *data;
|
|
||||||
VGint size;
|
|
||||||
VGint num_elements;
|
|
||||||
};
|
|
||||||
|
|
||||||
static INLINE struct array *array_create(VGint datatype_size)
|
|
||||||
{
|
|
||||||
struct array *array = CALLOC_STRUCT(array);
|
|
||||||
array->datatype_size = datatype_size;
|
|
||||||
|
|
||||||
array->size = DEFAULT_ARRAY_SIZE;
|
|
||||||
array->data = malloc(array->size * array->datatype_size);
|
|
||||||
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE struct array *array_create_size(VGint datatype_size, VGint size)
|
|
||||||
{
|
|
||||||
struct array *array = CALLOC_STRUCT(array);
|
|
||||||
array->datatype_size = datatype_size;
|
|
||||||
|
|
||||||
array->size = size;
|
|
||||||
array->data = malloc(array->size * array->datatype_size);
|
|
||||||
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void array_destroy(struct array *array)
|
|
||||||
{
|
|
||||||
if (array)
|
|
||||||
free(array->data);
|
|
||||||
FREE(array);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void array_resize(struct array *array, int num)
|
|
||||||
{
|
|
||||||
VGint size = array->datatype_size * num;
|
|
||||||
void *data = malloc(size);
|
|
||||||
memcpy(data, array->data, array->size * array->datatype_size);
|
|
||||||
free(array->data);
|
|
||||||
array->data = data;
|
|
||||||
array->size = num;
|
|
||||||
array->num_elements = (array->num_elements > num) ? num :
|
|
||||||
array->num_elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void array_append_data(struct array *array,
|
|
||||||
const void *data, int num_elements)
|
|
||||||
{
|
|
||||||
VGbyte *adata;
|
|
||||||
|
|
||||||
while (array->num_elements + num_elements > array->size) {
|
|
||||||
array_resize(array, (array->num_elements + num_elements) * 1.5);
|
|
||||||
}
|
|
||||||
adata = (VGbyte *)array->data;
|
|
||||||
memcpy(adata + (array->num_elements * array->datatype_size), data,
|
|
||||||
num_elements * array->datatype_size);
|
|
||||||
array->num_elements += num_elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void array_change_data(struct array *array,
|
|
||||||
const void *data,
|
|
||||||
int start_idx,
|
|
||||||
int num_elements)
|
|
||||||
{
|
|
||||||
VGbyte *adata = (VGbyte *)array->data;
|
|
||||||
memcpy(adata + (start_idx * array->datatype_size), data,
|
|
||||||
num_elements * array->datatype_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void array_remove_element(struct array *array,
|
|
||||||
int idx)
|
|
||||||
{
|
|
||||||
VGbyte *adata = (VGbyte *)array->data;
|
|
||||||
memmove(adata + (idx * array->datatype_size),
|
|
||||||
adata + ((idx + 1) * array->datatype_size),
|
|
||||||
(array->num_elements - idx - 1) * array->datatype_size);
|
|
||||||
--array->num_elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void array_reset(struct array *array)
|
|
||||||
{
|
|
||||||
array->num_elements = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* Mesa 3-D graphics library
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 LunarG Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Chia-I Wu <olv@lunarg.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VG_API_H
|
|
||||||
#define VG_API_H
|
|
||||||
|
|
||||||
struct st_api;
|
|
||||||
|
|
||||||
const struct st_api *
|
|
||||||
vg_api_get(void);
|
|
||||||
|
|
||||||
#endif /* VG_API_H */
|
|
||||||
|
|
@ -1,537 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "vg_context.h"
|
|
||||||
|
|
||||||
#include "paint.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
#include "shaders_cache.h"
|
|
||||||
#include "shader.h"
|
|
||||||
#include "vg_manager.h"
|
|
||||||
#include "api.h"
|
|
||||||
#include "mask.h"
|
|
||||||
#include "handle.h"
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
|
|
||||||
#include "cso_cache/cso_context.h"
|
|
||||||
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
#include "util/u_sampler.h"
|
|
||||||
#include "util/u_surface.h"
|
|
||||||
#include "util/u_format.h"
|
|
||||||
|
|
||||||
struct vg_context *_vg_context = 0;
|
|
||||||
|
|
||||||
struct vg_context * vg_current_context(void)
|
|
||||||
{
|
|
||||||
return _vg_context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A depth/stencil rb will be needed regardless of what the visual says.
|
|
||||||
*/
|
|
||||||
static boolean
|
|
||||||
choose_depth_stencil_format(struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
struct pipe_screen *screen = ctx->pipe->screen;
|
|
||||||
enum pipe_format formats[] = {
|
|
||||||
PIPE_FORMAT_Z24_UNORM_S8_UINT,
|
|
||||||
PIPE_FORMAT_S8_UINT_Z24_UNORM,
|
|
||||||
PIPE_FORMAT_NONE
|
|
||||||
};
|
|
||||||
enum pipe_format *fmt;
|
|
||||||
|
|
||||||
for (fmt = formats; *fmt != PIPE_FORMAT_NONE; fmt++) {
|
|
||||||
if (screen->is_format_supported(screen, *fmt,
|
|
||||||
PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->ds_format = *fmt;
|
|
||||||
|
|
||||||
return (ctx->ds_format != PIPE_FORMAT_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vg_set_current_context(struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
_vg_context = ctx;
|
|
||||||
api_make_dispatch_current((ctx) ? ctx->dispatch : NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vg_context * vg_create_context(struct pipe_context *pipe,
|
|
||||||
const void *visual,
|
|
||||||
struct vg_context *share)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx;
|
|
||||||
|
|
||||||
ctx = CALLOC_STRUCT(vg_context);
|
|
||||||
|
|
||||||
ctx->pipe = pipe;
|
|
||||||
if (!choose_depth_stencil_format(ctx)) {
|
|
||||||
FREE(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->dispatch = api_create_dispatch();
|
|
||||||
|
|
||||||
vg_init_state(&ctx->state.vg);
|
|
||||||
ctx->state.dirty = ALL_DIRTY;
|
|
||||||
|
|
||||||
ctx->cso_context = cso_create_context(pipe);
|
|
||||||
|
|
||||||
ctx->default_paint = paint_create(ctx);
|
|
||||||
ctx->state.vg.stroke_paint = ctx->default_paint;
|
|
||||||
ctx->state.vg.fill_paint = ctx->default_paint;
|
|
||||||
|
|
||||||
|
|
||||||
ctx->mask.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
ctx->mask.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
ctx->mask.sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
ctx->mask.sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
|
||||||
ctx->mask.sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
|
|
||||||
ctx->mask.sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
|
|
||||||
ctx->mask.sampler.normalized_coords = 0;
|
|
||||||
|
|
||||||
ctx->blend_sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
ctx->blend_sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
ctx->blend_sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
||||||
ctx->blend_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
|
||||||
ctx->blend_sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
|
|
||||||
ctx->blend_sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
|
|
||||||
ctx->blend_sampler.normalized_coords = 0;
|
|
||||||
|
|
||||||
vg_set_error(ctx, VG_NO_ERROR);
|
|
||||||
|
|
||||||
ctx->owned_objects[VG_OBJECT_PAINT] = cso_hash_create();
|
|
||||||
ctx->owned_objects[VG_OBJECT_IMAGE] = cso_hash_create();
|
|
||||||
ctx->owned_objects[VG_OBJECT_MASK] = cso_hash_create();
|
|
||||||
ctx->owned_objects[VG_OBJECT_FONT] = cso_hash_create();
|
|
||||||
ctx->owned_objects[VG_OBJECT_PATH] = cso_hash_create();
|
|
||||||
|
|
||||||
ctx->renderer = renderer_create(ctx);
|
|
||||||
ctx->sc = shaders_cache_create(ctx);
|
|
||||||
ctx->shader = shader_create(ctx);
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vg_destroy_context(struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
struct pipe_resource **cbuf = &ctx->mask.cbuf;
|
|
||||||
|
|
||||||
renderer_destroy(ctx->renderer);
|
|
||||||
shaders_cache_destroy(ctx->sc);
|
|
||||||
shader_destroy(ctx->shader);
|
|
||||||
paint_destroy(ctx->default_paint);
|
|
||||||
|
|
||||||
if (*cbuf)
|
|
||||||
pipe_resource_reference(cbuf, NULL);
|
|
||||||
|
|
||||||
if (ctx->mask.union_fs)
|
|
||||||
vg_shader_destroy(ctx, ctx->mask.union_fs);
|
|
||||||
if (ctx->mask.intersect_fs)
|
|
||||||
vg_shader_destroy(ctx, ctx->mask.intersect_fs);
|
|
||||||
if (ctx->mask.subtract_fs)
|
|
||||||
vg_shader_destroy(ctx, ctx->mask.subtract_fs);
|
|
||||||
if (ctx->mask.set_fs)
|
|
||||||
vg_shader_destroy(ctx, ctx->mask.set_fs);
|
|
||||||
|
|
||||||
cso_destroy_context(ctx->cso_context);
|
|
||||||
|
|
||||||
cso_hash_delete(ctx->owned_objects[VG_OBJECT_PAINT]);
|
|
||||||
cso_hash_delete(ctx->owned_objects[VG_OBJECT_IMAGE]);
|
|
||||||
cso_hash_delete(ctx->owned_objects[VG_OBJECT_MASK]);
|
|
||||||
cso_hash_delete(ctx->owned_objects[VG_OBJECT_FONT]);
|
|
||||||
cso_hash_delete(ctx->owned_objects[VG_OBJECT_PATH]);
|
|
||||||
|
|
||||||
api_destroy_dispatch(ctx->dispatch);
|
|
||||||
|
|
||||||
FREE(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vg_init_object(struct vg_object *obj, struct vg_context *ctx, enum vg_object_type type)
|
|
||||||
{
|
|
||||||
obj->type = type;
|
|
||||||
obj->ctx = ctx;
|
|
||||||
obj->handle = create_handle(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** free object resources, but not the object itself */
|
|
||||||
void vg_free_object(struct vg_object *obj)
|
|
||||||
{
|
|
||||||
obj->type = 0;
|
|
||||||
obj->ctx = NULL;
|
|
||||||
destroy_handle(obj->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
VGboolean vg_context_is_object_valid(struct vg_context *ctx,
|
|
||||||
enum vg_object_type type,
|
|
||||||
VGHandle handle)
|
|
||||||
{
|
|
||||||
if (ctx) {
|
|
||||||
struct cso_hash *hash = ctx->owned_objects[type];
|
|
||||||
if (!hash)
|
|
||||||
return VG_FALSE;
|
|
||||||
return cso_hash_contains(hash, (unsigned) handle);
|
|
||||||
}
|
|
||||||
return VG_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vg_context_add_object(struct vg_context *ctx,
|
|
||||||
struct vg_object *obj)
|
|
||||||
{
|
|
||||||
if (ctx) {
|
|
||||||
struct cso_hash *hash = ctx->owned_objects[obj->type];
|
|
||||||
if (!hash)
|
|
||||||
return;
|
|
||||||
cso_hash_insert(hash, (unsigned) obj->handle, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vg_context_remove_object(struct vg_context *ctx,
|
|
||||||
struct vg_object *obj)
|
|
||||||
{
|
|
||||||
if (ctx) {
|
|
||||||
struct cso_hash *hash = ctx->owned_objects[obj->type];
|
|
||||||
if (!hash)
|
|
||||||
return;
|
|
||||||
cso_hash_take(hash, (unsigned) obj->handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_resource *
|
|
||||||
create_texture(struct pipe_context *pipe, enum pipe_format format,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct pipe_resource templ;
|
|
||||||
|
|
||||||
memset(&templ, 0, sizeof(templ));
|
|
||||||
|
|
||||||
if (format != PIPE_FORMAT_NONE) {
|
|
||||||
templ.format = format;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
}
|
|
||||||
|
|
||||||
templ.target = PIPE_TEXTURE_2D;
|
|
||||||
templ.width0 = width;
|
|
||||||
templ.height0 = height;
|
|
||||||
templ.depth0 = 1;
|
|
||||||
templ.array_size = 1;
|
|
||||||
templ.last_level = 0;
|
|
||||||
|
|
||||||
if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
|
|
||||||
templ.bind = PIPE_BIND_DEPTH_STENCIL;
|
|
||||||
} else {
|
|
||||||
templ.bind = (PIPE_BIND_DISPLAY_TARGET |
|
|
||||||
PIPE_BIND_RENDER_TARGET |
|
|
||||||
PIPE_BIND_SAMPLER_VIEW);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pipe->screen->resource_create(pipe->screen, &templ);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_sampler_view *
|
|
||||||
create_tex_and_view(struct pipe_context *pipe, enum pipe_format format,
|
|
||||||
VGint width, VGint height)
|
|
||||||
{
|
|
||||||
struct pipe_resource *texture;
|
|
||||||
struct pipe_sampler_view view_templ;
|
|
||||||
struct pipe_sampler_view *view;
|
|
||||||
|
|
||||||
texture = create_texture(pipe, format, width, height);
|
|
||||||
|
|
||||||
if (!texture)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
u_sampler_view_default_template(&view_templ, texture, texture->format);
|
|
||||||
view = pipe->create_sampler_view(pipe, texture, &view_templ);
|
|
||||||
/* want the texture to go away if the view is freed */
|
|
||||||
pipe_resource_reference(&texture, NULL);
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vg_context_update_surface_mask_view(struct vg_context *ctx,
|
|
||||||
uint width, uint height)
|
|
||||||
{
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
struct pipe_sampler_view *old_sampler_view = stfb->surface_mask_view;
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
|
|
||||||
if (old_sampler_view &&
|
|
||||||
old_sampler_view->texture->width0 == width &&
|
|
||||||
old_sampler_view->texture->height0 == height)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to
|
|
||||||
this texture and use it as a sampler, so while this wastes some
|
|
||||||
space it makes both of those a lot simpler
|
|
||||||
*/
|
|
||||||
stfb->surface_mask_view = create_tex_and_view(pipe,
|
|
||||||
PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
|
|
||||||
|
|
||||||
if (!stfb->surface_mask_view) {
|
|
||||||
if (old_sampler_view)
|
|
||||||
pipe_sampler_view_reference(&old_sampler_view, NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX could this call be avoided? */
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
|
|
||||||
/* alpha mask starts with 1.f alpha */
|
|
||||||
mask_fill(0, 0, width, height, 1.f);
|
|
||||||
|
|
||||||
/* if we had an old surface copy it over */
|
|
||||||
if (old_sampler_view) {
|
|
||||||
struct pipe_box src_box;
|
|
||||||
u_box_origin_2d(MIN2(old_sampler_view->texture->width0,
|
|
||||||
stfb->surface_mask_view->texture->width0),
|
|
||||||
MIN2(old_sampler_view->texture->height0,
|
|
||||||
stfb->surface_mask_view->texture->height0),
|
|
||||||
&src_box);
|
|
||||||
|
|
||||||
pipe->resource_copy_region(pipe,
|
|
||||||
stfb->surface_mask_view->texture,
|
|
||||||
0, 0, 0, 0,
|
|
||||||
old_sampler_view->texture,
|
|
||||||
0, &src_box);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free the old texture
|
|
||||||
*/
|
|
||||||
if (old_sampler_view)
|
|
||||||
pipe_sampler_view_reference(&old_sampler_view, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vg_context_update_blend_texture_view(struct vg_context *ctx,
|
|
||||||
uint width, uint height)
|
|
||||||
{
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
struct pipe_sampler_view *old = stfb->blend_texture_view;
|
|
||||||
|
|
||||||
if (old &&
|
|
||||||
old->texture->width0 == width &&
|
|
||||||
old->texture->height0 == height)
|
|
||||||
return;
|
|
||||||
|
|
||||||
stfb->blend_texture_view = create_tex_and_view(pipe,
|
|
||||||
PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
|
|
||||||
|
|
||||||
pipe_sampler_view_reference(&old, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
vg_context_update_depth_stencil_rb(struct vg_context * ctx,
|
|
||||||
uint width, uint height)
|
|
||||||
{
|
|
||||||
struct st_renderbuffer *dsrb = ctx->draw_buffer->dsrb;
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct pipe_surface surf_tmpl;
|
|
||||||
|
|
||||||
if ((dsrb->width == width && dsrb->height == height) && dsrb->texture)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* unreference existing ones */
|
|
||||||
pipe_surface_reference(&dsrb->surface, NULL);
|
|
||||||
pipe_resource_reference(&dsrb->texture, NULL);
|
|
||||||
dsrb->width = dsrb->height = 0;
|
|
||||||
|
|
||||||
dsrb->texture = create_texture(pipe, dsrb->format, width, height);
|
|
||||||
if (!dsrb->texture)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
u_surface_default_template(&surf_tmpl, dsrb->texture);
|
|
||||||
dsrb->surface = pipe->create_surface(pipe,
|
|
||||||
dsrb->texture,
|
|
||||||
&surf_tmpl);
|
|
||||||
if (!dsrb->surface) {
|
|
||||||
pipe_resource_reference(&dsrb->texture, NULL);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
dsrb->width = width;
|
|
||||||
dsrb->height = height;
|
|
||||||
|
|
||||||
assert(dsrb->surface->width == width);
|
|
||||||
assert(dsrb->surface->height == height);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vg_validate_state(struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
|
|
||||||
vg_manager_validate_framebuffer(ctx);
|
|
||||||
|
|
||||||
if (vg_context_update_depth_stencil_rb(ctx, stfb->width, stfb->height))
|
|
||||||
ctx->state.dirty |= DEPTH_STENCIL_DIRTY;
|
|
||||||
|
|
||||||
/* blend state depends on fb format and paint color */
|
|
||||||
if ((ctx->state.dirty & FRAMEBUFFER_DIRTY) ||
|
|
||||||
(ctx->state.dirty & PAINT_DIRTY))
|
|
||||||
ctx->state.dirty |= BLEND_DIRTY;
|
|
||||||
|
|
||||||
renderer_validate(ctx->renderer, ctx->state.dirty,
|
|
||||||
ctx->draw_buffer, &ctx->state.vg);
|
|
||||||
|
|
||||||
ctx->state.dirty = 0;
|
|
||||||
|
|
||||||
shader_set_masking(ctx->shader, ctx->state.vg.masking);
|
|
||||||
shader_set_image_mode(ctx->shader, ctx->state.vg.image_mode);
|
|
||||||
shader_set_color_transform(ctx->shader, ctx->state.vg.color_transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
VGboolean vg_object_is_valid(VGHandle object, enum vg_object_type type)
|
|
||||||
{
|
|
||||||
struct vg_object *obj = handle_to_object(object);
|
|
||||||
if (obj && is_aligned(obj) && obj->type == type)
|
|
||||||
return VG_TRUE;
|
|
||||||
else
|
|
||||||
return VG_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vg_set_error(struct vg_context *ctx,
|
|
||||||
VGErrorCode code)
|
|
||||||
{
|
|
||||||
/*vgGetError returns the oldest error code provided by
|
|
||||||
* an API call on the current context since the previous
|
|
||||||
* call to vgGetError on that context (or since the creation
|
|
||||||
of the context).*/
|
|
||||||
if (ctx->_error == VG_NO_ERROR)
|
|
||||||
ctx->_error = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vg_prepare_blend_texture(struct vg_context *ctx,
|
|
||||||
struct pipe_sampler_view *src)
|
|
||||||
{
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct pipe_blit_info info;
|
|
||||||
|
|
||||||
vg_context_update_blend_texture_view(ctx, stfb->width, stfb->height);
|
|
||||||
|
|
||||||
memset(&info, 0, sizeof info);
|
|
||||||
info.dst.resource = stfb->blend_texture_view->texture;
|
|
||||||
info.dst.level = 0;
|
|
||||||
info.dst.box.x = 0;
|
|
||||||
info.dst.box.y = 0;
|
|
||||||
info.dst.box.z = 0;
|
|
||||||
info.dst.box.width = stfb->width;
|
|
||||||
info.dst.box.height = stfb->height;
|
|
||||||
info.dst.box.depth = 1;
|
|
||||||
info.dst.format = stfb->blend_texture_view->format;
|
|
||||||
info.src.resource = src->texture;
|
|
||||||
info.src.level = src->u.tex.first_level;
|
|
||||||
info.src.box.x = 0;
|
|
||||||
info.src.box.y = 0;
|
|
||||||
info.src.box.z = src->u.tex.first_layer;
|
|
||||||
info.src.box.width = stfb->width;
|
|
||||||
info.src.box.height = stfb->height;
|
|
||||||
info.src.box.depth = 1;
|
|
||||||
info.src.format = src->format;
|
|
||||||
info.mask = PIPE_MASK_RGBA;
|
|
||||||
info.filter = PIPE_TEX_MIPFILTER_NEAREST;
|
|
||||||
info.scissor_enable = 0;
|
|
||||||
|
|
||||||
pipe->blit(pipe, &info);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pipe_sampler_view *vg_prepare_blend_surface(struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct pipe_sampler_view *view;
|
|
||||||
struct pipe_sampler_view view_templ;
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
struct st_renderbuffer *strb = stfb->strb;
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
|
|
||||||
u_sampler_view_default_template(&view_templ, strb->texture, strb->texture->format);
|
|
||||||
view = pipe->create_sampler_view(pipe, strb->texture, &view_templ);
|
|
||||||
|
|
||||||
vg_prepare_blend_texture(ctx, view);
|
|
||||||
|
|
||||||
pipe_sampler_view_reference(&view, NULL);
|
|
||||||
|
|
||||||
return stfb->blend_texture_view;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct pipe_sampler_view *vg_prepare_blend_surface_from_mask(struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
|
|
||||||
vg_validate_state(ctx);
|
|
||||||
|
|
||||||
vg_context_update_surface_mask_view(ctx, stfb->width, stfb->height);
|
|
||||||
vg_prepare_blend_texture(ctx, stfb->surface_mask_view);
|
|
||||||
|
|
||||||
return stfb->blend_texture_view;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pipe_sampler_view *vg_get_surface_mask(struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
|
|
||||||
vg_context_update_surface_mask_view(ctx, stfb->width, stfb->height);
|
|
||||||
|
|
||||||
return stfb->surface_mask_view;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A transformation from window coordinates to paint coordinates.
|
|
||||||
*/
|
|
||||||
VGboolean vg_get_paint_matrix(struct vg_context *ctx,
|
|
||||||
const struct matrix *paint_to_user,
|
|
||||||
const struct matrix *user_to_surface,
|
|
||||||
struct matrix *mat)
|
|
||||||
{
|
|
||||||
struct matrix tmp;
|
|
||||||
|
|
||||||
/* get user-to-paint matrix */
|
|
||||||
memcpy(mat, paint_to_user, sizeof(*paint_to_user));
|
|
||||||
if (!matrix_invert(mat))
|
|
||||||
return VG_FALSE;
|
|
||||||
|
|
||||||
/* get surface-to-user matrix */
|
|
||||||
memcpy(&tmp, user_to_surface, sizeof(*user_to_surface));
|
|
||||||
if (!matrix_invert(&tmp))
|
|
||||||
return VG_FALSE;
|
|
||||||
|
|
||||||
matrix_mult(mat, &tmp);
|
|
||||||
|
|
||||||
return VG_TRUE;
|
|
||||||
}
|
|
||||||
|
|
@ -1,280 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef VG_CONTEXT_H
|
|
||||||
#define VG_CONTEXT_H
|
|
||||||
|
|
||||||
#include "vg_state.h"
|
|
||||||
|
|
||||||
#include "pipe/p_format.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "util/u_pointer.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
#include "state_tracker/st_api.h"
|
|
||||||
|
|
||||||
#include "cso_cache/cso_hash.h"
|
|
||||||
#include "cso_cache/cso_context.h"
|
|
||||||
|
|
||||||
struct renderer;
|
|
||||||
struct shaders_cache;
|
|
||||||
struct shader;
|
|
||||||
struct vg_shader;
|
|
||||||
struct mapi_table;
|
|
||||||
|
|
||||||
struct st_renderbuffer {
|
|
||||||
enum pipe_format format;
|
|
||||||
struct pipe_surface *surface;
|
|
||||||
struct pipe_resource *texture;
|
|
||||||
VGint width, height;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct st_framebuffer {
|
|
||||||
VGint width, height;
|
|
||||||
struct st_renderbuffer *strb;
|
|
||||||
struct st_renderbuffer *dsrb;
|
|
||||||
|
|
||||||
struct pipe_sampler_view *surface_mask_view;
|
|
||||||
|
|
||||||
struct pipe_sampler_view *blend_texture_view;
|
|
||||||
|
|
||||||
|
|
||||||
struct st_framebuffer_iface *iface;
|
|
||||||
enum st_attachment_type strb_att;
|
|
||||||
|
|
||||||
void *privateData;
|
|
||||||
int32_t stamp;
|
|
||||||
int32_t iface_stamp;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum vg_object_type {
|
|
||||||
VG_OBJECT_UNKNOWN = 0,
|
|
||||||
VG_OBJECT_PAINT,
|
|
||||||
VG_OBJECT_IMAGE,
|
|
||||||
VG_OBJECT_MASK,
|
|
||||||
VG_OBJECT_FONT,
|
|
||||||
VG_OBJECT_PATH,
|
|
||||||
|
|
||||||
VG_OBJECT_LAST
|
|
||||||
};
|
|
||||||
enum dirty_state {
|
|
||||||
BLEND_DIRTY = 1 << 0,
|
|
||||||
FRAMEBUFFER_DIRTY = 1 << 1,
|
|
||||||
DEPTH_STENCIL_DIRTY = 1 << 2,
|
|
||||||
PAINT_DIRTY = 1 << 3,
|
|
||||||
|
|
||||||
ALL_DIRTY = BLEND_DIRTY |
|
|
||||||
FRAMEBUFFER_DIRTY |
|
|
||||||
DEPTH_STENCIL_DIRTY |
|
|
||||||
PAINT_DIRTY
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vg_context
|
|
||||||
{
|
|
||||||
struct st_context_iface iface;
|
|
||||||
struct mapi_table *dispatch;
|
|
||||||
|
|
||||||
struct pipe_context *pipe;
|
|
||||||
enum pipe_format ds_format;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct vg_state vg;
|
|
||||||
VGbitfield dirty;
|
|
||||||
} state;
|
|
||||||
|
|
||||||
VGErrorCode _error;
|
|
||||||
|
|
||||||
struct st_framebuffer *draw_buffer;
|
|
||||||
|
|
||||||
struct cso_hash *owned_objects[VG_OBJECT_LAST];
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct pipe_resource *cbuf;
|
|
||||||
struct pipe_sampler_state sampler;
|
|
||||||
|
|
||||||
struct vg_shader *union_fs;
|
|
||||||
struct vg_shader *intersect_fs;
|
|
||||||
struct vg_shader *subtract_fs;
|
|
||||||
struct vg_shader *set_fs;
|
|
||||||
} mask;
|
|
||||||
|
|
||||||
struct cso_context *cso_context;
|
|
||||||
|
|
||||||
struct renderer *renderer;
|
|
||||||
struct shaders_cache *sc;
|
|
||||||
struct shader *shader;
|
|
||||||
|
|
||||||
struct pipe_sampler_state blend_sampler;
|
|
||||||
struct vg_paint *default_paint;
|
|
||||||
|
|
||||||
int32_t draw_stamp;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for VG objects like paths, images, fonts.
|
|
||||||
*/
|
|
||||||
struct vg_object {
|
|
||||||
enum vg_object_type type;
|
|
||||||
VGHandle handle;
|
|
||||||
struct vg_context *ctx;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void vg_init_object(struct vg_object *obj, struct vg_context *ctx, enum vg_object_type type);
|
|
||||||
void vg_free_object(struct vg_object *obj);
|
|
||||||
|
|
||||||
VGboolean vg_object_is_valid(VGHandle object, enum vg_object_type type);
|
|
||||||
|
|
||||||
struct vg_context *vg_create_context(struct pipe_context *pipe,
|
|
||||||
const void *visual,
|
|
||||||
struct vg_context *share);
|
|
||||||
void vg_destroy_context(struct vg_context *ctx);
|
|
||||||
struct vg_context *vg_current_context(void);
|
|
||||||
void vg_set_current_context(struct vg_context *ctx);
|
|
||||||
|
|
||||||
VGboolean vg_context_is_object_valid(struct vg_context *ctx,
|
|
||||||
enum vg_object_type type,
|
|
||||||
VGHandle object);
|
|
||||||
void vg_context_add_object(struct vg_context *ctx,
|
|
||||||
struct vg_object *obj);
|
|
||||||
void vg_context_remove_object(struct vg_context *ctx,
|
|
||||||
struct vg_object *obj);
|
|
||||||
|
|
||||||
void vg_validate_state(struct vg_context *ctx);
|
|
||||||
|
|
||||||
void vg_set_error(struct vg_context *ctx,
|
|
||||||
VGErrorCode code);
|
|
||||||
|
|
||||||
struct pipe_sampler_view *vg_prepare_blend_surface(struct vg_context *ctx);
|
|
||||||
struct pipe_sampler_view *vg_prepare_blend_surface_from_mask(struct vg_context *ctx);
|
|
||||||
|
|
||||||
struct pipe_sampler_view *vg_get_surface_mask(struct vg_context *ctx);
|
|
||||||
|
|
||||||
VGboolean vg_get_paint_matrix(struct vg_context *ctx,
|
|
||||||
const struct matrix *paint_to_user,
|
|
||||||
const struct matrix *user_to_surface,
|
|
||||||
struct matrix *mat);
|
|
||||||
|
|
||||||
static INLINE VGboolean is_aligned_to(const void *ptr, VGbyte alignment)
|
|
||||||
{
|
|
||||||
void *aligned = align_pointer(ptr, alignment);
|
|
||||||
return (ptr == aligned) ? VG_TRUE : VG_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE VGboolean is_aligned(const void *ptr)
|
|
||||||
{
|
|
||||||
return is_aligned_to(ptr, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void vg_shift_rectx(VGfloat coords[4],
|
|
||||||
const VGfloat *bounds,
|
|
||||||
const VGfloat shift)
|
|
||||||
{
|
|
||||||
coords[0] += shift;
|
|
||||||
coords[2] -= shift;
|
|
||||||
if (bounds) {
|
|
||||||
coords[2] = MIN2(coords[2], bounds[2]);
|
|
||||||
/* bound x/y + width/height */
|
|
||||||
if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) {
|
|
||||||
coords[2] = (bounds[0] + bounds[2]) - coords[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void vg_shift_recty(VGfloat coords[4],
|
|
||||||
const VGfloat *bounds,
|
|
||||||
const VGfloat shift)
|
|
||||||
{
|
|
||||||
coords[1] += shift;
|
|
||||||
coords[3] -= shift;
|
|
||||||
if (bounds) {
|
|
||||||
coords[3] = MIN2(coords[3], bounds[3]);
|
|
||||||
if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) {
|
|
||||||
coords[3] = (bounds[1] + bounds[3]) - coords[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void vg_bound_rect(VGfloat coords[4],
|
|
||||||
const VGfloat bounds[4],
|
|
||||||
VGfloat shift[4])
|
|
||||||
{
|
|
||||||
/* if outside the bounds */
|
|
||||||
if (coords[0] > (bounds[0] + bounds[2]) ||
|
|
||||||
coords[1] > (bounds[1] + bounds[3]) ||
|
|
||||||
(coords[0] + coords[2]) < bounds[0] ||
|
|
||||||
(coords[1] + coords[3]) < bounds[1]) {
|
|
||||||
coords[0] = 0.f;
|
|
||||||
coords[1] = 0.f;
|
|
||||||
coords[2] = 0.f;
|
|
||||||
coords[3] = 0.f;
|
|
||||||
shift[0] = 0.f;
|
|
||||||
shift[1] = 0.f;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bound x */
|
|
||||||
if (coords[0] < bounds[0]) {
|
|
||||||
shift[0] = bounds[0] - coords[0];
|
|
||||||
coords[2] -= shift[0];
|
|
||||||
coords[0] = bounds[0];
|
|
||||||
} else
|
|
||||||
shift[0] = 0.f;
|
|
||||||
|
|
||||||
/* bound y */
|
|
||||||
if (coords[1] < bounds[1]) {
|
|
||||||
shift[1] = bounds[1] - coords[1];
|
|
||||||
coords[3] -= shift[1];
|
|
||||||
coords[1] = bounds[1];
|
|
||||||
} else
|
|
||||||
shift[1] = 0.f;
|
|
||||||
|
|
||||||
shift[2] = bounds[2] - coords[2];
|
|
||||||
shift[3] = bounds[3] - coords[3];
|
|
||||||
/* bound width/height */
|
|
||||||
coords[2] = MIN2(coords[2], bounds[2]);
|
|
||||||
coords[3] = MIN2(coords[3], bounds[3]);
|
|
||||||
|
|
||||||
/* bound x/y + width/height */
|
|
||||||
if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) {
|
|
||||||
coords[2] = (bounds[0] + bounds[2]) - coords[0];
|
|
||||||
}
|
|
||||||
if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) {
|
|
||||||
coords[3] = (bounds[1] + bounds[3]) - coords[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if outside the bounds */
|
|
||||||
if ((coords[0] + coords[2]) < bounds[0] ||
|
|
||||||
(coords[1] + coords[3]) < bounds[1]) {
|
|
||||||
coords[0] = 0.f;
|
|
||||||
coords[1] = 0.f;
|
|
||||||
coords[2] = 0.f;
|
|
||||||
coords[3] = 0.f;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,399 +0,0 @@
|
||||||
/*
|
|
||||||
* Mesa 3-D graphics library
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
* Copyright (C) 2010 LunarG Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Chia-I Wu <olv@lunarg.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "state_tracker/st_api.h"
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_screen.h"
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "util/u_box.h"
|
|
||||||
#include "util/u_surface.h"
|
|
||||||
|
|
||||||
#include "vg_api.h"
|
|
||||||
#include "vg_manager.h"
|
|
||||||
#include "vg_context.h"
|
|
||||||
#include "api.h"
|
|
||||||
#include "handle.h"
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt)
|
|
||||||
{
|
|
||||||
struct st_renderbuffer *strb = ctx->draw_buffer->strb;
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
struct pipe_surface surf_tmpl;
|
|
||||||
|
|
||||||
if (strb->texture == pt) {
|
|
||||||
pipe_resource_reference(&pt, NULL);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unreference existing ones */
|
|
||||||
pipe_surface_reference(&strb->surface, NULL);
|
|
||||||
pipe_resource_reference(&strb->texture, NULL);
|
|
||||||
strb->width = strb->height = 0;
|
|
||||||
|
|
||||||
strb->texture = pt;
|
|
||||||
|
|
||||||
u_surface_default_template(&surf_tmpl, strb->texture);
|
|
||||||
strb->surface = pipe->create_surface(pipe, strb->texture, &surf_tmpl);
|
|
||||||
|
|
||||||
if (!strb->surface) {
|
|
||||||
pipe_resource_reference(&strb->texture, NULL);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
strb->width = pt->width0;
|
|
||||||
strb->height = pt->height0;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush the front buffer if the current context renders to the front buffer.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
vg_manager_flush_frontbuffer(struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
|
|
||||||
if (!stfb)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (stfb->strb_att) {
|
|
||||||
case ST_ATTACHMENT_FRONT_LEFT:
|
|
||||||
case ST_ATTACHMENT_FRONT_RIGHT:
|
|
||||||
stfb->iface->flush_front(&ctx->iface, stfb->iface, stfb->strb_att);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Re-validate the framebuffer.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
vg_manager_validate_framebuffer(struct vg_context *ctx)
|
|
||||||
{
|
|
||||||
struct st_framebuffer *stfb = ctx->draw_buffer;
|
|
||||||
struct pipe_resource *pt;
|
|
||||||
int32_t new_stamp;
|
|
||||||
|
|
||||||
/* no binding surface */
|
|
||||||
if (!stfb)
|
|
||||||
return;
|
|
||||||
|
|
||||||
new_stamp = p_atomic_read(&stfb->iface->stamp);
|
|
||||||
if (stfb->iface_stamp != new_stamp) {
|
|
||||||
do {
|
|
||||||
/* validate the fb */
|
|
||||||
if (!stfb->iface->validate((struct st_context_iface *)ctx,
|
|
||||||
stfb->iface, &stfb->strb_att,
|
|
||||||
1, &pt) || !pt)
|
|
||||||
return;
|
|
||||||
|
|
||||||
stfb->iface_stamp = new_stamp;
|
|
||||||
new_stamp = p_atomic_read(&stfb->iface->stamp);
|
|
||||||
|
|
||||||
} while (stfb->iface_stamp != new_stamp);
|
|
||||||
|
|
||||||
if (vg_context_update_color_rb(ctx, pt) ||
|
|
||||||
stfb->width != pt->width0 ||
|
|
||||||
stfb->height != pt->height0)
|
|
||||||
++stfb->stamp;
|
|
||||||
|
|
||||||
stfb->width = pt->width0;
|
|
||||||
stfb->height = pt->height0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->draw_stamp != stfb->stamp) {
|
|
||||||
ctx->state.dirty |= FRAMEBUFFER_DIRTY;
|
|
||||||
ctx->draw_stamp = stfb->stamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vg_context_flush(struct st_context_iface *stctxi, unsigned flags,
|
|
||||||
struct pipe_fence_handle **fence)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = (struct vg_context *) stctxi;
|
|
||||||
unsigned pipe_flags = 0;
|
|
||||||
|
|
||||||
if (flags & ST_FLUSH_END_OF_FRAME) {
|
|
||||||
pipe_flags |= PIPE_FLUSH_END_OF_FRAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->pipe->flush(ctx->pipe, fence, pipe_flags);
|
|
||||||
if (flags & ST_FLUSH_FRONT)
|
|
||||||
vg_manager_flush_frontbuffer(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vg_context_destroy(struct st_context_iface *stctxi)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = (struct vg_context *) stctxi;
|
|
||||||
struct pipe_context *pipe = ctx->pipe;
|
|
||||||
|
|
||||||
vg_destroy_context(ctx);
|
|
||||||
pipe->destroy(pipe);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct st_context_iface *
|
|
||||||
vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
|
|
||||||
const struct st_context_attribs *attribs,
|
|
||||||
enum st_context_error *error,
|
|
||||||
struct st_context_iface *shared_stctxi)
|
|
||||||
{
|
|
||||||
struct vg_context *shared_ctx = (struct vg_context *) shared_stctxi;
|
|
||||||
struct vg_context *ctx;
|
|
||||||
struct pipe_context *pipe;
|
|
||||||
|
|
||||||
if (!(stapi->profile_mask & (1 << attribs->profile))) {
|
|
||||||
*error = ST_CONTEXT_ERROR_BAD_API;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* only 1.0 is supported */
|
|
||||||
if (attribs->major > 1 || (attribs->major == 1 && attribs->minor > 0)) {
|
|
||||||
*error = ST_CONTEXT_ERROR_BAD_VERSION;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for VGHandle / pointer lookups */
|
|
||||||
init_handles();
|
|
||||||
|
|
||||||
pipe = smapi->screen->context_create(smapi->screen, NULL);
|
|
||||||
if (!pipe) {
|
|
||||||
*error = ST_CONTEXT_ERROR_NO_MEMORY;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ctx = vg_create_context(pipe, NULL, shared_ctx);
|
|
||||||
if (!ctx) {
|
|
||||||
pipe->destroy(pipe);
|
|
||||||
*error = ST_CONTEXT_ERROR_NO_MEMORY;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->iface.destroy = vg_context_destroy;
|
|
||||||
|
|
||||||
ctx->iface.flush = vg_context_flush;
|
|
||||||
|
|
||||||
ctx->iface.teximage = NULL;
|
|
||||||
ctx->iface.copy = NULL;
|
|
||||||
|
|
||||||
ctx->iface.st_context_private = (void *) smapi;
|
|
||||||
|
|
||||||
return &ctx->iface;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct st_renderbuffer *
|
|
||||||
create_renderbuffer(enum pipe_format format)
|
|
||||||
{
|
|
||||||
struct st_renderbuffer *strb;
|
|
||||||
|
|
||||||
strb = CALLOC_STRUCT(st_renderbuffer);
|
|
||||||
if (strb)
|
|
||||||
strb->format = format;
|
|
||||||
|
|
||||||
return strb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
destroy_renderbuffer(struct st_renderbuffer *strb)
|
|
||||||
{
|
|
||||||
pipe_surface_reference(&strb->surface, NULL);
|
|
||||||
pipe_resource_reference(&strb->texture, NULL);
|
|
||||||
FREE(strb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decide the buffer to render to.
|
|
||||||
*/
|
|
||||||
static enum st_attachment_type
|
|
||||||
choose_attachment(struct st_framebuffer_iface *stfbi)
|
|
||||||
{
|
|
||||||
enum st_attachment_type statt;
|
|
||||||
|
|
||||||
statt = stfbi->visual->render_buffer;
|
|
||||||
if (statt != ST_ATTACHMENT_INVALID) {
|
|
||||||
/* use the buffer given by the visual, unless it is unavailable */
|
|
||||||
if (!st_visual_have_buffers(stfbi->visual, 1 << statt)) {
|
|
||||||
switch (statt) {
|
|
||||||
case ST_ATTACHMENT_BACK_LEFT:
|
|
||||||
statt = ST_ATTACHMENT_FRONT_LEFT;
|
|
||||||
break;
|
|
||||||
case ST_ATTACHMENT_BACK_RIGHT:
|
|
||||||
statt = ST_ATTACHMENT_FRONT_RIGHT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!st_visual_have_buffers(stfbi->visual, 1 << statt))
|
|
||||||
statt = ST_ATTACHMENT_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return statt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bind the context to the given framebuffers.
|
|
||||||
*/
|
|
||||||
static boolean
|
|
||||||
vg_context_bind_framebuffers(struct st_context_iface *stctxi,
|
|
||||||
struct st_framebuffer_iface *stdrawi,
|
|
||||||
struct st_framebuffer_iface *streadi)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = (struct vg_context *) stctxi;
|
|
||||||
struct st_framebuffer *stfb;
|
|
||||||
enum st_attachment_type strb_att;
|
|
||||||
|
|
||||||
/* the draw and read framebuffers must be the same */
|
|
||||||
if (stdrawi != streadi)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
strb_att = (stdrawi) ? choose_attachment(stdrawi) : ST_ATTACHMENT_INVALID;
|
|
||||||
|
|
||||||
if (ctx->draw_buffer) {
|
|
||||||
stfb = ctx->draw_buffer;
|
|
||||||
|
|
||||||
/* free the existing fb */
|
|
||||||
if (!stdrawi ||
|
|
||||||
stfb->strb_att != strb_att ||
|
|
||||||
stfb->strb->format != stdrawi->visual->color_format) {
|
|
||||||
destroy_renderbuffer(stfb->strb);
|
|
||||||
destroy_renderbuffer(stfb->dsrb);
|
|
||||||
FREE(stfb);
|
|
||||||
|
|
||||||
ctx->draw_buffer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stdrawi)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (strb_att == ST_ATTACHMENT_INVALID)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* create a new fb */
|
|
||||||
if (!ctx->draw_buffer) {
|
|
||||||
stfb = CALLOC_STRUCT(st_framebuffer);
|
|
||||||
if (!stfb)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
stfb->strb = create_renderbuffer(stdrawi->visual->color_format);
|
|
||||||
if (!stfb->strb) {
|
|
||||||
FREE(stfb);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
stfb->dsrb = create_renderbuffer(ctx->ds_format);
|
|
||||||
if (!stfb->dsrb) {
|
|
||||||
FREE(stfb->strb);
|
|
||||||
FREE(stfb);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
stfb->width = 0;
|
|
||||||
stfb->height = 0;
|
|
||||||
stfb->strb_att = strb_att;
|
|
||||||
stfb->stamp = 1;
|
|
||||||
stfb->iface_stamp = p_atomic_read(&stdrawi->stamp) - 1;
|
|
||||||
|
|
||||||
ctx->draw_buffer = stfb;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->draw_buffer->iface = stdrawi;
|
|
||||||
ctx->draw_stamp = ctx->draw_buffer->stamp - 1;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
vg_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
|
|
||||||
struct st_framebuffer_iface *stdrawi,
|
|
||||||
struct st_framebuffer_iface *streadi)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = (struct vg_context *) stctxi;
|
|
||||||
|
|
||||||
if (stctxi)
|
|
||||||
vg_context_bind_framebuffers(stctxi, stdrawi, streadi);
|
|
||||||
vg_set_current_context(ctx);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct st_context_iface *
|
|
||||||
vg_api_get_current(struct st_api *stapi)
|
|
||||||
{
|
|
||||||
struct vg_context *ctx = vg_current_context();
|
|
||||||
|
|
||||||
return (ctx) ? &ctx->iface : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static st_proc_t
|
|
||||||
vg_api_get_proc_address(struct st_api *stapi, const char *procname)
|
|
||||||
{
|
|
||||||
return api_get_proc_address(procname);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vg_api_destroy(struct st_api *stapi)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vg_api_query_versions(struct st_api *stapi, struct st_manager *sm,
|
|
||||||
struct st_config_options *options,
|
|
||||||
int *gl_core_version,
|
|
||||||
int *gl_compat_version,
|
|
||||||
int *gl_es1_version,
|
|
||||||
int *gl_es2_version)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct st_api vg_api = {
|
|
||||||
"Vega " PACKAGE_VERSION,
|
|
||||||
ST_API_OPENVG,
|
|
||||||
ST_PROFILE_DEFAULT_MASK,
|
|
||||||
0,
|
|
||||||
vg_api_destroy,
|
|
||||||
vg_api_query_versions,
|
|
||||||
vg_api_get_proc_address,
|
|
||||||
vg_api_create_context,
|
|
||||||
vg_api_make_current,
|
|
||||||
vg_api_get_current,
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct st_api *
|
|
||||||
vg_api_get(void)
|
|
||||||
{
|
|
||||||
return &vg_api;
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* Mesa 3-D graphics library
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 LunarG Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Chia-I Wu <olv@lunarg.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VG_MANAGER_H
|
|
||||||
#define VG_MANAGER_H
|
|
||||||
|
|
||||||
#include "state_tracker/st_api.h"
|
|
||||||
#include "vg_context.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
vg_manager_flush_frontbuffer(struct vg_context *ctx);
|
|
||||||
|
|
||||||
void
|
|
||||||
vg_manager_validate_framebuffer(struct vg_context *ctx);
|
|
||||||
|
|
||||||
#endif /* VG_MANAGER_H */
|
|
||||||
|
|
@ -1,124 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "vg_state.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
void vg_init_state(struct vg_state *state)
|
|
||||||
{
|
|
||||||
state->matrix_mode = VG_MATRIX_PATH_USER_TO_SURFACE;
|
|
||||||
state->fill_rule = VG_EVEN_ODD;
|
|
||||||
state->image_quality = VG_IMAGE_QUALITY_FASTER;
|
|
||||||
state->rendering_quality = VG_RENDERING_QUALITY_BETTER;
|
|
||||||
state->blend_mode = VG_BLEND_SRC_OVER;
|
|
||||||
state->image_mode = VG_DRAW_IMAGE_NORMAL;
|
|
||||||
|
|
||||||
memset(state->scissor_rects, 0, sizeof(state->scissor_rects));
|
|
||||||
state->scissor_rects_num = 0;
|
|
||||||
|
|
||||||
state->color_transform = VG_FALSE;
|
|
||||||
state->color_transform_values[0] = 1.0f;
|
|
||||||
state->color_transform_values[1] = 1.0f;
|
|
||||||
state->color_transform_values[2] = 1.0f;
|
|
||||||
state->color_transform_values[3] = 1.0f;
|
|
||||||
state->color_transform_values[4] = 0.0f;
|
|
||||||
state->color_transform_values[5] = 0.0f;
|
|
||||||
state->color_transform_values[6] = 0.0f;
|
|
||||||
state->color_transform_values[7] = 0.0f;
|
|
||||||
|
|
||||||
/* Stroke parameters */
|
|
||||||
state->stroke.line_width.f = 1.0f;
|
|
||||||
state->stroke.line_width.i = 1;
|
|
||||||
state->stroke.cap_style = VG_CAP_BUTT;
|
|
||||||
state->stroke.join_style = VG_JOIN_MITER;
|
|
||||||
state->stroke.miter_limit.f = 4.0f;
|
|
||||||
state->stroke.miter_limit.i = 4;
|
|
||||||
state->stroke.dash_pattern_num = 0;
|
|
||||||
state->stroke.dash_phase.f = 0.0f;
|
|
||||||
state->stroke.dash_phase.i = 0;
|
|
||||||
state->stroke.dash_phase_reset = VG_FALSE;
|
|
||||||
|
|
||||||
/* Edge fill color for VG_TILE_FILL tiling mode */
|
|
||||||
state->tile_fill_color[0] = 0.0f;
|
|
||||||
state->tile_fill_color[1] = 0.0f;
|
|
||||||
state->tile_fill_color[2] = 0.0f;
|
|
||||||
state->tile_fill_color[3] = 0.0f;
|
|
||||||
|
|
||||||
/* Color for vgClear */
|
|
||||||
state->clear_color[0] = 0.0f;
|
|
||||||
state->clear_color[1] = 0.0f;
|
|
||||||
state->clear_color[2] = 0.0f;
|
|
||||||
state->clear_color[3] = 0.0f;
|
|
||||||
|
|
||||||
/* Glyph origin */
|
|
||||||
state->glyph_origin[0].f = 0.0f;
|
|
||||||
state->glyph_origin[1].f = 0.0f;
|
|
||||||
state->glyph_origin[0].i = 0;
|
|
||||||
state->glyph_origin[1].i = 0;
|
|
||||||
|
|
||||||
/* Enable/disable alpha masking and scissoring */
|
|
||||||
state->masking = VG_FALSE;
|
|
||||||
state->scissoring = VG_FALSE;
|
|
||||||
|
|
||||||
/* Pixel layout information */
|
|
||||||
state->pixel_layout = VG_PIXEL_LAYOUT_UNKNOWN;
|
|
||||||
state->screen_layout = VG_PIXEL_LAYOUT_UNKNOWN;
|
|
||||||
|
|
||||||
/* Source format selection for image filters */
|
|
||||||
state->filter_format_linear = VG_FALSE;
|
|
||||||
state->filter_format_premultiplied = VG_FALSE;
|
|
||||||
|
|
||||||
/* Destination write enable mask for image filters */
|
|
||||||
state->filter_channel_mask = (VG_RED | VG_GREEN | VG_BLUE | VG_ALPHA);
|
|
||||||
|
|
||||||
matrix_load_identity(&state->path_user_to_surface_matrix);
|
|
||||||
matrix_load_identity(&state->image_user_to_surface_matrix);
|
|
||||||
matrix_load_identity(&state->fill_paint_to_user_matrix);
|
|
||||||
matrix_load_identity(&state->stroke_paint_to_user_matrix);
|
|
||||||
matrix_load_identity(&state->glyph_user_to_surface_matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct matrix *vg_state_matrix(struct vg_state *state)
|
|
||||||
{
|
|
||||||
switch(state->matrix_mode) {
|
|
||||||
case VG_MATRIX_PATH_USER_TO_SURFACE:
|
|
||||||
return &state->path_user_to_surface_matrix;
|
|
||||||
case VG_MATRIX_IMAGE_USER_TO_SURFACE:
|
|
||||||
return &state->image_user_to_surface_matrix;
|
|
||||||
case VG_MATRIX_FILL_PAINT_TO_USER:
|
|
||||||
return &state->fill_paint_to_user_matrix;
|
|
||||||
case VG_MATRIX_STROKE_PAINT_TO_USER:
|
|
||||||
return &state->stroke_paint_to_user_matrix;
|
|
||||||
#ifdef OPENVG_VERSION_1_1
|
|
||||||
case VG_MATRIX_GLYPH_USER_TO_SURFACE:
|
|
||||||
return &state->glyph_user_to_surface_matrix;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef VG_STATE_H
|
|
||||||
#define VG_STATE_H
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
|
|
||||||
#include "api_consts.h"
|
|
||||||
#include "matrix.h"
|
|
||||||
|
|
||||||
struct vg_value
|
|
||||||
{
|
|
||||||
VGfloat f;
|
|
||||||
VGint i;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vg_state {
|
|
||||||
/* Mode settings */
|
|
||||||
VGMatrixMode matrix_mode;
|
|
||||||
VGFillRule fill_rule;
|
|
||||||
VGImageQuality image_quality;
|
|
||||||
VGRenderingQuality rendering_quality;
|
|
||||||
VGBlendMode blend_mode;
|
|
||||||
VGImageMode image_mode;
|
|
||||||
|
|
||||||
/* Scissoring rectangles */
|
|
||||||
struct vg_value scissor_rects[32*4];
|
|
||||||
VGint scissor_rects_num;
|
|
||||||
|
|
||||||
/* Color Transformation */
|
|
||||||
VGboolean color_transform;
|
|
||||||
VGfloat color_transform_values[8];
|
|
||||||
|
|
||||||
/* Stroke parameters */
|
|
||||||
struct {
|
|
||||||
struct vg_value line_width;
|
|
||||||
VGCapStyle cap_style;
|
|
||||||
VGJoinStyle join_style;
|
|
||||||
struct vg_value miter_limit;
|
|
||||||
struct vg_value dash_pattern[VEGA_MAX_DASH_COUNT];
|
|
||||||
VGint dash_pattern_num;
|
|
||||||
struct vg_value dash_phase;
|
|
||||||
VGboolean dash_phase_reset;
|
|
||||||
} stroke;
|
|
||||||
|
|
||||||
/* Edge fill color for VG_TILE_FILL tiling mode */
|
|
||||||
VGfloat tile_fill_color[4];
|
|
||||||
VGint tile_fill_colori[4];
|
|
||||||
|
|
||||||
/* Color for vgClear */
|
|
||||||
VGfloat clear_color[4];
|
|
||||||
VGint clear_colori[4];
|
|
||||||
|
|
||||||
/* Glyph origin */
|
|
||||||
struct vg_value glyph_origin[2];
|
|
||||||
|
|
||||||
/* Enable/disable alpha masking and scissoring */
|
|
||||||
VGboolean masking;
|
|
||||||
VGboolean scissoring;
|
|
||||||
|
|
||||||
/* Pixel layout information */
|
|
||||||
VGPixelLayout pixel_layout;
|
|
||||||
VGPixelLayout screen_layout;
|
|
||||||
|
|
||||||
/* Source format selection for image filters */
|
|
||||||
VGboolean filter_format_linear;
|
|
||||||
VGboolean filter_format_premultiplied;
|
|
||||||
|
|
||||||
/* Destination write enable mask for image filters */
|
|
||||||
VGbitfield filter_channel_mask;
|
|
||||||
|
|
||||||
struct matrix path_user_to_surface_matrix;
|
|
||||||
struct matrix image_user_to_surface_matrix;
|
|
||||||
struct matrix fill_paint_to_user_matrix;
|
|
||||||
struct matrix stroke_paint_to_user_matrix;
|
|
||||||
struct matrix glyph_user_to_surface_matrix;
|
|
||||||
|
|
||||||
struct vg_paint *stroke_paint;
|
|
||||||
struct vg_paint *fill_paint;
|
|
||||||
};
|
|
||||||
|
|
||||||
void vg_init_state(struct vg_state *state);
|
|
||||||
struct matrix * vg_state_matrix(struct vg_state *state);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,49 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef VG_TRANSLATE_H
|
|
||||||
#define VG_TRANSLATE_H
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
#include "vg_context.h"
|
|
||||||
|
|
||||||
/*FIXME: we really should be using translate module
|
|
||||||
* but pipe_format can't express some of the VG formats
|
|
||||||
* (the premultiplied ones) so currently it won't work */
|
|
||||||
|
|
||||||
void _vega_pack_rgba_span_float(struct vg_context *ctx,
|
|
||||||
VGuint n, VGfloat rgba[][4],
|
|
||||||
VGImageFormat dstFormat,
|
|
||||||
void *dstAddr);
|
|
||||||
void _vega_unpack_float_span_rgba(struct vg_context *ctx,
|
|
||||||
VGuint n,
|
|
||||||
VGuint offset,
|
|
||||||
const void * data,
|
|
||||||
VGImageFormat dataFormat,
|
|
||||||
VGfloat rgba[][4]);
|
|
||||||
VGint _vega_size_for_format(VGImageFormat format);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,441 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "VG/openvg.h"
|
|
||||||
#include "VG/vgu.h"
|
|
||||||
|
|
||||||
#include "matrix.h"
|
|
||||||
#include "path.h"
|
|
||||||
#include "handle.h"
|
|
||||||
|
|
||||||
#include "util/u_debug.h"
|
|
||||||
#include "util/u_pointer.h"
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
|
|
||||||
static void vgu_append_float_coords(VGPath path,
|
|
||||||
const VGubyte *cmds,
|
|
||||||
VGint num_cmds,
|
|
||||||
const VGfloat *coords,
|
|
||||||
VGint num_coords)
|
|
||||||
{
|
|
||||||
VGubyte common_data[40 * sizeof(VGfloat)];
|
|
||||||
struct path *p = handle_to_path(path);
|
|
||||||
|
|
||||||
vg_float_to_datatype(path_datatype(p), common_data, coords, num_coords);
|
|
||||||
vgAppendPathData(path, num_cmds, cmds, common_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
VGUErrorCode vguLine(VGPath path,
|
|
||||||
VGfloat x0, VGfloat y0,
|
|
||||||
VGfloat x1, VGfloat y1)
|
|
||||||
{
|
|
||||||
static const VGubyte cmds[] = {VG_MOVE_TO_ABS, VG_LINE_TO_ABS};
|
|
||||||
VGfloat coords[4];
|
|
||||||
VGbitfield caps;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
return VGU_BAD_HANDLE_ERROR;
|
|
||||||
}
|
|
||||||
caps = vgGetPathCapabilities(path);
|
|
||||||
if (!(caps & VG_PATH_CAPABILITY_APPEND_TO)) {
|
|
||||||
return VGU_PATH_CAPABILITY_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
coords[0] = x0;
|
|
||||||
coords[1] = y0;
|
|
||||||
coords[2] = x1;
|
|
||||||
coords[3] = y1;
|
|
||||||
|
|
||||||
vgu_append_float_coords(path, cmds, 2, coords, 4);
|
|
||||||
|
|
||||||
return VGU_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGUErrorCode vguPolygon(VGPath path,
|
|
||||||
const VGfloat * points,
|
|
||||||
VGint count,
|
|
||||||
VGboolean closed)
|
|
||||||
{
|
|
||||||
VGubyte *cmds;
|
|
||||||
VGfloat *coords;
|
|
||||||
VGbitfield caps;
|
|
||||||
VGint i;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
return VGU_BAD_HANDLE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!points || count <= 0 || !is_aligned(points)) {
|
|
||||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
caps = vgGetPathCapabilities(path);
|
|
||||||
if (!(caps & VG_PATH_CAPABILITY_APPEND_TO)) {
|
|
||||||
return VGU_PATH_CAPABILITY_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmds = malloc(sizeof(VGubyte) * count + 1);
|
|
||||||
coords = malloc(sizeof(VGfloat) * count * 2);
|
|
||||||
|
|
||||||
cmds[0] = VG_MOVE_TO_ABS;
|
|
||||||
coords[0] = points[0];
|
|
||||||
coords[1] = points[1];
|
|
||||||
for (i = 1; i < count; ++i) {
|
|
||||||
cmds[i] = VG_LINE_TO_ABS;
|
|
||||||
coords[2*i + 0] = points[2*i + 0];
|
|
||||||
coords[2*i + 1] = points[2*i + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (closed) {
|
|
||||||
cmds[i] = VG_CLOSE_PATH;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
vgu_append_float_coords(path, cmds, i, coords, 2*i);
|
|
||||||
|
|
||||||
free(cmds);
|
|
||||||
free(coords);
|
|
||||||
|
|
||||||
return VGU_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGUErrorCode vguRect(VGPath path,
|
|
||||||
VGfloat x, VGfloat y,
|
|
||||||
VGfloat width, VGfloat height)
|
|
||||||
{
|
|
||||||
static const VGubyte cmds[] = {VG_MOVE_TO_ABS,
|
|
||||||
VG_HLINE_TO_REL,
|
|
||||||
VG_VLINE_TO_REL,
|
|
||||||
VG_HLINE_TO_REL,
|
|
||||||
VG_CLOSE_PATH
|
|
||||||
};
|
|
||||||
VGfloat coords[5];
|
|
||||||
VGbitfield caps;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
return VGU_BAD_HANDLE_ERROR;
|
|
||||||
}
|
|
||||||
caps = vgGetPathCapabilities(path);
|
|
||||||
if (!(caps & VG_PATH_CAPABILITY_APPEND_TO)) {
|
|
||||||
return VGU_PATH_CAPABILITY_ERROR;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
coords[0] = x;
|
|
||||||
coords[1] = y;
|
|
||||||
coords[2] = width;
|
|
||||||
coords[3] = height;
|
|
||||||
coords[4] = -width;
|
|
||||||
|
|
||||||
vgu_append_float_coords(path, cmds, 5, coords, 5);
|
|
||||||
|
|
||||||
return VGU_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGUErrorCode vguRoundRect(VGPath path,
|
|
||||||
VGfloat x, VGfloat y,
|
|
||||||
VGfloat width,
|
|
||||||
VGfloat height,
|
|
||||||
VGfloat arcWidth,
|
|
||||||
VGfloat arcHeight)
|
|
||||||
{
|
|
||||||
static const VGubyte cmds[] = {VG_MOVE_TO_ABS,
|
|
||||||
VG_HLINE_TO_REL,
|
|
||||||
VG_SCCWARC_TO_REL,
|
|
||||||
VG_VLINE_TO_REL,
|
|
||||||
VG_SCCWARC_TO_REL,
|
|
||||||
VG_HLINE_TO_REL,
|
|
||||||
VG_SCCWARC_TO_REL,
|
|
||||||
VG_VLINE_TO_REL,
|
|
||||||
VG_SCCWARC_TO_REL,
|
|
||||||
VG_CLOSE_PATH
|
|
||||||
};
|
|
||||||
VGfloat c[26];
|
|
||||||
VGbitfield caps;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
return VGU_BAD_HANDLE_ERROR;
|
|
||||||
}
|
|
||||||
caps = vgGetPathCapabilities(path);
|
|
||||||
if (!(caps & VG_PATH_CAPABILITY_APPEND_TO)) {
|
|
||||||
return VGU_PATH_CAPABILITY_ERROR;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
c[0] = x + arcWidth/2; c[1] = y;
|
|
||||||
|
|
||||||
c[2] = width - arcWidth;
|
|
||||||
|
|
||||||
c[3] = arcWidth/2; c[4] = arcHeight/2; c[5] = 0;
|
|
||||||
c[6] = arcWidth/2; c[7] = arcHeight/2;
|
|
||||||
|
|
||||||
c[8] = height - arcHeight;
|
|
||||||
|
|
||||||
c[9] = arcWidth/2; c[10] = arcHeight/2; c[11] = 0;
|
|
||||||
c[12] = -arcWidth/2; c[13] = arcHeight/2;
|
|
||||||
|
|
||||||
c[14] = -(width - arcWidth);
|
|
||||||
|
|
||||||
c[15] = arcWidth/2; c[16] = arcHeight/2; c[17] = 0;
|
|
||||||
c[18] = -arcWidth/2; c[19] = -arcHeight/2;
|
|
||||||
|
|
||||||
c[20] = -(height - arcHeight);
|
|
||||||
|
|
||||||
c[21] = arcWidth/2; c[22] = arcHeight/2; c[23] = 0;
|
|
||||||
c[24] = arcWidth/2; c[25] = -arcHeight/2;
|
|
||||||
|
|
||||||
vgu_append_float_coords(path, cmds, 10, c, 26);
|
|
||||||
|
|
||||||
return VGU_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGUErrorCode vguEllipse(VGPath path,
|
|
||||||
VGfloat cx, VGfloat cy,
|
|
||||||
VGfloat width,
|
|
||||||
VGfloat height)
|
|
||||||
{
|
|
||||||
static const VGubyte cmds[] = {VG_MOVE_TO_ABS,
|
|
||||||
VG_SCCWARC_TO_REL,
|
|
||||||
VG_SCCWARC_TO_REL,
|
|
||||||
VG_CLOSE_PATH
|
|
||||||
};
|
|
||||||
VGfloat coords[12];
|
|
||||||
VGbitfield caps;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
return VGU_BAD_HANDLE_ERROR;
|
|
||||||
}
|
|
||||||
caps = vgGetPathCapabilities(path);
|
|
||||||
if (!(caps & VG_PATH_CAPABILITY_APPEND_TO)) {
|
|
||||||
return VGU_PATH_CAPABILITY_ERROR;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
coords[0] = cx + width/2; coords[1] = cy;
|
|
||||||
|
|
||||||
coords[2] = width/2; coords[3] = height/2; coords[4] = 0;
|
|
||||||
coords[5] = -width; coords[6] = 0;
|
|
||||||
|
|
||||||
coords[7] = width/2; coords[8] = height/2; coords[9] = 0;
|
|
||||||
coords[10] = width; coords[11] = 0;
|
|
||||||
|
|
||||||
vgu_append_float_coords(path, cmds, 4, coords, 11);
|
|
||||||
|
|
||||||
return VGU_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGUErrorCode vguArc(VGPath path,
|
|
||||||
VGfloat x, VGfloat y,
|
|
||||||
VGfloat width, VGfloat height,
|
|
||||||
VGfloat startAngle,
|
|
||||||
VGfloat angleExtent,
|
|
||||||
VGUArcType arcType)
|
|
||||||
{
|
|
||||||
VGubyte cmds[11];
|
|
||||||
VGfloat coords[40];
|
|
||||||
VGbitfield caps;
|
|
||||||
VGfloat last = startAngle + angleExtent;
|
|
||||||
VGint i, c = 0;
|
|
||||||
|
|
||||||
if (path == VG_INVALID_HANDLE) {
|
|
||||||
return VGU_BAD_HANDLE_ERROR;
|
|
||||||
}
|
|
||||||
caps = vgGetPathCapabilities(path);
|
|
||||||
if (!(caps & VG_PATH_CAPABILITY_APPEND_TO)) {
|
|
||||||
return VGU_PATH_CAPABILITY_ERROR;
|
|
||||||
}
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
}
|
|
||||||
if (arcType != VGU_ARC_OPEN &&
|
|
||||||
arcType != VGU_ARC_CHORD &&
|
|
||||||
arcType != VGU_ARC_PIE) {
|
|
||||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmds[c] = VG_MOVE_TO_ABS; ++c;
|
|
||||||
coords[0] = x+cos(DEGREES_TO_RADIANS(startAngle))*width/2;
|
|
||||||
coords[1] = y+sin(DEGREES_TO_RADIANS(startAngle))*height/2;
|
|
||||||
#ifdef DEBUG_VGUARC
|
|
||||||
debug_printf("start [%f, %f]\n", coords[0], coords[1]);
|
|
||||||
#endif
|
|
||||||
i = 2;
|
|
||||||
if (angleExtent > 0) {
|
|
||||||
VGfloat angle = startAngle + 180;
|
|
||||||
while (angle < last) {
|
|
||||||
cmds[c] = VG_SCCWARC_TO_ABS; ++c;
|
|
||||||
coords[i] = width/2; coords[i+1] = height/2; coords[i+2] = 0;
|
|
||||||
coords[i+3] = x + cos(DEGREES_TO_RADIANS(angle))*width/2;
|
|
||||||
coords[i+4] = y + sin(DEGREES_TO_RADIANS(angle))*height/2;
|
|
||||||
#ifdef DEBUG_VGUARC
|
|
||||||
debug_printf("1 [%f, %f]\n", coords[i+3],
|
|
||||||
coords[i+4]);
|
|
||||||
#endif
|
|
||||||
i += 5;
|
|
||||||
angle += 180;
|
|
||||||
}
|
|
||||||
cmds[c] = VG_SCCWARC_TO_ABS; ++c;
|
|
||||||
coords[i] = width/2; coords[i+1] = height/2; coords[i+2] = 0;
|
|
||||||
coords[i+3] = x+cos(DEGREES_TO_RADIANS(last))*width/2;
|
|
||||||
coords[i+4] = y+sin(DEGREES_TO_RADIANS(last))*height/2;
|
|
||||||
#ifdef DEBUG_VGUARC
|
|
||||||
debug_printf("2 [%f, %f]\n", coords[i+3],
|
|
||||||
coords[i+4]);
|
|
||||||
#endif
|
|
||||||
i += 5;
|
|
||||||
} else {
|
|
||||||
VGfloat angle = startAngle - 180;
|
|
||||||
while (angle > last) {
|
|
||||||
cmds[c] = VG_SCWARC_TO_ABS; ++c;
|
|
||||||
coords[i] = width/2; coords[i+1] = height/2; coords[i+2] = 0;
|
|
||||||
coords[i+3] = x + cos(DEGREES_TO_RADIANS(angle)) * width/2;
|
|
||||||
coords[i+4] = y + sin(DEGREES_TO_RADIANS(angle)) * height/2;
|
|
||||||
#ifdef DEBUG_VGUARC
|
|
||||||
debug_printf("3 [%f, %f]\n", coords[i+3],
|
|
||||||
coords[i+4]);
|
|
||||||
#endif
|
|
||||||
angle -= 180;
|
|
||||||
i += 5;
|
|
||||||
}
|
|
||||||
cmds[c] = VG_SCWARC_TO_ABS; ++c;
|
|
||||||
coords[i] = width/2; coords[i+1] = height/2; coords[i+2] = 0;
|
|
||||||
coords[i+3] = x + cos(DEGREES_TO_RADIANS(last)) * width/2;
|
|
||||||
coords[i+4] = y + sin(DEGREES_TO_RADIANS(last)) * height/2;
|
|
||||||
#ifdef DEBUG_VGUARC
|
|
||||||
debug_printf("4 [%f, %f]\n", coords[i+3],
|
|
||||||
coords[i+4]);
|
|
||||||
#endif
|
|
||||||
i += 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arcType == VGU_ARC_PIE) {
|
|
||||||
cmds[c] = VG_LINE_TO_ABS; ++c;
|
|
||||||
coords[i] = x; coords[i + 1] = y;
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
if (arcType == VGU_ARC_PIE || arcType == VGU_ARC_CHORD) {
|
|
||||||
cmds[c] = VG_CLOSE_PATH;
|
|
||||||
++c;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(c < 11);
|
|
||||||
|
|
||||||
vgu_append_float_coords(path, cmds, c, coords, i);
|
|
||||||
|
|
||||||
return VGU_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGUErrorCode vguComputeWarpQuadToSquare(VGfloat sx0, VGfloat sy0,
|
|
||||||
VGfloat sx1, VGfloat sy1,
|
|
||||||
VGfloat sx2, VGfloat sy2,
|
|
||||||
VGfloat sx3, VGfloat sy3,
|
|
||||||
VGfloat * matrix)
|
|
||||||
{
|
|
||||||
struct matrix mat;
|
|
||||||
|
|
||||||
if (!matrix || !is_aligned(matrix))
|
|
||||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
|
|
||||||
if (!matrix_quad_to_square(sx0, sy0,
|
|
||||||
sx1, sy1,
|
|
||||||
sx2, sy2,
|
|
||||||
sx3, sy3,
|
|
||||||
&mat))
|
|
||||||
return VGU_BAD_WARP_ERROR;
|
|
||||||
|
|
||||||
if (!matrix_is_invertible(&mat))
|
|
||||||
return VGU_BAD_WARP_ERROR;
|
|
||||||
|
|
||||||
memcpy(matrix, mat.m, sizeof(VGfloat) * 9);
|
|
||||||
|
|
||||||
return VGU_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGUErrorCode vguComputeWarpSquareToQuad(VGfloat dx0, VGfloat dy0,
|
|
||||||
VGfloat dx1, VGfloat dy1,
|
|
||||||
VGfloat dx2, VGfloat dy2,
|
|
||||||
VGfloat dx3, VGfloat dy3,
|
|
||||||
VGfloat * matrix)
|
|
||||||
{
|
|
||||||
struct matrix mat;
|
|
||||||
|
|
||||||
if (!matrix || !is_aligned(matrix))
|
|
||||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
|
|
||||||
if (!matrix_square_to_quad(dx0, dy0,
|
|
||||||
dx1, dy1,
|
|
||||||
dx2, dy2,
|
|
||||||
dx3, dy3,
|
|
||||||
&mat))
|
|
||||||
return VGU_BAD_WARP_ERROR;
|
|
||||||
|
|
||||||
if (!matrix_is_invertible(&mat))
|
|
||||||
return VGU_BAD_WARP_ERROR;
|
|
||||||
|
|
||||||
memcpy(matrix, mat.m, sizeof(VGfloat) * 9);
|
|
||||||
|
|
||||||
return VGU_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
VGUErrorCode vguComputeWarpQuadToQuad(VGfloat dx0, VGfloat dy0,
|
|
||||||
VGfloat dx1, VGfloat dy1,
|
|
||||||
VGfloat dx2, VGfloat dy2,
|
|
||||||
VGfloat dx3, VGfloat dy3,
|
|
||||||
VGfloat sx0, VGfloat sy0,
|
|
||||||
VGfloat sx1, VGfloat sy1,
|
|
||||||
VGfloat sx2, VGfloat sy2,
|
|
||||||
VGfloat sx3, VGfloat sy3,
|
|
||||||
VGfloat * matrix)
|
|
||||||
{
|
|
||||||
struct matrix mat;
|
|
||||||
|
|
||||||
if (!matrix || !is_aligned(matrix))
|
|
||||||
return VGU_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
|
|
||||||
if (!matrix_quad_to_quad(dx0, dy0,
|
|
||||||
dx1, dy1,
|
|
||||||
dx2, dy2,
|
|
||||||
dx3, dy3,
|
|
||||||
sx0, sy0,
|
|
||||||
sx1, sy1,
|
|
||||||
sx2, sy2,
|
|
||||||
sx3, sy3,
|
|
||||||
&mat))
|
|
||||||
return VGU_BAD_WARP_ERROR;
|
|
||||||
|
|
||||||
memcpy(matrix, mat.m, sizeof(VGfloat) * 9);
|
|
||||||
|
|
||||||
return VGU_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
@ -232,10 +232,4 @@ endif
|
||||||
es2api/glapi_mapi_tmp.h: glapi/gen/gl_and_es_API.xml $(glapi_gen_mapi_deps)
|
es2api/glapi_mapi_tmp.h: glapi/gen/gl_and_es_API.xml $(glapi_gen_mapi_deps)
|
||||||
$(call glapi_gen_mapi,$<,es2api)
|
$(call glapi_gen_mapi,$<,es2api)
|
||||||
|
|
||||||
# XXX: Inline vgapi's Makefile.am here.
|
|
||||||
EXTRA_DIST += vgapi
|
|
||||||
# if HAVE_OPENVG
|
|
||||||
# SUBDIRS += vgapi
|
|
||||||
# endif
|
|
||||||
|
|
||||||
include $(top_srcdir)/install-lib-links.mk
|
include $(top_srcdir)/install-lib-links.mk
|
||||||
|
|
|
||||||
|
|
@ -816,25 +816,8 @@ typedef int GLclampx;
|
||||||
|
|
||||||
return header
|
return header
|
||||||
|
|
||||||
class VGAPIPrinter(ABIPrinter):
|
|
||||||
"""OpenVG API Printer"""
|
|
||||||
|
|
||||||
def __init__(self, entries):
|
|
||||||
super(VGAPIPrinter, self).__init__(entries)
|
|
||||||
|
|
||||||
self.api_defines = ['VG_VGEXT_PROTOTYPES']
|
|
||||||
self.api_headers = ['"VG/openvg.h"', '"VG/vgext.h"']
|
|
||||||
self.api_call = 'VG_API_CALL'
|
|
||||||
self.api_entry = 'VG_API_ENTRY'
|
|
||||||
self.api_attrs = 'VG_API_EXIT'
|
|
||||||
|
|
||||||
self.prefix_lib = 'vg'
|
|
||||||
self.prefix_app = 'vega'
|
|
||||||
self.prefix_noop = 'noop'
|
|
||||||
self.prefix_warn = 'vg'
|
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
printers = ['vgapi', 'glapi', 'es1api', 'es2api', 'shared-glapi']
|
printers = ['glapi', 'es1api', 'es2api', 'shared-glapi']
|
||||||
modes = ['lib', 'app']
|
modes = ['lib', 'app']
|
||||||
|
|
||||||
parser = OptionParser(usage='usage: %prog [options] <filename>')
|
parser = OptionParser(usage='usage: %prog [options] <filename>')
|
||||||
|
|
@ -853,7 +836,6 @@ def parse_args():
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
printers = {
|
printers = {
|
||||||
'vgapi': VGAPIPrinter,
|
|
||||||
'glapi': GLAPIPrinter,
|
'glapi': GLAPIPrinter,
|
||||||
'es1api': ES1APIPrinter,
|
'es1api': ES1APIPrinter,
|
||||||
'es2api': ES2APIPrinter,
|
'es2api': ES2APIPrinter,
|
||||||
|
|
|
||||||
1
src/mapi/vgapi/.gitignore
vendored
1
src/mapi/vgapi/.gitignore
vendored
|
|
@ -1 +0,0 @@
|
||||||
vgapi_tmp.h
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
# Copyright © 2012 Intel Corporation
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
# copy of this software and associated documentation files (the "Software"),
|
|
||||||
# to deal in the Software without restriction, including without limitation
|
|
||||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
# and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
# Software is furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice (including the next
|
|
||||||
# paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
# Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
# IN THE SOFTWARE.
|
|
||||||
|
|
||||||
AM_CPPFLAGS = \
|
|
||||||
$(DEFINES) \
|
|
||||||
$(SELINUX_CFLAGS) \
|
|
||||||
-I$(top_srcdir)/include \
|
|
||||||
-I$(top_srcdir)/src/mapi \
|
|
||||||
-DMAPI_ABI_HEADER=\"vgapi_tmp.h\"
|
|
||||||
|
|
||||||
AM_CFLAGS = $(VISIBILITY_CFLAGS)
|
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
|
||||||
pkgconfig_DATA = vg.pc
|
|
||||||
|
|
||||||
VG_includedir = $(includedir)/VG
|
|
||||||
VG_include_HEADERS = \
|
|
||||||
$(top_srcdir)/include/VG/openvg.h \
|
|
||||||
$(top_srcdir)/include/VG/vgext.h \
|
|
||||||
$(top_srcdir)/include/VG/vgplatform.h \
|
|
||||||
$(top_srcdir)/include/VG/vgu.h
|
|
||||||
|
|
||||||
lib_LTLIBRARIES = libOpenVG.la
|
|
||||||
|
|
||||||
TOP=$(top_srcdir)
|
|
||||||
include ../Makefile.sources
|
|
||||||
libOpenVG_la_SOURCES = $(MAPI_FILES) vgapi_tmp.h
|
|
||||||
libOpenVG_la_LIBADD = $(VG_LIB_DEPS)
|
|
||||||
libOpenVG_la_LDFLAGS = \
|
|
||||||
-no-undefined \
|
|
||||||
-version-number 1 \
|
|
||||||
$(GC_SECTIONS) \
|
|
||||||
$(LD_NO_UNDEFINED)
|
|
||||||
|
|
||||||
vgapi_tmp.h: $(srcdir)/vgapi.csv $(top_srcdir)/src/mapi/mapi_abi.py
|
|
||||||
$(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(top_srcdir)/src/mapi/mapi_abi.py \
|
|
||||||
--printer vgapi --mode lib $< > $@
|
|
||||||
|
|
||||||
EXTRA_DIST = SConscript vgapi.csv
|
|
||||||
BUILT_SOURCES = vgapi_tmp.h
|
|
||||||
CLEANFILES = $(BUILT_SOURCES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/install-lib-links.mk
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
#######################################################################
|
|
||||||
# SConscript for vgapi
|
|
||||||
|
|
||||||
from sys import executable as python_cmd
|
|
||||||
|
|
||||||
Import('*')
|
|
||||||
|
|
||||||
env = env.Clone()
|
|
||||||
|
|
||||||
vgapi_header, = env.CodeGenerate(
|
|
||||||
target = 'vgapi_tmp.h',
|
|
||||||
script = '../mapi_abi.py',
|
|
||||||
source = 'vgapi.csv',
|
|
||||||
command = python_cmd + ' $SCRIPT --printer vgapi --mode lib $SOURCE > $TARGET'
|
|
||||||
)
|
|
||||||
|
|
||||||
env.Append(CPPDEFINES = [
|
|
||||||
'MAPI_ABI_HEADER=\\"vgapi/vgapi_tmp.h\\"',
|
|
||||||
'MAPI_DLL_EXPORTS',
|
|
||||||
'KHRONOS_DLL_EXPORTS',
|
|
||||||
])
|
|
||||||
|
|
||||||
env.Append(CPPPATH = [
|
|
||||||
'#/include',
|
|
||||||
'#/src/mapi',
|
|
||||||
Dir('..'), # vgapi/vgapi_tmp.h build path
|
|
||||||
])
|
|
||||||
|
|
||||||
mapi_sources = [
|
|
||||||
'entry.c',
|
|
||||||
'mapi.c',
|
|
||||||
'stub.c',
|
|
||||||
'table.c',
|
|
||||||
'u_current.c',
|
|
||||||
'u_execmem.c',
|
|
||||||
]
|
|
||||||
|
|
||||||
vgapi_objects = []
|
|
||||||
for s in mapi_sources:
|
|
||||||
o = env.SharedObject(s[:-2], '../' + s)
|
|
||||||
vgapi_objects.append(o)
|
|
||||||
|
|
||||||
env.Depends(vgapi_objects, vgapi_header)
|
|
||||||
|
|
||||||
# libOpenVG.dll
|
|
||||||
env['LIBPREFIX'] = 'lib'
|
|
||||||
env['SHLIBPREFIX'] = 'lib'
|
|
||||||
|
|
||||||
openvg = env.SharedLibrary(
|
|
||||||
target = 'OpenVG',
|
|
||||||
source = vgapi_objects,
|
|
||||||
)
|
|
||||||
|
|
||||||
env.InstallSharedLibrary(openvg, version=(1, 0, 0))
|
|
||||||
|
|
||||||
if env['platform'] == 'windows':
|
|
||||||
openvg = env.FindIxes(openvg, 'LIBPREFIX', 'LIBSUFFIX')
|
|
||||||
else:
|
|
||||||
openvg = env.FindIxes(openvg, 'SHLIBPREFIX', 'SHLIBSUFFIX')
|
|
||||||
|
|
||||||
Export(['openvg'])
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
prefix=@prefix@
|
|
||||||
exec_prefix=${prefix}
|
|
||||||
libdir=@libdir@
|
|
||||||
includedir=@includedir@
|
|
||||||
|
|
||||||
Name: vg
|
|
||||||
Description: Mesa OpenVG 1.0 library
|
|
||||||
Requires.private:
|
|
||||||
Version: @VERSION@
|
|
||||||
Libs: -L${libdir} -lOpenVG
|
|
||||||
Libs.private: @VG_PC_LIB_PRIV@
|
|
||||||
Cflags: -I${includedir}
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
# This is the source file for the various generate structs/tables/functions
|
|
||||||
# used in st/vega.
|
|
||||||
|
|
||||||
# OpenVG 1.0
|
|
||||||
void, AppendPath, VGPath dstPath, VGPath srcPath
|
|
||||||
void, AppendPathData, VGPath dstPath, VGint numSegments, const VGubyte *pathSegments, const void *pathData
|
|
||||||
VGImage, ChildImage, VGImage parent, VGint x, VGint y, VGint width, VGint height
|
|
||||||
void, Clear, VGint x, VGint y, VGint width, VGint height
|
|
||||||
void, ClearImage, VGImage image, VGint x, VGint y, VGint width, VGint height
|
|
||||||
void, ClearPath, VGPath path, VGbitfield capabilities
|
|
||||||
void, ColorMatrix, VGImage dst, VGImage src, const VGfloat *matrix
|
|
||||||
void, Convolve, VGImage dst, VGImage src, VGint kernelWidth, VGint kernelHeight, VGint shiftX, VGint shiftY, const VGshort *kernel, VGfloat scale, VGfloat bias, VGTilingMode tilingMode
|
|
||||||
void, CopyImage, VGImage dst, VGint dx, VGint dy, VGImage src, VGint sx, VGint sy, VGint width, VGint height, VGboolean dither
|
|
||||||
void, CopyPixels, VGint dx, VGint dy, VGint sx, VGint sy, VGint width, VGint height
|
|
||||||
VGImage, CreateImage, VGImageFormat format, VGint width, VGint height, VGbitfield allowedQuality
|
|
||||||
VGPaint, CreatePaint, void
|
|
||||||
VGPath, CreatePath, VGint pathFormat, VGPathDatatype datatype, VGfloat scale, VGfloat bias, VGint segmentCapacityHint, VGint coordCapacityHint, VGbitfield capabilities
|
|
||||||
void, DestroyImage, VGImage image
|
|
||||||
void, DestroyPaint, VGPaint paint
|
|
||||||
void, DestroyPath, VGPath path
|
|
||||||
void, DrawImage, VGImage image
|
|
||||||
void, DrawPath, VGPath path, VGbitfield paintModes
|
|
||||||
void, Finish, void
|
|
||||||
void, Flush, void
|
|
||||||
void, GaussianBlur, VGImage dst, VGImage src, VGfloat stdDeviationX, VGfloat stdDeviationY, VGTilingMode tilingMode
|
|
||||||
VGuint, GetColor, VGPaint paint
|
|
||||||
VGErrorCode, GetError, void
|
|
||||||
void, GetImageSubData, VGImage image, void *data, VGint dataStride, VGImageFormat dataFormat, VGint x, VGint y, VGint width, VGint height
|
|
||||||
void, GetMatrix, VGfloat *m
|
|
||||||
VGPaint, GetPaint, VGPaintMode paintMode
|
|
||||||
VGint, GetParameterVectorSize, VGHandle object, VGint paramType
|
|
||||||
VGfloat, GetParameterf, VGHandle object, VGint paramType
|
|
||||||
void, GetParameterfv, VGHandle object, VGint paramType, VGint count, VGfloat *values
|
|
||||||
VGint, GetParameteri, VGHandle object, VGint paramType
|
|
||||||
void, GetParameteriv, VGHandle object, VGint paramType, VGint count, VGint *values
|
|
||||||
VGImage, GetParent, VGImage image
|
|
||||||
VGbitfield, GetPathCapabilities, VGPath path
|
|
||||||
void, GetPixels, VGImage dst, VGint dx, VGint dy, VGint sx, VGint sy, VGint width, VGint height
|
|
||||||
const VGubyte *, GetString, VGStringID name
|
|
||||||
VGint, GetVectorSize, VGParamType type
|
|
||||||
VGfloat, Getf, VGParamType type
|
|
||||||
void, Getfv, VGParamType type, VGint count, VGfloat *values
|
|
||||||
VGint, Geti, VGParamType type
|
|
||||||
void, Getiv, VGParamType type, VGint count, VGint *values
|
|
||||||
VGHardwareQueryResult, HardwareQuery, VGHardwareQueryType key, VGint setting
|
|
||||||
void, ImageSubData, VGImage image, const void *data, VGint dataStride, VGImageFormat dataFormat, VGint x, VGint y, VGint width, VGint height
|
|
||||||
VGboolean, InterpolatePath, VGPath dstPath, VGPath startPath, VGPath endPath, VGfloat amount
|
|
||||||
void, LoadIdentity, void
|
|
||||||
void, LoadMatrix, const VGfloat *m
|
|
||||||
void, Lookup, VGImage dst, VGImage src, const VGubyte *redLUT, const VGubyte *greenLUT, const VGubyte *blueLUT, const VGubyte *alphaLUT, VGboolean outputLinear, VGboolean outputPremultiplied
|
|
||||||
void, LookupSingle, VGImage dst, VGImage src, const VGuint *lookupTable, VGImageChannel sourceChannel, VGboolean outputLinear, VGboolean outputPremultiplied
|
|
||||||
void, Mask, VGHandle mask, VGMaskOperation operation, VGint x, VGint y, VGint width, VGint height
|
|
||||||
void, ModifyPathCoords, VGPath dstPath, VGint startIndex, VGint numSegments, const void *pathData
|
|
||||||
void, MultMatrix, const VGfloat *m
|
|
||||||
void, PaintPattern, VGPaint paint, VGImage pattern
|
|
||||||
void, PathBounds, VGPath path, VGfloat *minX, VGfloat *minY, VGfloat *width, VGfloat *height
|
|
||||||
VGfloat, PathLength, VGPath path, VGint startSegment, VGint numSegments
|
|
||||||
void, PathTransformedBounds, VGPath path, VGfloat *minX, VGfloat *minY, VGfloat *width, VGfloat *height
|
|
||||||
void, PointAlongPath, VGPath path, VGint startSegment, VGint numSegments, VGfloat distance, VGfloat *x, VGfloat *y, VGfloat *tangentX, VGfloat *tangentY
|
|
||||||
void, ReadPixels, void *data, VGint dataStride, VGImageFormat dataFormat, VGint sx, VGint sy, VGint width, VGint height
|
|
||||||
void, RemovePathCapabilities, VGPath path, VGbitfield capabilities
|
|
||||||
void, Rotate, VGfloat angle
|
|
||||||
void, Scale, VGfloat sx, VGfloat sy
|
|
||||||
void, SeparableConvolve, VGImage dst, VGImage src, VGint kernelWidth, VGint kernelHeight, VGint shiftX, VGint shiftY, const VGshort *kernelX, const VGshort *kernelY, VGfloat scale, VGfloat bias, VGTilingMode tilingMode
|
|
||||||
void, SetColor, VGPaint paint, VGuint rgba
|
|
||||||
void, SetPaint, VGPaint paint, VGbitfield paintModes
|
|
||||||
void, SetParameterf, VGHandle object, VGint paramType, VGfloat value
|
|
||||||
void, SetParameterfv, VGHandle object, VGint paramType, VGint count, const VGfloat *values
|
|
||||||
void, SetParameteri, VGHandle object, VGint paramType, VGint value
|
|
||||||
void, SetParameteriv, VGHandle object, VGint paramType, VGint count, const VGint *values
|
|
||||||
void, SetPixels, VGint dx, VGint dy, VGImage src, VGint sx, VGint sy, VGint width, VGint height
|
|
||||||
void, Setf, VGParamType type, VGfloat value
|
|
||||||
void, Setfv, VGParamType type, VGint count, const VGfloat *values
|
|
||||||
void, Seti, VGParamType type, VGint value
|
|
||||||
void, Setiv, VGParamType type, VGint count, const VGint *values
|
|
||||||
void, Shear, VGfloat shx, VGfloat shy
|
|
||||||
void, TransformPath, VGPath dstPath, VGPath srcPath
|
|
||||||
void, Translate, VGfloat tx, VGfloat ty
|
|
||||||
void, WritePixels, const void *data, VGint dataStride, VGImageFormat dataFormat, VGint dx, VGint dy, VGint width, VGint height
|
|
||||||
|
|
||||||
## OpenVG 1.1
|
|
||||||
void, ClearGlyph, VGFont font, VGuint glyphIndex
|
|
||||||
void, CopyMask, VGMaskLayer maskLayer, VGint dx, VGint dy, VGint sx, VGint sy, VGint width, VGint height
|
|
||||||
VGFont, CreateFont, VGint glyphCapacityHint
|
|
||||||
VGMaskLayer, CreateMaskLayer, VGint width, VGint height
|
|
||||||
void, DestroyFont, VGFont font
|
|
||||||
void, DestroyMaskLayer, VGMaskLayer maskLayer
|
|
||||||
void, DrawGlyph, VGFont font, VGuint glyphIndex, VGbitfield paintModes, VGboolean allowAutoHinting
|
|
||||||
void, DrawGlyphs, VGFont font, VGint glyphCount, const VGuint *glyphIndices, const VGfloat *adjustments_x, const VGfloat *adjustments_y, VGbitfield paintModes, VGboolean allowAutoHinting
|
|
||||||
void, FillMaskLayer, VGMaskLayer maskLayer, VGint x, VGint y, VGint width, VGint height, VGfloat value
|
|
||||||
void, RenderToMask, VGPath path, VGbitfield paintModes, VGMaskOperation operation
|
|
||||||
void, SetGlyphToImage, VGFont font, VGuint glyphIndex, VGImage image, const VGfloat glyphOrigin[2], const VGfloat escapement[2]
|
|
||||||
void, SetGlyphToPath, VGFont font, VGuint glyphIndex, VGPath path, VGboolean isHinted, const VGfloat glyphOrigin[2], const VGfloat escapement[2]
|
|
||||||
|
Loading…
Add table
Reference in a new issue