blob: 1e2c45c020ae4ee8d8c0e2e0a583cf60735b6ce7 [file] [log] [blame] [edit]
// Copyright (c) 2015, the Dart GL extension authors. All rights reserved.
// Please see the AUTHORS file for details. Use of this source code is governed
// by a BSD-style license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
// This file contains utility functions for the GL Dart native extension.
#include <map>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <GLES2/gl2.h>
#include "dart_api.h"
#include "util.h"
Dart_Handle HandleError(Dart_Handle handle) {
if (Dart_IsError(handle)) {
Dart_PropagateError(Dart_NewUnhandledExceptionError(handle));
}
return handle;
}
Dart_Handle Dart_IntegerToUInt(Dart_Handle integer, unsigned int *value) {
int64_t actual;
HandleError(Dart_IntegerToInt64(integer, &actual));
if (actual < UINT_MAX) {
*value = static_cast<unsigned int>(actual);
return Dart_True();
} else {
char buf[50]; // Technically we only need 46 characters for this.
snprintf(buf, sizeof(buf), "%" PRId64 " does not fit into an unsigned int.",
actual);
return Dart_NewApiError(buf);
}
}
Dart_Handle Dart_NewStringFromGLubyteString(const GLubyte *string) {
return Dart_NewStringFromCString(reinterpret_cast<const char *>(string));
}
// The length of the resulting array of values for a call to glGetBooleanv,
// glGetFloatv, or glGetIntegerv with the given parameter. Note that some
// parameters return a variable-length list of values. The length of the list
// must be queried via another call to glGetIntegerv (these parameters are
// not in the map below, but are handled specially in `GetGlGetResultLength`).
const std::map<GLenum, GLint> kGlGetResultLengths = {
{GL_ACTIVE_TEXTURE, 1},
{GL_ALIASED_LINE_WIDTH_RANGE, 2},
{GL_ALIASED_POINT_SIZE_RANGE, 2},
{GL_ALPHA_BITS, 1},
{GL_ARRAY_BUFFER_BINDING, 1},
{GL_BLEND, 1},
{GL_BLEND_COLOR, 4},
{GL_BLEND_DST_ALPHA, 1},
{GL_BLEND_SRC_ALPHA, 1},
{GL_BLEND_EQUATION_ALPHA, 1},
{GL_BLEND_EQUATION_RGB, 1},
{GL_BLEND_SRC_RGB, 1},
{GL_BLEND_DST_RGB, 1},
{GL_BLUE_BITS, 1},
{GL_COLOR_CLEAR_VALUE, 4},
{GL_COLOR_WRITEMASK, 4},
{GL_CULL_FACE, 1},
{GL_CULL_FACE_MODE, 1},
{GL_CURRENT_PROGRAM, 1},
{GL_DEPTH_BITS, 1},
{GL_DEPTH_CLEAR_VALUE, 1},
{GL_DEPTH_FUNC, 1},
{GL_DEPTH_RANGE, 2},
{GL_DEPTH_TEST, 1},
{GL_DEPTH_WRITEMASK, 1},
{GL_DITHER, 1},
{GL_ELEMENT_ARRAY_BUFFER_BINDING, 1},
{GL_FRAMEBUFFER_BINDING, 1},
{GL_FRONT_FACE, 1},
{GL_GENERATE_MIPMAP_HINT, 1},
{GL_GREEN_BITS, 1},
{GL_IMPLEMENTATION_COLOR_READ_FORMAT, 1},
{GL_IMPLEMENTATION_COLOR_READ_TYPE, 1},
{GL_LINE_WIDTH, 1},
{GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 1},
{GL_MAX_CUBE_MAP_TEXTURE_SIZE, 1},
{GL_MAX_FRAGMENT_UNIFORM_VECTORS, 1},
{GL_MAX_RENDERBUFFER_SIZE, 1},
{GL_MAX_TEXTURE_IMAGE_UNITS, 1},
{GL_MAX_TEXTURE_SIZE, 1},
{GL_MAX_VARYING_VECTORS, 1},
{GL_MAX_VERTEX_ATTRIBS, 1},
{GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, 1},
{GL_MAX_VERTEX_UNIFORM_VECTORS, 1},
{GL_MAX_VIEWPORT_DIMS, 2},
{GL_NUM_COMPRESSED_TEXTURE_FORMATS, 1},
{GL_NUM_SHADER_BINARY_FORMATS, 1},
{GL_PACK_ALIGNMENT, 1},
{GL_POLYGON_OFFSET_FACTOR, 1},
{GL_POLYGON_OFFSET_FILL, 1},
{GL_POLYGON_OFFSET_UNITS, 1},
{GL_RED_BITS, 1},
{GL_RENDERBUFFER_BINDING, 1},
{GL_SAMPLE_ALPHA_TO_COVERAGE, 1},
{GL_SAMPLE_BUFFERS, 1},
{GL_SAMPLE_COVERAGE, 1},
{GL_SAMPLE_COVERAGE_INVERT, 1},
{GL_SAMPLE_COVERAGE_VALUE, 1},
{GL_SAMPLES, 1},
{GL_SCISSOR_BOX, 4},
{GL_SCISSOR_TEST, 1},
{GL_SHADER_COMPILER, 1},
{GL_STENCIL_CLEAR_VALUE, 1},
{GL_STENCIL_BACK_FAIL, 1},
{GL_STENCIL_BACK_FUNC, 1},
{GL_STENCIL_BACK_PASS_DEPTH_FAIL, 1},
{GL_STENCIL_BACK_PASS_DEPTH_PASS, 1},
{GL_STENCIL_BACK_REF, 1},
{GL_STENCIL_BACK_VALUE_MASK, 1},
{GL_STENCIL_BACK_WRITEMASK, 1},
{GL_STENCIL_BITS, 1},
{GL_STENCIL_FAIL, 1},
{GL_STENCIL_FUNC, 1},
{GL_STENCIL_PASS_DEPTH_FAIL, 1},
{GL_STENCIL_PASS_DEPTH_PASS, 1},
{GL_STENCIL_REF, 1},
{GL_STENCIL_TEST, 1},
{GL_STENCIL_VALUE_MASK, 1},
{GL_STENCIL_WRITEMASK, 1},
{GL_SUBPIXEL_BITS, 1},
{GL_TEXTURE_BINDING_2D, 1},
{GL_TEXTURE_BINDING_CUBE_MAP, 1},
{GL_UNPACK_ALIGNMENT, 1},
{GL_VIEWPORT, 4},
};
// Looks up the number of values returned for a call to glGet*v in the map.
GLint GetGlGetResultLength(GLenum param) {
// There are two parameters that return a variable number of arguments,
// so the length must be queried via another call to glGetIntegerv. In
// all other cases, we'll just look up the value in the map.
GLint length = -1;
switch (param) {
case GL_COMPRESSED_TEXTURE_FORMATS:
glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &length);
return length;
case GL_SHADER_BINARY_FORMATS:
glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &length);
return length;
default:
std::map<GLenum, GLint>::const_iterator itr =
kGlGetResultLengths.find(param);
if (itr != kGlGetResultLengths.end()) {
length = itr->second;
}
return length;
}
}