Subversion Repositories Kolibri OS

Rev

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

  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 */
  280.