1544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin/**************************************************************************
2544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
3544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * Copyright 2009 VMware, Inc.  All Rights Reserved.
4544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
5544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * Permission is hereby granted, free of charge, to any person obtaining a
6544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * copy of this software and associated documentation files (the
7544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * "Software"), to deal in the Software without restriction, including
8544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * without limitation the rights to use, copy, modify, merge, publish,
9544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * distribute, sub license, and/or sell copies of the Software, and to
10544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * permit persons to whom the Software is furnished to do so, subject to
11544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * the following conditions:
12544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
13544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * The above copyright notice and this permission notice (including the
14544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * next paragraph) shall be included in all copies or substantial portions
15544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * of the Software.
16544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
17544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin *
25544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin **************************************************************************/
26544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
27544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "paint.h"
28544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
29544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "matrix.h"
30544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "image.h"
31544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
32544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "pipe/p_compiler.h"
3328486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
34544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
35544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "util/u_memory.h"
36544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "util/u_math.h"
37e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger#include "util/u_sampler.h"
38544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
39544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#include "cso_cache/cso_context.h"
40544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
41544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct vg_paint {
42544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct vg_object base;
43544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
44544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGPaintType type;
45544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
46544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct {
47544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGfloat color[4];
48544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGint colori[4];
49544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   } solid;
50544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
51544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct {
52544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGColorRampSpreadMode spread;
53544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGuint color_data[1024];
54544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      struct {
55544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         VGfloat  coords[4];
56544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         VGint  coordsi[4];
57544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      } linear;
58544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      struct {
59544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         VGfloat vals[5];
60544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         VGint valsi[5];
61544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      } radial;
62e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger      struct pipe_sampler_view *sampler_view;
63544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      struct pipe_sampler_state sampler;
64544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
65544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGfloat *ramp_stops;
66544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGint *ramp_stopsi;
67544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGint    num_stops;
68544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
69544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGboolean color_ramps_premultiplied;
70544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   } gradient;
71544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
72544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct {
73e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger      struct pipe_sampler_view *sampler_view;
74544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGTilingMode tiling_mode;
75544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      struct pipe_sampler_state sampler;
76544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   } pattern;
77544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
78f44b0ff84338c2184ef4f2cbb752bf62f4fff1fcRoland Scheidegger   /* XXX next 3 all unneded? */
79287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct pipe_resource *cbuf;
80544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct pipe_shader_state fs_state;
81544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   void *fs;
82544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin};
83544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
84544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic INLINE VGuint mix_pixels(VGuint p1, VGuint a, VGuint p2, VGuint b)
85544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
86544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGuint t = (p1 & 0xff00ff) * a + (p2 & 0xff00ff) * b;
87544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   t >>= 8; t &= 0xff00ff;
88544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
89544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   p1 = ((p1 >> 8) & 0xff00ff) * a + ((p2 >> 8) & 0xff00ff) * b;
90544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   p1 &= 0xff00ff00; p1 |= t;
91544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
92544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return p1;
93544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
94544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
95544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic INLINE VGuint float4_to_argb(const VGfloat *clr)
96544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
97544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return float_to_ubyte(clr[3]) << 24 |
98544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      float_to_ubyte(clr[0]) << 16 |
99544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      float_to_ubyte(clr[1]) << 8 |
100544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      float_to_ubyte(clr[2]) << 0;
101544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
102544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
103544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic INLINE void create_gradient_data(const VGfloat *ramp_stops,
104544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                        VGint num,
105544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                        VGuint *data,
106544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                        VGint size)
107544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
108544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint i;
109544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint pos = 0;
110544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat fpos = 0, incr = 1.f / size;
111544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGuint last_color;
112544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
113544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   while (fpos < ramp_stops[0]) {
114544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      data[pos] = float4_to_argb(ramp_stops + 1);
115544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      fpos += incr;
116544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++pos;
117544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
118544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
119544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   for (i = 0; i < num - 1; ++i) {
120544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGint rcur  = 5 * i;
121544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGint rnext = 5 * (i + 1);
122544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGfloat delta = 1.f/(ramp_stops[rnext] - ramp_stops[rcur]);
123544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      while (fpos < ramp_stops[rnext] && pos < size) {
124544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         VGint dist = 256 * ((fpos - ramp_stops[rcur]) * delta);
125544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         VGint idist = 256 - dist;
126544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         VGuint current_color = float4_to_argb(ramp_stops + rcur + 1);
127544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         VGuint next_color = float4_to_argb(ramp_stops + rnext + 1);
128544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         data[pos] = mix_pixels(current_color, idist,
129544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                next_color, dist);
130544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         fpos += incr;
131544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         ++pos;
132544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      }
133544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
134544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
135544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   last_color = float4_to_argb(ramp_stops + ((num - 1) * 5 + 1));
136544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   while (pos < size) {
137544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      data[pos] = last_color;
138544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      ++pos;
139544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
140544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   data[size-1] = last_color;
141544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
142544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
143287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic INLINE struct pipe_resource *create_gradient_texture(struct vg_paint *p)
144544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
145544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct pipe_context *pipe = p->base.ctx->pipe;
146544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct pipe_screen *screen = pipe->screen;
147287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct pipe_resource *tex = 0;
148287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct pipe_resource templ;
149544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
150544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memset(&templ, 0, sizeof(templ));
151544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   templ.target = PIPE_TEXTURE_1D;
152b306308757c0ce3cf47a50bac12bb39f212ca6b2José Fonseca   templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
153544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   templ.last_level = 0;
154d509f84543d0979e9bb53c20c195f378dd61e728Roland Scheidegger   templ.width0 = 1024;
155d509f84543d0979e9bb53c20c195f378dd61e728Roland Scheidegger   templ.height0 = 1;
156d509f84543d0979e9bb53c20c195f378dd61e728Roland Scheidegger   templ.depth0 = 1;
1574c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   templ.array_size = 1;
158287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   templ.bind = PIPE_BIND_SAMPLER_VIEW;
159544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
160287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   tex = screen->resource_create(screen, &templ);
161544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
162544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   { /* upload color_data */
163544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      struct pipe_transfer *transfer =
1644c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         pipe_get_transfer(p->base.ctx->pipe, tex, 0, 0,
1654c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                           PIPE_TRANSFER_WRITE, 0, 0, 1024, 1);
166b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      void *map = pipe->transfer_map(pipe, transfer);
167544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      memcpy(map, p->gradient.color_data, sizeof(VGint)*1024);
168b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      pipe->transfer_unmap(pipe, transfer);
169287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe->transfer_destroy(pipe, transfer);
170544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
171544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
172544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return tex;
173544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
174544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
175e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheideggerstatic INLINE struct pipe_sampler_view *create_gradient_sampler_view(struct vg_paint *p)
176e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger{
177e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   struct pipe_context *pipe = p->base.ctx->pipe;
178287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct pipe_resource *texture;
179e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   struct pipe_sampler_view view_templ;
180e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   struct pipe_sampler_view *view;
181e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger
182e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   texture = create_gradient_texture(p);
183e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger
184e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   if (!texture)
185e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger      return NULL;
186e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger
187e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   u_sampler_view_default_template(&view_templ, texture, texture->format);
188e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   view = pipe->create_sampler_view(pipe, texture, &view_templ);
189e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   /* want the texture to go away if the view is freed */
190287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_resource_reference(&texture, NULL);
191e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger
192e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   return view;
193e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger}
194e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger
195544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstruct vg_paint * paint_create(struct vg_context *ctx)
196544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
197544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct vg_paint *paint = CALLOC_STRUCT(vg_paint);
198544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   const VGfloat default_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
199544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   const VGfloat def_ling[] = {0.0f, 0.0f, 1.0f, 0.0f};
200544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   const VGfloat def_radg[] = {0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
201544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   vg_init_object(&paint->base, ctx, VG_OBJECT_PAINT);
202ceb6d34906c7c03c102c7e78dd02f5b0ebab4ca9Chia-I Wu   vg_context_add_object(ctx, &paint->base);
203544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
204544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->type = VG_PAINT_TYPE_COLOR;
205544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(paint->solid.color, default_color,
206544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin          4 * sizeof(VGfloat));
207544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->gradient.spread = VG_COLOR_RAMP_SPREAD_PAD;
208544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(paint->gradient.linear.coords, def_ling,
209544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin          4 * sizeof(VGfloat));
210544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(paint->gradient.radial.vals, def_radg,
211544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin          5 * sizeof(VGfloat));
212544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
213544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->gradient.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
214544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->gradient.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
215544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->gradient.sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
216544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->gradient.sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
217544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->gradient.sampler.normalized_coords = 1;
218544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
219544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(&paint->pattern.sampler,
220544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin          &paint->gradient.sampler,
221544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin          sizeof(struct pipe_sampler_state));
222544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
223544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return paint;
224544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
225544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
226544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_destroy(struct vg_paint *paint)
227544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
228544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct vg_context *ctx = paint->base.ctx;
229e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   pipe_sampler_view_reference(&paint->gradient.sampler_view, NULL);
230e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   if (paint->pattern.sampler_view)
231e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger      pipe_sampler_view_reference(&paint->pattern.sampler_view, NULL);
232544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (ctx)
233ceb6d34906c7c03c102c7e78dd02f5b0ebab4ca9Chia-I Wu      vg_context_remove_object(ctx, &paint->base);
234544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
235544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   free(paint->gradient.ramp_stopsi);
236544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   free(paint->gradient.ramp_stops);
237f914cd1796845164109c837a111c39ba64852ad4nobled   FREE(paint);
238544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
239544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
240544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_color(struct vg_paint *paint,
241544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                     const VGfloat *color)
242544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
243544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.color[0] = color[0];
244544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.color[1] = color[1];
245544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.color[2] = color[2];
246544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.color[3] = color[3];
247544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
248544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.colori[0] = FLT_TO_INT(color[0]);
249544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.colori[1] = FLT_TO_INT(color[1]);
250544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.colori[2] = FLT_TO_INT(color[2]);
251544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.colori[3] = FLT_TO_INT(color[3]);
252544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
253544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
254544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinstatic INLINE void paint_color_buffer(struct vg_paint *paint, void *buffer)
255544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
256544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat *map = (VGfloat*)buffer;
257544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(buffer, paint->solid.color, 4 * sizeof(VGfloat));
258544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[4] = 0.f;
259544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[5] = 1.f;
260544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[6] = 2.f;
261544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[7] = 4.f;
262544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
263544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
264b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wustatic INLINE void paint_linear_gradient_buffer(struct vg_paint *paint,
265b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu                                                const struct matrix *inv,
266b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu                                                void *buffer)
267544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
268544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat *map = (VGfloat*)buffer;
269d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   VGfloat dd;
270544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
271544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[0] = paint->gradient.linear.coords[2] - paint->gradient.linear.coords[0];
272544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[1] = paint->gradient.linear.coords[3] - paint->gradient.linear.coords[1];
273d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   dd = (map[0] * map[0] + map[1] * map[1]);
274d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu
275d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   map[2] = (dd > 0.0f) ? 1.f / dd : 0.f;
276544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[3] = 1.f;
277544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
278544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[4] = 0.f;
279544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[5] = 1.f;
280544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[6] = 2.f;
281544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[7] = 4.f;
282544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   {
283544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      struct matrix mat;
284544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      matrix_load_identity(&mat);
285b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu      /* VEGA_LINEAR_GRADIENT_SHADER expects the first point to be at (0, 0) */
286544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      matrix_translate(&mat, -paint->gradient.linear.coords[0], -paint->gradient.linear.coords[1]);
287b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu      matrix_mult(&mat, inv);
288544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
289544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      map[8]  = mat.m[0]; map[9]  = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
290544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
291544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      map[16] = mat.m[2]; map[17] = mat.m[5]; map[18] = mat.m[8]; map[19] = 0.f;
292544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
293544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#if 0
294544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   debug_printf("Coords  (%f, %f, %f, %f)\n",
295544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                map[0], map[1], map[2], map[3]);
296544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#endif
297544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
298544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
299544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
300b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wustatic INLINE void paint_radial_gradient_buffer(struct vg_paint *paint,
301b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu                                                const struct matrix *inv,
302b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu                                                void *buffer)
303544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
304d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   const VGfloat *center = &paint->gradient.radial.vals[0];
305d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   const VGfloat *focal = &paint->gradient.radial.vals[2];
306d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   VGfloat rr = paint->gradient.radial.vals[4];
307544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat *map = (VGfloat*)buffer;
308d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   VGfloat dd, new_focal[2];
309d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu
310d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   rr *= rr;
311d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu
312d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   map[0] = center[0] - focal[0];
313d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   map[1] = center[1] - focal[1];
314d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   dd = map[0] * map[0] + map[1] * map[1];
315d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu
316d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   /* focal point must lie inside the circle */
317d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   if (0.998f * rr < dd) {
318d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      VGfloat scale;
319d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu
320d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      scale = (dd > 0.0f) ? sqrt(0.998f * rr / dd) : 0.0f;
321d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      map[0] *= scale;
322d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      map[1] *= scale;
323544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
324d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      new_focal[0] = center[0] - map[0];
325d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      new_focal[1] = center[1] - map[1];
326d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      dd = map[0] * map[0] + map[1] * map[1];
327d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      focal = new_focal;
328d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   }
329d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu
330d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   map[2] = (rr > dd) ? rr - dd : 1.0f;
331544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[3] = 1.f;
332544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
333544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[4] = 0.f;
334544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[5] = 1.f;
335544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[6] = 2.f;
336544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[7] = 4.f;
337544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
338544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   {
339544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      struct matrix mat;
340544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      matrix_load_identity(&mat);
341d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      matrix_translate(&mat, -focal[0], -focal[1]);
342b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu      matrix_mult(&mat, inv);
343544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
344544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      map[8]  = mat.m[0]; map[9]  = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
345544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
346544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      map[16] = mat.m[2]; map[17] = mat.m[5]; map[18] = mat.m[8]; map[19] = 0.f;
347544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
348544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
349544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#if 0
350544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   debug_printf("Coords  (%f, %f, %f, %f)\n",
351544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                map[0], map[1], map[2], map[3]);
352544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#endif
353544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
354544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
355544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
356b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wustatic INLINE void  paint_pattern_buffer(struct vg_paint *paint,
357b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu                                         const struct matrix *inv,
358b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu                                         void *buffer)
359544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
360544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat *map = (VGfloat *)buffer;
361544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(map, paint->solid.color, 4 * sizeof(VGfloat));
362544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
363544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[4] = 0.f;
364544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   map[5] = 1.f;
365e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   map[6] = paint->pattern.sampler_view->texture->width0;
366e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   map[7] = paint->pattern.sampler_view->texture->height0;
367544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   {
368544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      struct matrix mat;
369b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu
370b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu      memcpy(&mat, inv, sizeof(*inv));
371544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
372544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      map[8]  = mat.m[0]; map[9]  = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
373544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
374544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      map[16] = mat.m[2]; map[17] = mat.m[5]; map[18] = mat.m[8]; map[19] = 0.f;
375544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
376544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
377544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
378544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_type(struct vg_paint *paint, VGPaintType type)
379544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
380544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->type = type;
381544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
382544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
383544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_ramp_stops(struct vg_paint *paint, const VGfloat *stops,
384544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                          int num)
385544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
386544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   const VGfloat default_stops[] = {0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
387544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                    1.0f, 1.0f, 1.0f, 1.0f, 1.0f};
388544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGint i;
389544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   const VGint num_stops = num / 5;
390544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   VGfloat last_coord;
391544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
392544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->gradient.num_stops = num;
393544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (num) {
394544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      free(paint->gradient.ramp_stops);
395544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->gradient.ramp_stops = malloc(sizeof(VGfloat)*num);
396544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      memcpy(paint->gradient.ramp_stops, stops, sizeof(VGfloat)*num);
397544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   } else
398544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      return;
399544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
400544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   /* stops must be in increasing order. the last stop is 1.0. if the
401544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin    * first one is bigger than 1 then the whole sequence is invalid*/
402544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (stops[0] > 1) {
403544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      stops = default_stops;
404544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      num = 10;
405544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
406544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   last_coord = stops[0];
407544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   for (i = 1; i < num_stops; ++i) {
408544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGint idx = 5 * i;
409544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      VGfloat coord = stops[idx];
410544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      if (!floatsEqual(last_coord, coord) && coord < last_coord) {
411544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         stops = default_stops;
412544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         num = 10;
413544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         break;
414544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      }
415544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      last_coord = coord;
416544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
417544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
418544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   create_gradient_data(stops, num / 5, paint->gradient.color_data,
419544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                        1024);
420544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
421e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   if (paint->gradient.sampler_view) {
422e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger      pipe_sampler_view_reference(&paint->gradient.sampler_view, NULL);
423e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger      paint->gradient.sampler_view = NULL;
424544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
425544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
426e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   paint->gradient.sampler_view = create_gradient_sampler_view(paint);
427544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
428544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
429544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_colori(struct vg_paint *p,
430544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                      VGuint rgba)
431544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
432544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   p->solid.color[0] = ((rgba >> 24) & 0xff) / 255.f;
433544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   p->solid.color[1] = ((rgba >> 16) & 0xff) / 255.f;
434544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   p->solid.color[2] = ((rgba >>  8) & 0xff) / 255.f;
435544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   p->solid.color[3] = ((rgba >>  0) & 0xff) / 255.f;
436544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
437544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
438544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack RusinVGuint paint_colori(struct vg_paint *p)
439544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
440544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#define F2B(f) (float_to_ubyte(f))
441544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
442544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return ((F2B(p->solid.color[0]) << 24) |
443544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin           (F2B(p->solid.color[1]) << 16) |
444544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin           (F2B(p->solid.color[2]) << 8)  |
445544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin           (F2B(p->solid.color[3]) << 0));
446544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin#undef F2B
447544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
448544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
449544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_linear_gradient(struct vg_paint *paint,
450544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                               const VGfloat *coords)
451544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
452544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(paint->gradient.linear.coords, coords, sizeof(VGfloat) * 4);
453544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
454544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
455544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_spread_mode(struct vg_paint *paint,
456544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                           VGint mode)
457544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
458544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->gradient.spread = mode;
459544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   switch(mode) {
460544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_COLOR_RAMP_SPREAD_PAD:
461544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->gradient.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
462544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
463544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_COLOR_RAMP_SPREAD_REPEAT:
464544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->gradient.sampler.wrap_s = PIPE_TEX_WRAP_REPEAT;
465544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
466544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_COLOR_RAMP_SPREAD_REFLECT:
467544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->gradient.sampler.wrap_s = PIPE_TEX_WRAP_MIRROR_REPEAT;
468544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
469544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
470544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
471544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
472544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack RusinVGColorRampSpreadMode paint_spread_mode(struct vg_paint *paint)
473544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
474544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return paint->gradient.spread;
475544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
476544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
477544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_radial_gradient(struct vg_paint *paint,
478544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                               const VGfloat *values)
479544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
480544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(paint->gradient.radial.vals, values, sizeof(VGfloat) * 5);
481544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
482544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
483544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_pattern(struct vg_paint *paint,
484544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                       struct vg_image *img)
485544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
486e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   if (paint->pattern.sampler_view)
487e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger      pipe_sampler_view_reference(&paint->pattern.sampler_view, NULL);
488544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
489e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   paint->pattern.sampler_view = NULL;
490e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger   pipe_sampler_view_reference(&paint->pattern.sampler_view,
491e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger                               img->sampler_view);
492544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
493544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
494544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_pattern_tiling(struct vg_paint *paint,
495544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                              VGTilingMode mode)
496544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
497544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->pattern.tiling_mode = mode;
498544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
499544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   switch(mode) {
500544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_TILE_FILL:
501544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->pattern.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
502544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->pattern.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
503544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
504544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_TILE_PAD:
505544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->pattern.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
506544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->pattern.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
507544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
508544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_TILE_REPEAT:
509544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->pattern.sampler.wrap_s = PIPE_TEX_WRAP_REPEAT;
510544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->pattern.sampler.wrap_t = PIPE_TEX_WRAP_REPEAT;
511544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
512544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_TILE_REFLECT:
513544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->pattern.sampler.wrap_s = PIPE_TEX_WRAP_MIRROR_REPEAT;
514544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->pattern.sampler.wrap_t = PIPE_TEX_WRAP_MIRROR_REPEAT;
515544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
516544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   default:
517544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_assert("!Unknown tiling mode");
518544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
519544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
520544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
521544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_get_color(struct vg_paint *paint,
522544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                     VGfloat *color)
523544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
524544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   color[0] = paint->solid.color[0];
525544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   color[1] = paint->solid.color[1];
526544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   color[2] = paint->solid.color[2];
527544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   color[3] = paint->solid.color[3];
528544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
529544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
530544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_ramp_stops(struct vg_paint *paint, VGfloat *stops,
531544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                      int num)
532544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
533544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(stops, paint->gradient.ramp_stops, sizeof(VGfloat)*num);
534544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
535544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
536544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_linear_gradient(struct vg_paint *paint,
537544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                           VGfloat *coords)
538544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
539544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(coords, paint->gradient.linear.coords, sizeof(VGfloat)*4);
540544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
541544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
542544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_radial_gradient(struct vg_paint *paint,
543544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                           VGfloat *coords)
544544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
545544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(coords, paint->gradient.radial.vals, sizeof(VGfloat)*5);
546544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
547544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
548544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinint paint_num_ramp_stops(struct vg_paint *paint)
549544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
550544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return paint->gradient.num_stops;
551544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
552544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
553544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack RusinVGPaintType paint_type(struct vg_paint *paint)
554544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
555544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return paint->type;
556544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
557544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
558544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_coloriv(struct vg_paint *paint,
559544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                      const VGint *color)
560544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
561544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.color[0] = color[0];
562544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.color[1] = color[1];
563544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.color[2] = color[2];
564544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.color[3] = color[3];
565544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
566544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.colori[0] = color[0];
567544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.colori[1] = color[1];
568544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.colori[2] = color[2];
569544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->solid.colori[3] = color[3];
570544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
571544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
572544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_get_coloriv(struct vg_paint *paint,
573544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                      VGint *color)
574544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
575544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   color[0] = paint->solid.colori[0];
576544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   color[1] = paint->solid.colori[1];
577544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   color[2] = paint->solid.colori[2];
578544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   color[3] = paint->solid.colori[3];
579544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
580544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
581544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_color_ramp_premultiplied(struct vg_paint *paint,
582544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                        VGboolean set)
583544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
584544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   paint->gradient.color_ramps_premultiplied = set;
585544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
586544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
587544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack RusinVGboolean paint_color_ramp_premultiplied(struct vg_paint *paint)
588544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
589544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return paint->gradient.color_ramps_premultiplied;
590544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
591544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
592544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_ramp_stopsi(struct vg_paint *paint, const VGint *stops,
593544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                           int num)
594544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
595544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (num) {
596544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      free(paint->gradient.ramp_stopsi);
597544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->gradient.ramp_stopsi = malloc(sizeof(VGint)*num);
598544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      memcpy(paint->gradient.ramp_stopsi, stops, sizeof(VGint)*num);
599544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
600544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
601544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
602544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_ramp_stopsi(struct vg_paint *paint, VGint *stops,
603544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                       int num)
604544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
605544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(stops, paint->gradient.ramp_stopsi, sizeof(VGint)*num);
606544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
607544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
608544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_linear_gradienti(struct vg_paint *paint,
609544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                const VGint *coords)
610544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
611544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(paint->gradient.linear.coordsi, coords, sizeof(VGint) * 4);
612544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
613544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
614544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_linear_gradienti(struct vg_paint *paint,
615544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                            VGint *coords)
616544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
617544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(coords, paint->gradient.linear.coordsi, sizeof(VGint)*4);
618544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
619544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
620544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_set_radial_gradienti(struct vg_paint *paint,
621544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                const VGint *values)
622544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
623544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(paint->gradient.radial.valsi, values, sizeof(VGint) * 5);
624544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
625544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
626544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_radial_gradienti(struct vg_paint *paint,
627544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                            VGint *coords)
628544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
629544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   memcpy(coords, paint->gradient.radial.valsi, sizeof(VGint)*5);
630544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
631544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
632544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack RusinVGTilingMode paint_pattern_tiling(struct vg_paint *paint)
633544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
634544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return paint->pattern.tiling_mode;
635544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
636544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
637544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack RusinVGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers,
638e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger                          struct pipe_sampler_view **sampler_views)
639544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
640544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   struct vg_context *ctx = vg_current_context();
641544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
642544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   switch(paint->type) {
643544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_PAINT_TYPE_LINEAR_GRADIENT:
644544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_PAINT_TYPE_RADIAL_GRADIENT: {
645e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger      if (paint->gradient.sampler_view) {
646544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         paint->gradient.sampler.min_img_filter = image_sampler_filter(ctx);
647544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         paint->gradient.sampler.mag_img_filter = image_sampler_filter(ctx);
648544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         samplers[0] = &paint->gradient.sampler;
649e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger         sampler_views[0] = paint->gradient.sampler_view;
650544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin         return 1;
651544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      }
652544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
653544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
654544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_PAINT_TYPE_PATTERN: {
6559f61e43b4903c6cf0ac03a479ec9ed7b15fd6ccfDave Airlie      memcpy(paint->pattern.sampler.border_color.f,
656544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin             ctx->state.vg.tile_fill_color,
657544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin             sizeof(VGfloat) * 4);
658544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->pattern.sampler.min_img_filter = image_sampler_filter(ctx);
659544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->pattern.sampler.mag_img_filter = image_sampler_filter(ctx);
660544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      samplers[0] = &paint->pattern.sampler;
661e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger      sampler_views[0] = paint->pattern.sampler_view;
662544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      return 1;
663544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
664544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
665544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   default:
666544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
667544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
668544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return 0;
669544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
670544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
671544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_resolve_type(struct vg_paint *paint)
672544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
673544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   if (paint->type == VG_PAINT_TYPE_PATTERN &&
674e5f0384ad06359aa1b9dc1b4bc6f475f7a119af2Roland Scheidegger       !paint->pattern.sampler_view) {
675544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint->type = VG_PAINT_TYPE_COLOR;
676544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
677544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
678544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
679d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I WuVGboolean paint_is_degenerate(struct vg_paint *paint)
680d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu{
681d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   VGboolean degen;
682d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   VGfloat *vals;
683d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu
684d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu
685d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   switch (paint->type) {
686d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   case VG_PAINT_TYPE_LINEAR_GRADIENT:
687d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      vals = paint->gradient.linear.coords;
688d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      /* two points are coincident */
689d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      degen = (floatsEqual(vals[0], vals[2]) &&
690d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu               floatsEqual(vals[1], vals[3]));
691d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      break;
692d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   case VG_PAINT_TYPE_RADIAL_GRADIENT:
693d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      vals = paint->gradient.radial.vals;
694d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      /* radius <= 0 */
695d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      degen = (vals[4] <= 0.0f);
696d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      break;
697d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   case VG_PAINT_TYPE_COLOR:
698d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   case VG_PAINT_TYPE_PATTERN:
699d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   default:
700d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      degen = VG_FALSE;
701d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu      break;
702d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   }
703d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu
704d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu   return degen;
705d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu}
706d7aa03b4feb7c30408b2ed3070e0fe33e2fd05baChia-I Wu
707544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack RusinVGint paint_constant_buffer_size(struct vg_paint *paint)
708544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
709544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   switch(paint->type) {
710544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_PAINT_TYPE_COLOR:
711544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      return 8 * sizeof(VGfloat);/*4 color + 4 constants (0.f,1.f,2.f,4.f)*/
712544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
713544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_PAINT_TYPE_LINEAR_GRADIENT:
714544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      return 20 * sizeof(VGfloat);
715544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
716544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_PAINT_TYPE_RADIAL_GRADIENT:
717544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      return 20 * sizeof(VGfloat);
718544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
719544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_PAINT_TYPE_PATTERN:
720544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      return 20 * sizeof(VGfloat);
721544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
722544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   default:
723544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      debug_printf("Uknown paint type: %d\n", paint->type);
724544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
725544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
726544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   return 0;
727544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
728544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
729544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusinvoid paint_fill_constant_buffer(struct vg_paint *paint,
730b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu                                const struct matrix *mat,
731544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin                                void *buffer)
732544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin{
733544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   switch(paint->type) {
734544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_PAINT_TYPE_COLOR:
735544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      paint_color_buffer(paint, buffer);
736544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
737544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_PAINT_TYPE_LINEAR_GRADIENT:
738b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu      paint_linear_gradient_buffer(paint, mat, buffer);
739544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
740544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_PAINT_TYPE_RADIAL_GRADIENT:
741b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu      paint_radial_gradient_buffer(paint, mat, buffer);
742544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
743544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   case VG_PAINT_TYPE_PATTERN:
744b06de80843e7d096bed4ae03ddc5e2842f1876afChia-I Wu      paint_pattern_buffer(paint, mat, buffer);
745544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      break;
746544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin
747544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   default:
748544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin      abort();
749544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin   }
750544dd4b11f7be76bb00fe29a60eaf2772dcc69caZack Rusin}
7513f0a966807f03a364edea0272ddf45f08ab7ce4fChia-I Wu
7523f0a966807f03a364edea0272ddf45f08ab7ce4fChia-I WuVGboolean paint_is_opaque(struct vg_paint *paint)
7533f0a966807f03a364edea0272ddf45f08ab7ce4fChia-I Wu{
7543f0a966807f03a364edea0272ddf45f08ab7ce4fChia-I Wu   /* TODO add other paint types and make sure PAINT_DIRTY gets set */
7553f0a966807f03a364edea0272ddf45f08ab7ce4fChia-I Wu   return (paint->type == VG_PAINT_TYPE_COLOR &&
7563f0a966807f03a364edea0272ddf45f08ab7ce4fChia-I Wu           floatsEqual(paint->solid.color[3], 1.0f));
7573f0a966807f03a364edea0272ddf45f08ab7ce4fChia-I Wu}
758