Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / swrast / s_clear.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  7.1
4  *
5  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 #include "main/glheader.h"
26 #include "main/colormac.h"
27 #include "main/condrender.h"
28 #include "main/macros.h"
29 #include "main/imports.h"
30 #include "main/mtypes.h"
31
32 #include "s_accum.h"
33 #include "s_context.h"
34 #include "s_depth.h"
35 #include "s_masking.h"
36 #include "s_stencil.h"
37
38
39 /**
40  * Clear the color buffer when glColorMask is in effect.
41  */
42 static void
43 clear_rgba_buffer_with_masking(struct gl_context *ctx, struct gl_renderbuffer *rb,
44                                GLuint buf)
45 {
46    const GLint x = ctx->DrawBuffer->_Xmin;
47    const GLint y = ctx->DrawBuffer->_Ymin;
48    const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
49    const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
50    SWspan span;
51    GLint i;
52
53    ASSERT(rb->PutRow);
54
55    /* Initialize color span with clear color */
56    /* XXX optimize for clearcolor == black/zero (bzero) */
57    INIT_SPAN(span, GL_BITMAP);
58    span.end = width;
59    span.arrayMask = SPAN_RGBA;
60    span.array->ChanType = rb->DataType;
61    if (span.array->ChanType == GL_UNSIGNED_BYTE) {
62       GLubyte clearColor[4];
63       UNCLAMPED_FLOAT_TO_UBYTE(clearColor[RCOMP], ctx->Color.ClearColor[0]);
64       UNCLAMPED_FLOAT_TO_UBYTE(clearColor[GCOMP], ctx->Color.ClearColor[1]);
65       UNCLAMPED_FLOAT_TO_UBYTE(clearColor[BCOMP], ctx->Color.ClearColor[2]);
66       UNCLAMPED_FLOAT_TO_UBYTE(clearColor[ACOMP], ctx->Color.ClearColor[3]);
67       for (i = 0; i < width; i++) {
68          COPY_4UBV(span.array->rgba[i], clearColor);
69       }
70    }
71    else if (span.array->ChanType == GL_UNSIGNED_SHORT) {
72       GLushort clearColor[4];
73       UNCLAMPED_FLOAT_TO_USHORT(clearColor[RCOMP], ctx->Color.ClearColor[0]);
74       UNCLAMPED_FLOAT_TO_USHORT(clearColor[GCOMP], ctx->Color.ClearColor[1]);
75       UNCLAMPED_FLOAT_TO_USHORT(clearColor[BCOMP], ctx->Color.ClearColor[2]);
76       UNCLAMPED_FLOAT_TO_USHORT(clearColor[ACOMP], ctx->Color.ClearColor[3]);
77       for (i = 0; i < width; i++) {
78          COPY_4V_CAST(span.array->rgba[i], clearColor, GLchan);
79       }
80    }
81    else {
82       ASSERT(span.array->ChanType == GL_FLOAT);
83       for (i = 0; i < width; i++) {
84          CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][0], ctx->Color.ClearColor[0]);
85          CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][1], ctx->Color.ClearColor[1]);
86          CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][2], ctx->Color.ClearColor[2]);
87          CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][3], ctx->Color.ClearColor[3]);
88       }
89    }
90
91    /* Note that masking will change the color values, but only the
92     * channels for which the write mask is GL_FALSE.  The channels
93     * which which are write-enabled won't get modified.
94     */
95    for (i = 0; i < height; i++) {
96       span.x = x;
97       span.y = y + i;
98       _swrast_mask_rgba_span(ctx, rb, &span, buf);
99       /* write masked row */
100       rb->PutRow(ctx, rb, width, x, y + i, span.array->rgba, NULL);
101    }
102 }
103
104
105 /**
106  * Clear an rgba color buffer without channel masking.
107  */
108 static void
109 clear_rgba_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint buf)
110 {
111    const GLint x = ctx->DrawBuffer->_Xmin;
112    const GLint y = ctx->DrawBuffer->_Ymin;
113    const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
114    const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
115    GLubyte clear8[4];
116    GLushort clear16[4];
117    GLvoid *clearVal;
118    GLint i;
119
120    ASSERT(ctx->Color.ColorMask[buf][0] &&
121           ctx->Color.ColorMask[buf][1] &&
122           ctx->Color.ColorMask[buf][2] &&
123           ctx->Color.ColorMask[buf][3]);             
124
125    ASSERT(rb->PutMonoRow);
126
127    switch (rb->DataType) {
128       case GL_UNSIGNED_BYTE:
129          UNCLAMPED_FLOAT_TO_UBYTE(clear8[0], ctx->Color.ClearColor[0]);
130          UNCLAMPED_FLOAT_TO_UBYTE(clear8[1], ctx->Color.ClearColor[1]);
131          UNCLAMPED_FLOAT_TO_UBYTE(clear8[2], ctx->Color.ClearColor[2]);
132          UNCLAMPED_FLOAT_TO_UBYTE(clear8[3], ctx->Color.ClearColor[3]);
133          clearVal = clear8;
134          break;
135       case GL_UNSIGNED_SHORT:
136          UNCLAMPED_FLOAT_TO_USHORT(clear16[0], ctx->Color.ClearColor[0]);
137          UNCLAMPED_FLOAT_TO_USHORT(clear16[1], ctx->Color.ClearColor[1]);
138          UNCLAMPED_FLOAT_TO_USHORT(clear16[2], ctx->Color.ClearColor[2]);
139          UNCLAMPED_FLOAT_TO_USHORT(clear16[3], ctx->Color.ClearColor[3]);
140          clearVal = clear16;
141          break;
142       case GL_FLOAT:
143          clearVal = ctx->Color.ClearColor;
144          break;
145       default:
146          _mesa_problem(ctx, "Bad rb DataType in clear_color_buffer");
147          return;
148    }
149
150    for (i = 0; i < height; i++) {
151       rb->PutMonoRow(ctx, rb, width, x, y + i, clearVal, NULL);
152    }
153 }
154
155
156 /**
157  * Clear the front/back/left/right/aux color buffers.
158  * This function is usually only called if the device driver can't
159  * clear its own color buffers for some reason (such as with masking).
160  */
161 static void
162 clear_color_buffers(struct gl_context *ctx)
163 {
164    GLuint buf;
165
166    for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
167       struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[buf];
168
169       /* If this is an ES2 context or GL_ARB_ES2_compatibility is supported,
170        * the framebuffer can be complete with some attachments be missing.  In
171        * this case the _ColorDrawBuffers pointer will be NULL.
172        */
173       if (rb == NULL)
174          continue;
175
176       if (ctx->Color.ColorMask[buf][0] == 0 ||
177           ctx->Color.ColorMask[buf][1] == 0 ||
178           ctx->Color.ColorMask[buf][2] == 0 ||
179           ctx->Color.ColorMask[buf][3] == 0) {
180          clear_rgba_buffer_with_masking(ctx, rb, buf);
181       }
182       else {
183          clear_rgba_buffer(ctx, rb, buf);
184       }
185    }
186 }
187
188
189 /**
190  * Called via the device driver's ctx->Driver.Clear() function if the
191  * device driver can't clear one or more of the buffers itself.
192  * \param buffers  bitfield of BUFFER_BIT_* values indicating which
193  *                 renderbuffers are to be cleared.
194  * \param all  if GL_TRUE, clear whole buffer, else clear specified region.
195  */
196 void
197 _swrast_Clear(struct gl_context *ctx, GLbitfield buffers)
198 {
199 #ifdef DEBUG_FOO
200    {
201       const GLbitfield legalBits =
202          BUFFER_BIT_FRONT_LEFT |
203          BUFFER_BIT_FRONT_RIGHT |
204          BUFFER_BIT_BACK_LEFT |
205          BUFFER_BIT_BACK_RIGHT |
206          BUFFER_BIT_DEPTH |
207          BUFFER_BIT_STENCIL |
208          BUFFER_BIT_ACCUM |
209          BUFFER_BIT_AUX0;
210       assert((buffers & (~legalBits)) == 0);
211    }
212 #endif
213
214    if (!_mesa_check_conditional_render(ctx))
215       return; /* don't clear */
216
217    swrast_render_start(ctx);
218
219    /* do software clearing here */
220    if (buffers) {
221       if ((buffers & BUFFER_BITS_COLOR)
222           && (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) {
223          clear_color_buffers(ctx);
224       }
225       if (buffers & BUFFER_BIT_DEPTH) {
226          _swrast_clear_depth_buffer(ctx, ctx->DrawBuffer->_DepthBuffer);
227       }
228       if (buffers & BUFFER_BIT_ACCUM) {
229          _swrast_clear_accum_buffer(ctx,
230                        ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
231       }
232       if (buffers & BUFFER_BIT_STENCIL) {
233          _swrast_clear_stencil_buffer(ctx, ctx->DrawBuffer->_StencilBuffer);
234       }
235    }
236
237    swrast_render_finish(ctx);
238 }