<commit_before>/**
 * @license
 * Copyright 2018 Google Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * =============================================================================
 */

#include "webgl_extensions.h"

#include "angle/include/GLES2/gl2.h"
#include "angle/include/GLES2/gl2ext.h"

#include "utils.h"

namespace nodejsgl {

// Throws error if extension is not supported:
#ifndef ENSURE_EXTENSION_IS_SUPPORTED
#define ENSURE_EXTENSION_IS_SUPPORTED               \
  if (!IsSupported(egl_context_wrapper)) {          \
    NAPI_THROW_ERROR(env, "Unsupported extension"); \
    return napi_invalid_arg;                        \
  }
#endif

// Returns true if extension is requestable or enabled:
#ifndef IS_EXTENSION_NAME_AVAILABLE
#define IS_EXTENSION_NAME_AVAILABLE(ext_name)                             \
  return egl_context_wrapper->angle_requestable_extensions->HasExtension( \
             ext_name) ||                                                 \
         egl_context_wrapper->gl_extensions->HasExtension(ext_name);
#endif

//==============================================================================
// GLExtensionBase

/* static */
napi_value GLExtensionBase::InitStubClass(napi_env env,
                                          napi_callback_info info) {
  ENSURE_CONSTRUCTOR_CALL_RETVAL(env, info, nullptr);

  napi_status nstatus;
  napi_value js_this;
  nstatus = napi_get_cb_info(env, info, 0, nullptr, &js_this, nullptr);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr);

  return js_this;
}

/* static */
napi_status GLExtensionBase::NewInstanceBase(napi_env env,
                                             napi_ref constructor_ref,
                                             napi_value* instance) {
  napi_status nstatus;

  napi_value ctor_value;
  nstatus = napi_get_reference_value(env, constructor_ref, &ctor_value);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus);

  nstatus = napi_new_instance(env, ctor_value, 0, nullptr, instance);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus);

  return napi_ok;
}

//==============================================================================
// ANGLEInstancedArraysExtension

napi_ref ANGLEInstancedArraysExtension::constructor_ref_;

ANGLEInstancedArraysExtension::ANGLEInstancedArraysExtension(napi_env env)
    : GLExtensionBase(env) {}

/* static */
bool ANGLEInstancedArraysExtension::IsSupported(
    EGLContextWrapper* egl_context_wrapper) {
  IS_EXTENSION_NAME_AVAILABLE("GL_ANGLE_instanced_arrays");
}

/* static */
napi_status ANGLEInstancedArraysExtension::Register(napi_env env,
                                                    napi_value exports) {
  napi_status nstatus;

  napi_value ctor_value;
  nstatus = napi_define_class(env, "GL_ANGLE_instanced_arrays",
                              NAPI_AUTO_LENGTH, GLExtensionBase::InitStubClass,
                              nullptr, 0, nullptr, &ctor_value);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus);

  nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus);

  return napi_ok;
}

/* static */
napi_status ANGLEInstancedArraysExtension::NewInstance(
    napi_env env, napi_value* instance,
    EGLContextWrapper* egl_context_wrapper) {
  ENSURE_EXTENSION_IS_SUPPORTED

  napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus);

  egl_context_wrapper->glRequestExtensionANGLE("GL_ANGLE_instanced_arrays");
  egl_context_wrapper->RefreshGLExtensions();

  return napi_ok;
}

//==============================================================================
// EXTBlendMinmaxExtension

napi_ref EXTBlendMinmaxExtension::constructor_ref_;

EXTBlendMinmaxExtension::EXTBlendMinmaxExtension(napi_env env)
    : GLExtensionBase(env) {}

/* static */
bool EXTBlendMinmaxExtension::IsSupported(
    EGLContextWrapper* egl_context_wrapper) {
  IS_EXTENSION_NAME_AVAILABLE("GL_EXT_blend_minmax");
}

/* static */
napi_status EXTBlendMinmaxExtension::Register(napi_env env,
                                              napi_value exports) {
  napi_status nstatus;

  napi_property_descriptor properties[] = {
      NapiDefineIntProperty(env, GL_MAX_EXT, "MIN_EXT"),
      NapiDefineIntProperty(env, GL_MIN_EXT, "MAX_EXT")};

  napi_value ctor_value;
  nstatus = napi_define_class(env, "EXT_blend_minmax", NAPI_AUTO_LENGTH,
                              GLExtensionBase::InitStubClass, nullptr,<commit_msg>Swap min/max<commit_after>/**
 * @license
 * Copyright 2018 Google Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * =============================================================================
 */

#include "webgl_extensions.h"

#include "angle/include/GLES2/gl2.h"
#include "angle/include/GLES2/gl2ext.h"

#include "utils.h"

namespace nodejsgl {

// Throws error if extension is not supported:
#ifndef ENSURE_EXTENSION_IS_SUPPORTED
#define ENSURE_EXTENSION_IS_SUPPORTED               \
  if (!IsSupported(egl_context_wrapper)) {          \
    NAPI_THROW_ERROR(env, "Unsupported extension"); \
    return napi_invalid_arg;                        \
  }
#endif

// Returns true if extension is requestable or enabled:
#ifndef IS_EXTENSION_NAME_AVAILABLE
#define IS_EXTENSION_NAME_AVAILABLE(ext_name)                             \
  return egl_context_wrapper->angle_requestable_extensions->HasExtension( \
             ext_name) ||                                                 \
         egl_context_wrapper->gl_extensions->HasExtension(ext_name);
#endif

//==============================================================================
// GLExtensionBase

/* static */
napi_value GLExtensionBase::InitStubClass(napi_env env,
                                          napi_callback_info info) {
  ENSURE_CONSTRUCTOR_CALL_RETVAL(env, info, nullptr);

  napi_status nstatus;
  napi_value js_this;
  nstatus = napi_get_cb_info(env, info, 0, nullptr, &js_this, nullptr);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr);

  return js_this;
}

/* static */
napi_status GLExtensionBase::NewInstanceBase(napi_env env,
                                             napi_ref constructor_ref,
                                             napi_value* instance) {
  napi_status nstatus;

  napi_value ctor_value;
  nstatus = napi_get_reference_value(env, constructor_ref, &ctor_value);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus);

  nstatus = napi_new_instance(env, ctor_value, 0, nullptr, instance);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus);

  return napi_ok;
}

//==============================================================================
// ANGLEInstancedArraysExtension

napi_ref ANGLEInstancedArraysExtension::constructor_ref_;

ANGLEInstancedArraysExtension::ANGLEInstancedArraysExtension(napi_env env)
    : GLExtensionBase(env) {}

/* static */
bool ANGLEInstancedArraysExtension::IsSupported(
    EGLContextWrapper* egl_context_wrapper) {
  IS_EXTENSION_NAME_AVAILABLE("GL_ANGLE_instanced_arrays");
}

/* static */
napi_status ANGLEInstancedArraysExtension::Register(napi_env env,
                                                    napi_value exports) {
  napi_status nstatus;

  napi_value ctor_value;
  nstatus = napi_define_class(env, "GL_ANGLE_instanced_arrays",
                              NAPI_AUTO_LENGTH, GLExtensionBase::InitStubClass,
                              nullptr, 0, nullptr, &ctor_value);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus);

  nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus);

  return napi_ok;
}

/* static */
napi_status ANGLEInstancedArraysExtension::NewInstance(
    napi_env env, napi_value* instance,
    EGLContextWrapper* egl_context_wrapper) {
  ENSURE_EXTENSION_IS_SUPPORTED

  napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus);

  egl_context_wrapper->glRequestExtensionANGLE("GL_ANGLE_instanced_arrays");
  egl_context_wrapper->RefreshGLExtensions();

  return napi_ok;
}

//==============================================================================
// EXTBlendMinmaxExtension

napi_ref EXTBlendMinmaxExtension::constructor_ref_;

EXTBlendMinmaxExtension::EXTBlendMinmaxExtension(napi_env env)
    : GLExtensionBase(env) {}

/* static */
bool EXTBlendMinmaxExtension::IsSupported(
    EGLContextWrapper* egl_context_wrapper) {
  IS_EXTENSION_NAME_AVAILABLE("GL_EXT_blend_minmax");
}

/* static */
napi_status EXTBlendMinmaxExtension::Register(napi_env env,
                                              napi_value exports) {
  napi_status nstatus;

  napi_property_descriptor properties[] = {
      NapiDefineIntProperty(env, GL_MAX_EXT, "MAX_EXT"),
      NapiDefineIntProperty(env, GL_MIN_EXT, "MIN_EXT")};

  napi_value ctor_value;
  nstatus = napi_define_class(env, "EXT_blend_minmax", NAPI_AUTO_LENGTH,
                              GLExtensionBase::InitStubClass, nullptr,
{'fraction_non_alphanumeric': 0.14049257154252667, 'fraction_numerical': 0.0031907468341808754, 'mean_word_length': 3.7244465379180407, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5256987', 'n_tokens_mistral': 3073, 'n_tokens_neox': 2998, 'n_words': 582}