Add GrContext::oomed() and implement for GL and VK.
Surfaces to client whether GrContext has seen a GL_OUT_MEMORY,
VK_ERROR_OUT_OF_HOST_MEMORY, or VK_ERROR_OUT_OF_DEVICE_MEMORY error.
Bug: chromium:1093997
Change-Id: I8e9799a0f7d8a74df056629d7d1d07c0d0a0fe30
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/298216
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrLegacyDirectContext.cpp b/src/gpu/GrLegacyDirectContext.cpp
index 07be4fb..4b027ea 100644
--- a/src/gpu/GrLegacyDirectContext.cpp
+++ b/src/gpu/GrLegacyDirectContext.cpp
@@ -31,6 +31,13 @@
#include "src/gpu/dawn/GrDawnGpu.h"
#endif
+#if GR_TEST_UTILS
+# include "include/utils/SkRandom.h"
+# if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
+# include <sanitizer/lsan_interface.h>
+# endif
+#endif
+
#ifdef SK_DISABLE_REDUCE_OPLIST_SPLITTING
static const bool kDefaultReduceOpsTaskSplitting = false;
#else
@@ -135,10 +142,50 @@
return MakeGL(nullptr, defaultOptions);
}
+#if GR_TEST_UTILS
+GrGLFunction<GrGLGetErrorFn> make_get_error_with_random_oom(GrGLFunction<GrGLGetErrorFn> original) {
+ // A SkRandom and a GrGLFunction<GrGLGetErrorFn> are too big to be captured by a
+ // GrGLFunction<GrGLGetError> (surprise, surprise). So we make a context object and
+ // capture that by pointer. However, GrGLFunction doesn't support calling a destructor
+ // on the thing it captures. So we leak the context.
+ struct GetErrorContext {
+ SkRandom fRandom;
+ GrGLFunction<GrGLGetErrorFn> fGetError;
+ };
+
+ auto errorContext = new GetErrorContext;
+
+#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
+ __lsan_ignore_object(errorContext);
+#endif
+
+ errorContext->fGetError = original;
+
+ return GrGLFunction<GrGLGetErrorFn>([errorContext]() {
+ GrGLenum error = errorContext->fGetError();
+ if (error == GR_GL_NO_ERROR && (errorContext->fRandom.nextU() % 300) == 0) {
+ error = GR_GL_OUT_OF_MEMORY;
+ }
+ return error;
+ });
+}
+#endif
+
sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> glInterface,
const GrContextOptions& options) {
sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kOpenGL, options));
-
+#if GR_TEST_UTILS
+ if (options.fRandomGLOOM) {
+ auto copy = sk_make_sp<GrGLInterface>(*glInterface);
+ copy->fFunctions.fGetError =
+ make_get_error_with_random_oom(glInterface->fFunctions.fGetError);
+#if GR_GL_CHECK_ERROR
+ // Suppress logging GL errors since we'll be synthetically generating them.
+ copy->suppressErrorLogging();
+#endif
+ glInterface = std::move(copy);
+ }
+#endif
context->fGpu = GrGLGpu::Make(std::move(glInterface), options, context.get());
if (!context->init()) {
return nullptr;