clear.c revision c1f859d4
1c1f859d4Smrg/* 2c1f859d4Smrg * Mesa 3-D graphics library 3c1f859d4Smrg * Version: 7.1 4c1f859d4Smrg * 5c1f859d4Smrg * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 6c1f859d4Smrg * 7c1f859d4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8c1f859d4Smrg * copy of this software and associated documentation files (the "Software"), 9c1f859d4Smrg * to deal in the Software without restriction, including without limitation 10c1f859d4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11c1f859d4Smrg * and/or sell copies of the Software, and to permit persons to whom the 12c1f859d4Smrg * Software is furnished to do so, subject to the following conditions: 13c1f859d4Smrg * 14c1f859d4Smrg * The above copyright notice and this permission notice shall be included 15c1f859d4Smrg * in all copies or substantial portions of the Software. 16c1f859d4Smrg * 17c1f859d4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18c1f859d4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19c1f859d4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20c1f859d4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21c1f859d4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22c1f859d4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23c1f859d4Smrg */ 24c1f859d4Smrg 25c1f859d4Smrg 26c1f859d4Smrg/** 27c1f859d4Smrg * \file clear.c 28c1f859d4Smrg * glClearColor, glClearIndex, glClear() functions. 29c1f859d4Smrg */ 30c1f859d4Smrg 31c1f859d4Smrg 32c1f859d4Smrg 33c1f859d4Smrg#include "glheader.h" 34c1f859d4Smrg#include "clear.h" 35c1f859d4Smrg#include "context.h" 36c1f859d4Smrg#include "colormac.h" 37c1f859d4Smrg#include "state.h" 38c1f859d4Smrg 39c1f859d4Smrg 40c1f859d4Smrg 41c1f859d4Smrg#if _HAVE_FULL_GL 42c1f859d4Smrgvoid GLAPIENTRY 43c1f859d4Smrg_mesa_ClearIndex( GLfloat c ) 44c1f859d4Smrg{ 45c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 46c1f859d4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 47c1f859d4Smrg 48c1f859d4Smrg if (ctx->Color.ClearIndex == (GLuint) c) 49c1f859d4Smrg return; 50c1f859d4Smrg 51c1f859d4Smrg FLUSH_VERTICES(ctx, _NEW_COLOR); 52c1f859d4Smrg ctx->Color.ClearIndex = (GLuint) c; 53c1f859d4Smrg 54c1f859d4Smrg if (!ctx->Visual.rgbMode && ctx->Driver.ClearIndex) { 55c1f859d4Smrg /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */ 56c1f859d4Smrg (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex ); 57c1f859d4Smrg } 58c1f859d4Smrg} 59c1f859d4Smrg#endif 60c1f859d4Smrg 61c1f859d4Smrg 62c1f859d4Smrg/** 63c1f859d4Smrg * Specify the clear values for the color buffers. 64c1f859d4Smrg * 65c1f859d4Smrg * \param red red color component. 66c1f859d4Smrg * \param green green color component. 67c1f859d4Smrg * \param blue blue color component. 68c1f859d4Smrg * \param alpha alpha component. 69c1f859d4Smrg * 70c1f859d4Smrg * \sa glClearColor(). 71c1f859d4Smrg * 72c1f859d4Smrg * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor. On a 73c1f859d4Smrg * change, flushes the vertices and notifies the driver via the 74c1f859d4Smrg * dd_function_table::ClearColor callback. 75c1f859d4Smrg */ 76c1f859d4Smrgvoid GLAPIENTRY 77c1f859d4Smrg_mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) 78c1f859d4Smrg{ 79c1f859d4Smrg GLfloat tmp[4]; 80c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 81c1f859d4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 82c1f859d4Smrg 83c1f859d4Smrg tmp[0] = CLAMP(red, 0.0F, 1.0F); 84c1f859d4Smrg tmp[1] = CLAMP(green, 0.0F, 1.0F); 85c1f859d4Smrg tmp[2] = CLAMP(blue, 0.0F, 1.0F); 86c1f859d4Smrg tmp[3] = CLAMP(alpha, 0.0F, 1.0F); 87c1f859d4Smrg 88c1f859d4Smrg if (TEST_EQ_4V(tmp, ctx->Color.ClearColor)) 89c1f859d4Smrg return; /* no change */ 90c1f859d4Smrg 91c1f859d4Smrg FLUSH_VERTICES(ctx, _NEW_COLOR); 92c1f859d4Smrg COPY_4V(ctx->Color.ClearColor, tmp); 93c1f859d4Smrg 94c1f859d4Smrg if (ctx->Visual.rgbMode && ctx->Driver.ClearColor) { 95c1f859d4Smrg /* it's OK to call glClearColor in CI mode but it should be a NOP */ 96c1f859d4Smrg (*ctx->Driver.ClearColor)(ctx, ctx->Color.ClearColor); 97c1f859d4Smrg } 98c1f859d4Smrg} 99c1f859d4Smrg 100c1f859d4Smrg 101c1f859d4Smrg/** 102c1f859d4Smrg * Clear buffers. 103c1f859d4Smrg * 104c1f859d4Smrg * \param mask bit-mask indicating the buffers to be cleared. 105c1f859d4Smrg * 106c1f859d4Smrg * Flushes the vertices and verifies the parameter. If __GLcontextRec::NewState 107c1f859d4Smrg * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin, 108c1f859d4Smrg * etc. If the rasterization mode is set to GL_RENDER then requests the driver 109c1f859d4Smrg * to clear the buffers, via the dd_function_table::Clear callback. 110c1f859d4Smrg */ 111c1f859d4Smrgvoid GLAPIENTRY 112c1f859d4Smrg_mesa_Clear( GLbitfield mask ) 113c1f859d4Smrg{ 114c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 115c1f859d4Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 116c1f859d4Smrg 117c1f859d4Smrg FLUSH_CURRENT(ctx, 0); 118c1f859d4Smrg 119c1f859d4Smrg if (MESA_VERBOSE & VERBOSE_API) 120c1f859d4Smrg _mesa_debug(ctx, "glClear 0x%x\n", mask); 121c1f859d4Smrg 122c1f859d4Smrg if (mask & ~(GL_COLOR_BUFFER_BIT | 123c1f859d4Smrg GL_DEPTH_BUFFER_BIT | 124c1f859d4Smrg GL_STENCIL_BUFFER_BIT | 125c1f859d4Smrg GL_ACCUM_BUFFER_BIT)) { 126c1f859d4Smrg /* invalid bit set */ 127c1f859d4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask); 128c1f859d4Smrg return; 129c1f859d4Smrg } 130c1f859d4Smrg 131c1f859d4Smrg if (ctx->NewState) { 132c1f859d4Smrg _mesa_update_state( ctx ); /* update _Xmin, etc */ 133c1f859d4Smrg } 134c1f859d4Smrg 135c1f859d4Smrg if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 136c1f859d4Smrg _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 137c1f859d4Smrg "glClear(incomplete framebuffer)"); 138c1f859d4Smrg return; 139c1f859d4Smrg } 140c1f859d4Smrg 141c1f859d4Smrg if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 || 142c1f859d4Smrg ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax || 143c1f859d4Smrg ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax) 144c1f859d4Smrg return; 145c1f859d4Smrg 146c1f859d4Smrg if (ctx->RenderMode == GL_RENDER) { 147c1f859d4Smrg GLbitfield bufferMask; 148c1f859d4Smrg 149c1f859d4Smrg /* don't clear depth buffer if depth writing disabled */ 150c1f859d4Smrg if (!ctx->Depth.Mask) 151c1f859d4Smrg mask &= ~GL_DEPTH_BUFFER_BIT; 152c1f859d4Smrg 153c1f859d4Smrg /* Build the bitmask to send to device driver's Clear function. 154c1f859d4Smrg * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4 155c1f859d4Smrg * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the 156c1f859d4Smrg * BUFFER_BIT_COLORn flags. 157c1f859d4Smrg */ 158c1f859d4Smrg bufferMask = 0; 159c1f859d4Smrg if (mask & GL_COLOR_BUFFER_BIT) { 160c1f859d4Smrg GLuint i; 161c1f859d4Smrg for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { 162c1f859d4Smrg bufferMask |= (1 << ctx->DrawBuffer->_ColorDrawBufferIndexes[i]); 163c1f859d4Smrg } 164c1f859d4Smrg } 165c1f859d4Smrg 166c1f859d4Smrg if ((mask & GL_DEPTH_BUFFER_BIT) 167c1f859d4Smrg && ctx->DrawBuffer->Visual.haveDepthBuffer) { 168c1f859d4Smrg bufferMask |= BUFFER_BIT_DEPTH; 169c1f859d4Smrg } 170c1f859d4Smrg 171c1f859d4Smrg if ((mask & GL_STENCIL_BUFFER_BIT) 172c1f859d4Smrg && ctx->DrawBuffer->Visual.haveStencilBuffer) { 173c1f859d4Smrg bufferMask |= BUFFER_BIT_STENCIL; 174c1f859d4Smrg } 175c1f859d4Smrg 176c1f859d4Smrg if ((mask & GL_ACCUM_BUFFER_BIT) 177c1f859d4Smrg && ctx->DrawBuffer->Visual.haveAccumBuffer) { 178c1f859d4Smrg bufferMask |= BUFFER_BIT_ACCUM; 179c1f859d4Smrg } 180c1f859d4Smrg 181c1f859d4Smrg ASSERT(ctx->Driver.Clear); 182c1f859d4Smrg ctx->Driver.Clear(ctx, bufferMask); 183c1f859d4Smrg } 184c1f859d4Smrg} 185