2019-03-25 21:23:55 +00:00
|
|
|
// Copyright 2019 The Chromium Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
const ASSEMBLE_INTERFACE_GL_ES = `/*
|
|
|
|
* Copyright 2019 Google LLC
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*
|
|
|
|
* THIS FILE IS AUTOGENERATED
|
|
|
|
* Make edits to tools/gpu/gl/interface/templates.go or they will
|
|
|
|
* be overwritten.
|
|
|
|
*/
|
|
|
|
|
2019-04-24 17:10:37 +00:00
|
|
|
#include "include/gpu/gl/GrGLAssembleHelpers.h"
|
|
|
|
#include "include/gpu/gl/GrGLAssembleInterface.h"
|
|
|
|
#include "src/gpu/gl/GrGLUtil.h"
|
2019-03-25 21:23:55 +00:00
|
|
|
|
|
|
|
#define GET_PROC(F) functions->f##F = (GrGL##F##Fn*)get(ctx, "gl" #F)
|
|
|
|
#define GET_PROC_SUFFIX(F, S) functions->f##F = (GrGL##F##Fn*)get(ctx, "gl" #F #S)
|
|
|
|
#define GET_PROC_LOCAL(F) GrGL##F##Fn* F = (GrGL##F##Fn*)get(ctx, "gl" #F)
|
|
|
|
|
|
|
|
#define GET_EGL_PROC_SUFFIX(F, S) functions->fEGL##F = (GrEGL##F##Fn*)get(ctx, "egl" #F #S)
|
|
|
|
|
|
|
|
#if SK_DISABLE_GL_ES_INTERFACE
|
|
|
|
sk_sp<const GrGLInterface> GrGLMakeAssembledGLESInterface(void *ctx, GrGLGetProc get) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
sk_sp<const GrGLInterface> GrGLMakeAssembledGLESInterface(void *ctx, GrGLGetProc get) {
|
|
|
|
GET_PROC_LOCAL(GetString);
|
|
|
|
if (nullptr == GetString) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* verStr = reinterpret_cast<const char*>(GetString(GR_GL_VERSION));
|
|
|
|
GrGLVersion glVer = GrGLGetVersionFromString(verStr);
|
|
|
|
|
|
|
|
if (glVer < GR_GL_VER(2,0)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
GET_PROC_LOCAL(GetIntegerv);
|
|
|
|
GET_PROC_LOCAL(GetStringi);
|
|
|
|
GrEGLQueryStringFn* queryString;
|
|
|
|
GrEGLDisplay display;
|
|
|
|
GrGetEGLQueryAndDisplay(&queryString, &display, ctx, get);
|
|
|
|
GrGLExtensions extensions;
|
|
|
|
if (!extensions.init(kGLES_GrGLStandard, GetString, GetStringi, GetIntegerv, queryString,
|
|
|
|
display)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
sk_sp<GrGLInterface> interface(new GrGLInterface);
|
|
|
|
GrGLInterface::Functions* functions = &interface->fFunctions;
|
|
|
|
|
|
|
|
// Autogenerated content follows
|
|
|
|
[[content]]
|
|
|
|
// End autogenerated content
|
|
|
|
// TODO(kjlubick): Do we want a feature that removes the extension if it doesn't have
|
|
|
|
// the function? This is common on some low-end GPUs.
|
|
|
|
|
|
|
|
if (extensions.has("GL_KHR_debug")) {
|
|
|
|
// In general we have a policy against removing extension strings when the driver does
|
|
|
|
// not provide function pointers for an advertised extension. However, because there is a
|
|
|
|
// known device that advertises GL_KHR_debug but fails to provide the functions and this is
|
|
|
|
// a debugging- only extension we've made an exception. This also can happen when using
|
|
|
|
// APITRACE.
|
|
|
|
if (!interface->fFunctions.fDebugMessageControl) {
|
|
|
|
extensions.remove("GL_KHR_debug");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
interface->fStandard = kGLES_GrGLStandard;
|
|
|
|
interface->fExtensions.swap(&extensions);
|
|
|
|
|
turn on -Wreturn-std-move-in-c++11
This CL has a complicated back story, but it's concrete change is
simple, just turning the warning on and converting a bunch of
return foo;
to
return std::move(foo);
These changes are exclusively in places where RVO and NRVO do not apply,
so it should not conflict with warnings like -Wpessimizing-move.
Since C++11, when you return a named local and its type doesn't match
the declared return type exactly, there's an implicit std::move()
wrapped around the value (what I'm making explicit here) so the move
constructor gets an opportunity to take precedence over the copy
constructor. You can read about this implicit move here under the
section "automatic move from local variables and parameters":
https://en.cppreference.com/w/cpp/language/return#Notes.
This situation comes up for us with smart pointers: a function declares
its return type as std::unique_ptr<Base> or sk_sp<Base>, and we return a
std::unique_ptr<Impl> or sk_sp<Impl>. Those types don't match exactly,
so RVO and NRVO don't come into play. They've always been going through
move constructors, and that's not changed here, just made explicit.
There was apparently once a bug in the C++11 standard and compilers
implementing that which made these copy instead of move, and then this
sort of code would do a little unnecessary ref/unref dance for sk_sp,
and would entirely fail to compile for uncopyable std::unique_ptr.
These explicit moves ostensibly will make our code more compatible with
those older compilers.
That compatibility alone is, I think, a terrible reason to land this CL.
Like, actively bad. But... to balance that out, I think the explicit
std::move()s here actually help remind us that RVO/NRVO are not in play,
and remind us we're going to call the move constructor. So that C++11
standard bug becomes kind of useful for us, in that Clang added this
warning to catch it, and its fix improves readability.
So really read this all as, "warn about implicit std::move() on return".
In the end I think it's just about readability. I don't really hold any
hope out that we'll become compatible with those older compilers.
Bug: skia:9909
Change-Id: Id596e9261188b6f10e759906af6c95fe303f6ffe
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271601
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
2020-02-18 19:33:23 +00:00
|
|
|
return std::move(interface);
|
2019-03-25 21:23:55 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
`
|
|
|
|
|
|
|
|
const ASSEMBLE_INTERFACE_GL = `/*
|
|
|
|
* Copyright 2019 Google LLC
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*
|
|
|
|
* THIS FILE IS AUTOGENERATED
|
|
|
|
* Make edits to tools/gpu/gl/interface/templates.go or they will
|
|
|
|
* be overwritten.
|
|
|
|
*/
|
|
|
|
|
2019-04-24 17:10:37 +00:00
|
|
|
#include "include/gpu/gl/GrGLAssembleHelpers.h"
|
|
|
|
#include "include/gpu/gl/GrGLAssembleInterface.h"
|
|
|
|
#include "src/gpu/gl/GrGLUtil.h"
|
2019-03-25 21:23:55 +00:00
|
|
|
|
|
|
|
#define GET_PROC(F) functions->f##F = (GrGL##F##Fn*)get(ctx, "gl" #F)
|
|
|
|
#define GET_PROC_SUFFIX(F, S) functions->f##F = (GrGL##F##Fn*)get(ctx, "gl" #F #S)
|
|
|
|
#define GET_PROC_LOCAL(F) GrGL##F##Fn* F = (GrGL##F##Fn*)get(ctx, "gl" #F)
|
|
|
|
|
|
|
|
#define GET_EGL_PROC_SUFFIX(F, S) functions->fEGL##F = (GrEGL##F##Fn*)get(ctx, "egl" #F #S)
|
|
|
|
|
|
|
|
#if SK_DISABLE_GL_INTERFACE
|
|
|
|
sk_sp<const GrGLInterface> GrGLMakeAssembledGLInterface(void *ctx, GrGLGetProc get) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
sk_sp<const GrGLInterface> GrGLMakeAssembledGLInterface(void *ctx, GrGLGetProc get) {
|
|
|
|
GET_PROC_LOCAL(GetString);
|
|
|
|
GET_PROC_LOCAL(GetStringi);
|
|
|
|
GET_PROC_LOCAL(GetIntegerv);
|
|
|
|
|
|
|
|
// GetStringi may be nullptr depending on the GL version.
|
|
|
|
if (nullptr == GetString || nullptr == GetIntegerv) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* versionString = (const char*) GetString(GR_GL_VERSION);
|
|
|
|
GrGLVersion glVer = GrGLGetVersionFromString(versionString);
|
|
|
|
|
|
|
|
if (glVer < GR_GL_VER(2,0) || GR_GL_INVALID_VER == glVer) {
|
|
|
|
// This is our minimum for non-ES GL.
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
GrEGLQueryStringFn* queryString;
|
|
|
|
GrEGLDisplay display;
|
|
|
|
GrGetEGLQueryAndDisplay(&queryString, &display, ctx, get);
|
|
|
|
GrGLExtensions extensions;
|
|
|
|
if (!extensions.init(kGL_GrGLStandard, GetString, GetStringi, GetIntegerv, queryString,
|
|
|
|
display)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
sk_sp<GrGLInterface> interface(new GrGLInterface());
|
|
|
|
GrGLInterface::Functions* functions = &interface->fFunctions;
|
|
|
|
|
|
|
|
// Autogenerated content follows
|
|
|
|
[[content]]
|
|
|
|
// End autogenerated content
|
|
|
|
interface->fStandard = kGL_GrGLStandard;
|
|
|
|
interface->fExtensions.swap(&extensions);
|
|
|
|
|
turn on -Wreturn-std-move-in-c++11
This CL has a complicated back story, but it's concrete change is
simple, just turning the warning on and converting a bunch of
return foo;
to
return std::move(foo);
These changes are exclusively in places where RVO and NRVO do not apply,
so it should not conflict with warnings like -Wpessimizing-move.
Since C++11, when you return a named local and its type doesn't match
the declared return type exactly, there's an implicit std::move()
wrapped around the value (what I'm making explicit here) so the move
constructor gets an opportunity to take precedence over the copy
constructor. You can read about this implicit move here under the
section "automatic move from local variables and parameters":
https://en.cppreference.com/w/cpp/language/return#Notes.
This situation comes up for us with smart pointers: a function declares
its return type as std::unique_ptr<Base> or sk_sp<Base>, and we return a
std::unique_ptr<Impl> or sk_sp<Impl>. Those types don't match exactly,
so RVO and NRVO don't come into play. They've always been going through
move constructors, and that's not changed here, just made explicit.
There was apparently once a bug in the C++11 standard and compilers
implementing that which made these copy instead of move, and then this
sort of code would do a little unnecessary ref/unref dance for sk_sp,
and would entirely fail to compile for uncopyable std::unique_ptr.
These explicit moves ostensibly will make our code more compatible with
those older compilers.
That compatibility alone is, I think, a terrible reason to land this CL.
Like, actively bad. But... to balance that out, I think the explicit
std::move()s here actually help remind us that RVO/NRVO are not in play,
and remind us we're going to call the move constructor. So that C++11
standard bug becomes kind of useful for us, in that Clang added this
warning to catch it, and its fix improves readability.
So really read this all as, "warn about implicit std::move() on return".
In the end I think it's just about readability. I don't really hold any
hope out that we'll become compatible with those older compilers.
Bug: skia:9909
Change-Id: Id596e9261188b6f10e759906af6c95fe303f6ffe
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271601
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
2020-02-18 19:33:23 +00:00
|
|
|
return std::move(interface);
|
2019-03-25 21:23:55 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
`
|
|
|
|
|
2019-03-28 16:46:40 +00:00
|
|
|
const ASSEMBLE_INTERFACE_WEBGL = `/*
|
|
|
|
* Copyright 2019 Google LLC
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*
|
|
|
|
* THIS FILE IS AUTOGENERATED
|
|
|
|
* Make edits to tools/gpu/gl/interface/templates.go or they will
|
|
|
|
* be overwritten.
|
|
|
|
*/
|
|
|
|
|
2019-04-24 17:10:37 +00:00
|
|
|
#include "include/gpu/gl/GrGLAssembleHelpers.h"
|
|
|
|
#include "include/gpu/gl/GrGLAssembleInterface.h"
|
|
|
|
#include "src/gpu/gl/GrGLUtil.h"
|
2019-03-28 16:46:40 +00:00
|
|
|
|
2020-08-20 14:33:39 +00:00
|
|
|
#if SK_DISABLE_WEBGL_INTERFACE || !defined(SK_USE_WEBGL)
|
2019-03-28 16:46:40 +00:00
|
|
|
sk_sp<const GrGLInterface> GrGLMakeAssembledWebGLInterface(void *ctx, GrGLGetProc get) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
#else
|
2020-08-20 14:33:39 +00:00
|
|
|
|
|
|
|
// Located https://github.com/emscripten-core/emscripten/tree/7ba7700902c46734987585409502f3c63beb650f/system/include/webgl
|
|
|
|
#include "webgl/webgl1.h"
|
|
|
|
#include "webgl/webgl1_ext.h"
|
|
|
|
#include "webgl/webgl2.h"
|
|
|
|
#include "webgl/webgl2_ext.h"
|
|
|
|
|
2020-09-29 19:07:11 +00:00
|
|
|
#define GET_PROC(F) functions->f##F = emscripten_gl##F
|
|
|
|
#define GET_PROC_SUFFIX(F, S) functions->f##F = emscripten_gl##F##S
|
|
|
|
|
|
|
|
// Adapter from standard GL signature to emscripten.
|
|
|
|
void emscripten_glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
|
|
|
|
uint32_t timeoutLo = timeout;
|
|
|
|
uint32_t timeoutHi = timeout >> 32;
|
|
|
|
emscripten_glWaitSync(sync, flags, timeoutLo, timeoutHi);
|
|
|
|
}
|
2020-08-20 14:33:39 +00:00
|
|
|
|
2020-09-29 19:07:11 +00:00
|
|
|
// Adapter from standard GL signature to emscripten.
|
|
|
|
GLenum emscripten_glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
|
|
|
|
uint32_t timeoutLo = timeout;
|
|
|
|
uint32_t timeoutHi = timeout >> 32;
|
|
|
|
return emscripten_glClientWaitSync(sync, flags, timeoutLo, timeoutHi);
|
|
|
|
}
|
2019-03-28 16:46:40 +00:00
|
|
|
|
2020-09-29 19:07:11 +00:00
|
|
|
sk_sp<const GrGLInterface> GrGLMakeAssembledWebGLInterface(void *ctx, GrGLGetProc get) {
|
|
|
|
const char* verStr = reinterpret_cast<const char*>(emscripten_glGetString(GR_GL_VERSION));
|
2019-03-28 16:46:40 +00:00
|
|
|
GrGLVersion glVer = GrGLGetVersionFromString(verStr);
|
|
|
|
if (glVer < GR_GL_VER(1,0)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
GrGLExtensions extensions;
|
2020-09-29 19:07:11 +00:00
|
|
|
if (!extensions.init(kWebGL_GrGLStandard, emscripten_glGetString, emscripten_glGetStringi,
|
|
|
|
emscripten_glGetIntegerv)) {
|
2019-03-28 16:46:40 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
sk_sp<GrGLInterface> interface(new GrGLInterface);
|
|
|
|
GrGLInterface::Functions* functions = &interface->fFunctions;
|
|
|
|
|
|
|
|
// Autogenerated content follows
|
|
|
|
[[content]]
|
|
|
|
// End autogenerated content
|
|
|
|
|
|
|
|
interface->fStandard = kWebGL_GrGLStandard;
|
|
|
|
interface->fExtensions.swap(&extensions);
|
|
|
|
|
turn on -Wreturn-std-move-in-c++11
This CL has a complicated back story, but it's concrete change is
simple, just turning the warning on and converting a bunch of
return foo;
to
return std::move(foo);
These changes are exclusively in places where RVO and NRVO do not apply,
so it should not conflict with warnings like -Wpessimizing-move.
Since C++11, when you return a named local and its type doesn't match
the declared return type exactly, there's an implicit std::move()
wrapped around the value (what I'm making explicit here) so the move
constructor gets an opportunity to take precedence over the copy
constructor. You can read about this implicit move here under the
section "automatic move from local variables and parameters":
https://en.cppreference.com/w/cpp/language/return#Notes.
This situation comes up for us with smart pointers: a function declares
its return type as std::unique_ptr<Base> or sk_sp<Base>, and we return a
std::unique_ptr<Impl> or sk_sp<Impl>. Those types don't match exactly,
so RVO and NRVO don't come into play. They've always been going through
move constructors, and that's not changed here, just made explicit.
There was apparently once a bug in the C++11 standard and compilers
implementing that which made these copy instead of move, and then this
sort of code would do a little unnecessary ref/unref dance for sk_sp,
and would entirely fail to compile for uncopyable std::unique_ptr.
These explicit moves ostensibly will make our code more compatible with
those older compilers.
That compatibility alone is, I think, a terrible reason to land this CL.
Like, actively bad. But... to balance that out, I think the explicit
std::move()s here actually help remind us that RVO/NRVO are not in play,
and remind us we're going to call the move constructor. So that C++11
standard bug becomes kind of useful for us, in that Clang added this
warning to catch it, and its fix improves readability.
So really read this all as, "warn about implicit std::move() on return".
In the end I think it's just about readability. I don't really hold any
hope out that we'll become compatible with those older compilers.
Bug: skia:9909
Change-Id: Id596e9261188b6f10e759906af6c95fe303f6ffe
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271601
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
2020-02-18 19:33:23 +00:00
|
|
|
return std::move(interface);
|
2019-03-28 16:46:40 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
`
|
|
|
|
|
2019-03-25 21:23:55 +00:00
|
|
|
const VALIDATE_INTERFACE = `/*
|
|
|
|
* Copyright 2011 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*
|
|
|
|
* THIS FILE IS AUTOGENERATED
|
|
|
|
* Make edits to tools/gpu/gl/interface/templates.go or they will
|
|
|
|
* be overwritten.
|
|
|
|
*/
|
|
|
|
|
2019-04-24 17:10:37 +00:00
|
|
|
#include "include/gpu/gl/GrGLExtensions.h"
|
|
|
|
#include "include/gpu/gl/GrGLInterface.h"
|
|
|
|
#include "src/gpu/gl/GrGLUtil.h"
|
2019-03-25 21:23:55 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
GrGLInterface::GrGLInterface() {
|
|
|
|
fStandard = kNone_GrGLStandard;
|
|
|
|
}
|
|
|
|
|
2020-06-24 14:19:52 +00:00
|
|
|
#if GR_GL_CHECK_ERROR
|
|
|
|
static const char* get_error_string(GrGLenum err) {
|
|
|
|
switch (err) {
|
|
|
|
case GR_GL_NO_ERROR:
|
|
|
|
return "";
|
|
|
|
case GR_GL_INVALID_ENUM:
|
|
|
|
return "Invalid Enum";
|
|
|
|
case GR_GL_INVALID_VALUE:
|
|
|
|
return "Invalid Value";
|
|
|
|
case GR_GL_INVALID_OPERATION:
|
|
|
|
return "Invalid Operation";
|
|
|
|
case GR_GL_OUT_OF_MEMORY:
|
|
|
|
return "Out of Memory";
|
|
|
|
case GR_GL_CONTEXT_LOST:
|
|
|
|
return "Context Lost";
|
|
|
|
}
|
|
|
|
return "Unknown";
|
|
|
|
}
|
|
|
|
|
|
|
|
GrGLenum GrGLInterface::checkError(const char* location, const char* call) const {
|
|
|
|
GrGLenum error = fFunctions.fGetError();
|
|
|
|
if (error != GR_GL_NO_ERROR && !fSuppressErrorLogging) {
|
|
|
|
SkDebugf("---- glGetError 0x%x(%s)", error, get_error_string(error));
|
|
|
|
if (location) {
|
|
|
|
SkDebugf(" at\n\t%s", location);
|
|
|
|
}
|
|
|
|
if (call) {
|
|
|
|
SkDebugf("\n\t\t%s", call);
|
|
|
|
}
|
|
|
|
SkDebugf("\n");
|
|
|
|
if (error == GR_GL_OUT_OF_MEMORY) {
|
|
|
|
fOOMed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GrGLInterface::checkAndResetOOMed() const {
|
|
|
|
if (fOOMed) {
|
|
|
|
fOOMed = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GrGLInterface::suppressErrorLogging() { fSuppressErrorLogging = true; }
|
|
|
|
#endif
|
|
|
|
|
2019-03-25 21:23:55 +00:00
|
|
|
#define RETURN_FALSE_INTERFACE \
|
|
|
|
SkDEBUGF("%s:%d GrGLInterface::validate() failed.\n", __FILE__, __LINE__); \
|
|
|
|
return false
|
|
|
|
|
|
|
|
bool GrGLInterface::validate() const {
|
|
|
|
|
|
|
|
if (kNone_GrGLStandard == fStandard) {
|
|
|
|
RETURN_FALSE_INTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!fExtensions.isInitialized()) {
|
|
|
|
RETURN_FALSE_INTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
GrGLVersion glVer = GrGLGetVersion(this);
|
|
|
|
if (GR_GL_INVALID_VER == glVer) {
|
|
|
|
RETURN_FALSE_INTERFACE;
|
|
|
|
}
|
|
|
|
// Autogenerated content follows
|
|
|
|
[[content]]
|
|
|
|
// End autogenerated content
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if GR_TEST_UTILS
|
|
|
|
|
|
|
|
void GrGLInterface::abandon() const {
|
|
|
|
const_cast<GrGLInterface*>(this)->fFunctions = GrGLInterface::Functions();
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // GR_TEST_UTILS
|
|
|
|
`
|