"Initial commit to Gerrit"
[profile/ivi/cogl.git] / cogl / cogl-clip-state.c
1 /*
2  * Cogl
3  *
4  * An object oriented GL/GLES Abstraction/Utility Layer
5  *
6  * Copyright (C) 2007,2008,2009,2010 Intel Corporation.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
20  *
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <string.h>
29 #include <math.h>
30
31 #include <glib.h>
32
33 #include "cogl-clip-stack.h"
34 #include "cogl-clip-state-private.h"
35 #include "cogl-context-private.h"
36 #include "cogl-internal.h"
37 #include "cogl-framebuffer-private.h"
38 #include "cogl-journal-private.h"
39 #include "cogl-util.h"
40 #include "cogl-matrix-private.h"
41 #include "cogl-clip-state.h"
42 #include "cogl1-context.h"
43
44 void
45 cogl_clip_push_window_rectangle (int x_offset,
46                                  int y_offset,
47                                  int width,
48                                  int height)
49 {
50   cogl_framebuffer_push_scissor_clip (cogl_get_draw_framebuffer (),
51                                       x_offset, y_offset, width, height);
52 }
53
54 /* XXX: This is deprecated API */
55 void
56 cogl_clip_push_window_rect (float x_offset,
57                             float y_offset,
58                             float width,
59                             float height)
60 {
61   cogl_clip_push_window_rectangle (x_offset, y_offset, width, height);
62 }
63
64 void
65 cogl_clip_push_rectangle (float x_1,
66                           float y_1,
67                           float x_2,
68                           float y_2)
69 {
70   cogl_framebuffer_push_rectangle_clip (cogl_get_draw_framebuffer (),
71                                         x_1, y_1, x_2, y_2);
72 }
73
74 /* XXX: Deprecated API */
75 void
76 cogl_clip_push (float x_offset,
77                 float y_offset,
78                 float width,
79                 float height)
80 {
81   cogl_clip_push_rectangle (x_offset,
82                             y_offset,
83                             x_offset + width,
84                             y_offset + height);
85 }
86
87 void
88 cogl_clip_push_from_path_preserve (void)
89 {
90   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
91   cogl_framebuffer_push_path_clip (cogl_get_draw_framebuffer (),
92                                    ctx->current_path);
93 }
94
95 #undef cogl_clip_push_from_path
96 void
97 cogl_clip_push_from_path (void)
98 {
99   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
100
101   cogl_clip_push_from_path_preserve ();
102
103   cogl_object_unref (ctx->current_path);
104   ctx->current_path = cogl2_path_new ();
105 }
106
107 void
108 cogl_clip_push_primitive (CoglPrimitive *primitive,
109                           float bounds_x1,
110                           float bounds_y1,
111                           float bounds_x2,
112                           float bounds_y2)
113 {
114   cogl_framebuffer_push_primitive_clip (cogl_get_draw_framebuffer (),
115                                         primitive,
116                                         bounds_x1,
117                                         bounds_y1,
118                                         bounds_x2,
119                                         bounds_y2);
120 }
121
122 void
123 cogl_clip_pop (void)
124 {
125   cogl_framebuffer_pop_clip (cogl_get_draw_framebuffer ());
126 }
127
128 void
129 cogl_clip_stack_save (void)
130 {
131   _cogl_framebuffer_save_clip_stack (cogl_get_draw_framebuffer ());
132 }
133
134 void
135 cogl_clip_stack_restore (void)
136 {
137   _cogl_framebuffer_restore_clip_stack (cogl_get_draw_framebuffer ());
138 }
139
140 /* XXX: This should never have been made public API! */
141 void
142 cogl_clip_ensure (void)
143 {
144   /* Do nothing.
145    *
146    * This API shouldn't be used by anyone and the documented semantics
147    * are basically vague enough that we can get away with doing
148    * nothing here.
149    */
150 }
151
152 void
153 _cogl_clip_state_init (CoglClipState *clip_state)
154 {
155   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
156
157   clip_state->stacks = NULL;
158
159   /* Add an intial stack */
160   _cogl_clip_state_save_clip_stack (clip_state);
161 }
162
163 void
164 _cogl_clip_state_destroy (CoglClipState *clip_state)
165 {
166   /* Destroy all of the stacks */
167   while (clip_state->stacks)
168     _cogl_clip_state_restore_clip_stack (clip_state);
169 }
170
171 CoglClipStack *
172 _cogl_clip_state_get_stack (CoglClipState *clip_state)
173 {
174   return clip_state->stacks->data;
175 }
176
177 void
178 _cogl_clip_state_set_stack (CoglClipState *clip_state,
179                             CoglClipStack *stack)
180 {
181   /* Replace the top of the stack of stacks */
182   _cogl_clip_stack_ref (stack);
183   _cogl_clip_stack_unref (clip_state->stacks->data);
184   clip_state->stacks->data = stack;
185 }
186
187 void
188 _cogl_clip_state_save_clip_stack (CoglClipState *clip_state)
189 {
190   clip_state->stacks = g_slist_prepend (clip_state->stacks, NULL);
191 }
192
193 void
194 _cogl_clip_state_restore_clip_stack (CoglClipState *clip_state)
195 {
196   CoglHandle stack;
197
198   _COGL_RETURN_IF_FAIL (clip_state->stacks != NULL);
199
200   stack = clip_state->stacks->data;
201
202   _cogl_clip_stack_unref (stack);
203
204   /* Revert to an old stack */
205   clip_state->stacks = g_slist_delete_link (clip_state->stacks,
206                                             clip_state->stacks);
207 }