Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1901 serge 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 "glheader.h"
26
#include "imports.h"
27
#include "bufferobj.h"
28
#include "context.h"
29
#include "drawpix.h"
30
#include "enums.h"
31
#include "feedback.h"
32
#include "framebuffer.h"
33
#include "readpix.h"
34
#include "state.h"
35
#include "dispatch.h"
36
 
37
 
38
#if FEATURE_drawpix
39
 
40
 
41
/*
42
 * Execute glDrawPixels
43
 */
44
static void GLAPIENTRY
45
_mesa_DrawPixels( GLsizei width, GLsizei height,
46
                  GLenum format, GLenum type, const GLvoid *pixels )
47
{
48
   GET_CURRENT_CONTEXT(ctx);
49
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
50
 
51
   if (width < 0 || height < 0) {
52
      _mesa_error( ctx, GL_INVALID_VALUE, "glDrawPixels(width or height < 0" );
53
      return;
54
   }
55
 
56
   /* We're not using the current vertex program, and the driver may install
57
    * its own.  Note: this may dirty some state.
58
    */
59
   _mesa_set_vp_override(ctx, GL_TRUE);
60
 
61
   /* Note: this call does state validation */
62
   if (!_mesa_valid_to_render(ctx, "glDrawPixels")) {
63
      goto end;      /* the error code was recorded */
64
   }
65
 
66
   if (_mesa_error_check_format_type(ctx, format, type, GL_TRUE)) {
67
      goto end;      /* the error code was recorded */
68
   }
69
 
70
   if (!ctx->Current.RasterPosValid) {
71
      goto end;  /* no-op, not an error */
72
   }
73
 
74
   if (ctx->RenderMode == GL_RENDER) {
75
      if (width > 0 && height > 0) {
76
         /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
77
         GLint x = IROUND(ctx->Current.RasterPos[0]);
78
         GLint y = IROUND(ctx->Current.RasterPos[1]);
79
 
80
         if (ctx->Unpack.BufferObj->Name) {
81
            /* unpack from PBO */
82
            if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
83
                                           format, type, pixels)) {
84
               _mesa_error(ctx, GL_INVALID_OPERATION,
85
                           "glDrawPixels(invalid PBO access)");
86
               goto end;
87
            }
88
            if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
89
               /* buffer is mapped - that's an error */
90
               _mesa_error(ctx, GL_INVALID_OPERATION,
91
                           "glDrawPixels(PBO is mapped)");
92
               goto end;
93
            }
94
         }
95
 
96
         ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type,
97
                                &ctx->Unpack, pixels);
98
      }
99
   }
100
   else if (ctx->RenderMode == GL_FEEDBACK) {
101
      /* Feedback the current raster pos info */
102
      FLUSH_CURRENT( ctx, 0 );
103
      _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
104
      _mesa_feedback_vertex( ctx,
105
                             ctx->Current.RasterPos,
106
                             ctx->Current.RasterColor,
107
                             ctx->Current.RasterTexCoords[0] );
108
   }
109
   else {
110
      ASSERT(ctx->RenderMode == GL_SELECT);
111
      /* Do nothing.  See OpenGL Spec, Appendix B, Corollary 6. */
112
   }
113
 
114
end:
115
   _mesa_set_vp_override(ctx, GL_FALSE);
116
}
117
 
118
 
119
static void GLAPIENTRY
120
_mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
121
                  GLenum type )
122
{
123
   GET_CURRENT_CONTEXT(ctx);
124
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
125
 
126
   if (width < 0 || height < 0) {
127
      _mesa_error(ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)");
128
      return;
129
   }
130
 
131
   /* Note: more detailed 'type' checking is done by the
132
    * _mesa_source/dest_buffer_exists() calls below.  That's where we
133
    * check if the stencil buffer exists, etc.
134
    */
135
   if (type != GL_COLOR &&
136
       type != GL_DEPTH &&
137
       type != GL_STENCIL &&
138
       type != GL_DEPTH_STENCIL) {
139
      _mesa_error(ctx, GL_INVALID_ENUM, "glCopyPixels(type=%s)",
140
                  _mesa_lookup_enum_by_nr(type));
141
      return;
142
   }
143
 
144
   /* We're not using the current vertex program, and the driver may install
145
    * it's own.  Note: this may dirty some state.
146
    */
147
   _mesa_set_vp_override(ctx, GL_TRUE);
148
 
149
   /* Note: this call does state validation */
150
   if (!_mesa_valid_to_render(ctx, "glCopyPixels")) {
151
      goto end;      /* the error code was recorded */
152
   }
153
 
154
   /* Check read buffer's status (draw buffer was already checked) */
155
   if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
156
      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
157
                  "glCopyPixels(incomplete framebuffer)" );
158
      goto end;
159
   }
160
 
161
   if (!_mesa_source_buffer_exists(ctx, type) ||
162
       !_mesa_dest_buffer_exists(ctx, type)) {
163
      _mesa_error(ctx, GL_INVALID_OPERATION,
164
                  "glCopyPixels(missing source or dest buffer)");
165
      goto end;
166
   }
167
 
168
   if (!ctx->Current.RasterPosValid || width ==0 || height == 0) {
169
      goto end; /* no-op, not an error */
170
   }
171
 
172
   if (ctx->RenderMode == GL_RENDER) {
173
      /* Round to satisfy conformance tests (matches SGI's OpenGL) */
174
      if (width > 0 && height > 0) {
175
         GLint destx = IROUND(ctx->Current.RasterPos[0]);
176
         GLint desty = IROUND(ctx->Current.RasterPos[1]);
177
         ctx->Driver.CopyPixels( ctx, srcx, srcy, width, height, destx, desty,
178
                                 type );
179
      }
180
   }
181
   else if (ctx->RenderMode == GL_FEEDBACK) {
182
      FLUSH_CURRENT( ctx, 0 );
183
      _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_COPY_PIXEL_TOKEN );
184
      _mesa_feedback_vertex( ctx,
185
                             ctx->Current.RasterPos,
186
                             ctx->Current.RasterColor,
187
                             ctx->Current.RasterTexCoords[0] );
188
   }
189
   else {
190
      ASSERT(ctx->RenderMode == GL_SELECT);
191
      /* Do nothing.  See OpenGL Spec, Appendix B, Corollary 6. */
192
   }
193
 
194
end:
195
   _mesa_set_vp_override(ctx, GL_FALSE);
196
}
197
 
198
 
199
static void GLAPIENTRY
200
_mesa_Bitmap( GLsizei width, GLsizei height,
201
              GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
202
              const GLubyte *bitmap )
203
{
204
   GET_CURRENT_CONTEXT(ctx);
205
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
206
 
207
   if (width < 0 || height < 0) {
208
      _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" );
209
      return;
210
   }
211
 
212
   if (!ctx->Current.RasterPosValid) {
213
      return;    /* do nothing */
214
   }
215
 
216
   /* Note: this call does state validation */
217
   if (!_mesa_valid_to_render(ctx, "glBitmap")) {
218
      /* the error code was recorded */
219
      return;
220
   }
221
 
222
   if (ctx->RenderMode == GL_RENDER) {
223
      /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
224
      if (width > 0 && height > 0) {
225
         const GLfloat epsilon = 0.0001F;
226
         GLint x = IFLOOR(ctx->Current.RasterPos[0] + epsilon - xorig);
227
         GLint y = IFLOOR(ctx->Current.RasterPos[1] + epsilon - yorig);
228
 
229
         if (ctx->Unpack.BufferObj->Name) {
230
            /* unpack from PBO */
231
            if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
232
                                           GL_COLOR_INDEX, GL_BITMAP,
233
                                           (GLvoid *) bitmap)) {
234
               _mesa_error(ctx, GL_INVALID_OPERATION,
235
                           "glBitmap(invalid PBO access)");
236
               return;
237
            }
238
            if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
239
               /* buffer is mapped - that's an error */
240
               _mesa_error(ctx, GL_INVALID_OPERATION,
241
                           "glBitmap(PBO is mapped)");
242
               return;
243
            }
244
         }
245
 
246
         ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
247
      }
248
   }
249
#if _HAVE_FULL_GL
250
   else if (ctx->RenderMode == GL_FEEDBACK) {
251
      FLUSH_CURRENT(ctx, 0);
252
      _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN );
253
      _mesa_feedback_vertex( ctx,
254
                             ctx->Current.RasterPos,
255
                             ctx->Current.RasterColor,
256
                             ctx->Current.RasterTexCoords[0] );
257
   }
258
   else {
259
      ASSERT(ctx->RenderMode == GL_SELECT);
260
      /* Do nothing.  See OpenGL Spec, Appendix B, Corollary 6. */
261
   }
262
#endif
263
 
264
   /* update raster position */
265
   ctx->Current.RasterPos[0] += xmove;
266
   ctx->Current.RasterPos[1] += ymove;
267
}
268
 
269
 
270
void
271
_mesa_init_drawpix_dispatch(struct _glapi_table *disp)
272
{
273
   SET_Bitmap(disp, _mesa_Bitmap);
274
   SET_CopyPixels(disp, _mesa_CopyPixels);
275
   SET_DrawPixels(disp, _mesa_DrawPixels);
276
}
277
 
278
 
279
#endif /* FEATURE_drawpix */