Move convert GL state into renderer backend

This commit is contained in:
2026-06-04 20:27:43 +02:00
parent 51601adf6d
commit 967a15f15f
8 changed files with 172 additions and 25 deletions

View File

@@ -325,9 +325,12 @@ Known local toolchain state:
App OpenGL initialization debug severity, debug output, GL info string,
renderer API viewport/scissor rect conversion, default depth/program-point/
line-smooth state, blend factor/equation, and UI render-target RGBA8 format
tokens are cataloged and tested here too, including the legacy convert command
and resize path. App clear color-buffer masks, default framebuffer binding,
scissor state, and sampler filter/wrap tokens also consume the backend mapping.
tokens are cataloged and tested here too. The legacy convert command now
applies its depth, program-point-size, source-alpha blend, and add-equation
startup policy through a tested dispatch contract here; the resize path
consumes the backend-owned mapping. App clear color-buffer masks, default
framebuffer binding, scissor state, and sampler filter/wrap tokens also
consume the backend mapping.
OpenGL extension enumeration query tokens
used before runtime capability detection are cataloged here. Legacy font
atlas texture formats, text mesh buffer targets, attribute component and
@@ -605,9 +608,12 @@ Known local toolchain state:
the retained `Texture2D` utility, tested framebuffer blit/readback dispatch
consumed by retained `RTT` resize/copy/readback paths, tested framebuffer
bind/restore dispatch consumed by retained `RTT` render-target pass entry
and exit paths, tested render platform hint and debug-output state dispatch
consumed by `WindowsPlatformServices`, plus renderer API to OpenGL token
mapping and command-planning contracts used by the OpenGL parity work.
and exit paths, tested convert-command state dispatch consumed by
`App::cmd_convert`, tested render platform hint dispatch consumed by
`WindowsPlatformServices` and the retained macOS legacy fallback, tested
debug-output state dispatch consumed by `WindowsPlatformServices`, plus
renderer API to OpenGL token mapping and command-planning contracts used by
the OpenGL parity work.
- `pano_cli plan-cloud-upload` exposes `pp_app_core` cloud upload availability,
new-document warning, publish prompt, and save-before-upload planning as JSON;
the live cloud upload command consumes the same start contract before

View File

@@ -35,7 +35,7 @@ agent or engineer to remove them without reconstructing context from chat.
| DEBT-0014 | Open | Modernization | `windows-clangcl-asan` now configures as a headless Ninja/clang-cl preset and uses the release MSVC runtime required by ASan, but local builds still fail because installed clang-cl 18.1.8 is paired with VS 2026-preview STL headers that require Clang 20 or newer | Sanitizer validation should be local and repeatable, but this machine's compiler/header pairing is incompatible | `cmake --fresh --preset windows-clangcl-asan`; `cmake --build --preset windows-clangcl-asan --target pp_foundation` | Install/use Clang 20+ with the VS 2026 STL, or point the preset at a compatible VS 2022 toolchain, then make `platform-build.ps1 -Presets windows-clangcl-asan` pass for the headless matrix |
| DEBT-0015 | Open | Modernization | Cursor visibility requests now consume pure `pp_app_core` planning through `pano_cli plan-cursor-visibility`, `App::show_cursor`/`App::hide_cursor` dispatch through `PlatformServices` without platform guards, and Windows live execution uses injected `WindowsPlatformServices`, but macOS cursor execution still reaches the retained fallback adapter | Keep canvas cursor behavior stable while platform shells are extracted incrementally | `pp_app_core_document_platform_io_tests`; `pano_cli plan-cursor-visibility --visible`; `ctest --preset desktop-fast --build-config Debug` | Cursor visibility execution is owned by injected `pp_platform_*` services for every supported platform |
| DEBT-0016 | Open | Modernization | Clipboard get/set requests now consume pure `pp_app_core` planning through `pano_cli plan-clipboard-read` and `pano_cli plan-clipboard-write`, and Windows live execution uses injected `WindowsPlatformServices`, but Apple/Android clipboard execution still reaches retained fallback adapter branches from `App::clipboard_get_text` and `App::clipboard_set_text` | Keep picker/color text clipboard behavior stable while platform shells are extracted incrementally | `pp_app_core_document_platform_io_tests`; `pano_cli plan-clipboard-write --text #ff00aa`; `ctest --preset desktop-fast --build-config Debug` | Clipboard execution is owned by injected `pp_platform_*` services for every supported platform |
| DEBT-0017 | Open | Modernization | Startup storage path preparation, `App::clipboard_get_text`, `App::clipboard_set_text`, `App::show_cursor`, `App::hide_cursor`, `App::showKeyboard`, `App::hideKeyboard`, `App::display_file`, `App::share_file`, native app/window close, UI-thread lifecycle hooks, render-context acquire/release/present hooks, render-target binding hooks, render platform hint hooks, render debug callback hooks, render-capture frame hooks, recording cleanup, live asset/layout reload policy, diagnostic stacktrace/crash hooks, per-frame platform hooks, `App::pick_image`, `App::pick_file`, the non-writer `App::pick_file_save`, `App::pick_dir`, working-directory picker/display-path policy, canvas input tip/pressure policy, prepared-file save/download handoff, work-directory document export collection policy, app network TLS verification policy, PPBR export data-directory policy, SonarPen availability/startup, and VR mode start/stop now call the SDK-free `pp::platform::PlatformServices` interface, and Windows injects `WindowsPlatformServices` from `src/platform_windows/windows_platform_services.*`; Windows render-platform hint and debug-output state token/enable sequencing now delegates to tested `pp_renderer_gl` helpers, leaving Windows with context, callback, console, and Win32 ownership; non-Windows live implementations still use `src/platform_legacy/legacy_platform_services.*`, a named fallback adapter that forwards to retained Apple/Android/Linux/Web bridge functions and retained no-op branches, including retained iOS canvas tip behavior, retained macOS directory picker/display-path behavior, retained iOS SonarPen bridge, retained non-Windows VR unsupported/no-op behavior, and retained macOS PPBR export directory override; `pp_platform_api` also owns the default network TLS policy helper consumed by retained curl sites that cannot yet depend on injected services | Preserve behavior while moving platform execution behind a testable service boundary before platform shell implementations are injected | `pp_platform_api_tests`; `pp_app_core_document_export_tests`; `pp_app_core_document_platform_io_tests`; `ctest --preset desktop-fast --build-config Debug`; `powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug` | Replace `src/platform_legacy/legacy_platform_services.*` with injected `pp_platform_*` service implementations owned by each non-Windows platform shell |
| DEBT-0017 | Open | Modernization | Startup storage path preparation, `App::clipboard_get_text`, `App::clipboard_set_text`, `App::show_cursor`, `App::hide_cursor`, `App::showKeyboard`, `App::hideKeyboard`, `App::display_file`, `App::share_file`, native app/window close, UI-thread lifecycle hooks, render-context acquire/release/present hooks, render-target binding hooks, render platform hint hooks, render debug callback hooks, render-capture frame hooks, recording cleanup, live asset/layout reload policy, diagnostic stacktrace/crash hooks, per-frame platform hooks, `App::pick_image`, `App::pick_file`, the non-writer `App::pick_file_save`, `App::pick_dir`, working-directory picker/display-path policy, canvas input tip/pressure policy, prepared-file save/download handoff, work-directory document export collection policy, app network TLS verification policy, PPBR export data-directory policy, SonarPen availability/startup, and VR mode start/stop now call the SDK-free `pp::platform::PlatformServices` interface, and Windows injects `WindowsPlatformServices` from `src/platform_windows/windows_platform_services.*`; Windows render-platform hint and debug-output state token/enable sequencing now delegates to tested `pp_renderer_gl` helpers, leaving Windows with context, callback, console, and Win32 ownership; the retained macOS fallback render-platform hint enable sequence also delegates to the same tested `pp_renderer_gl` helper; non-Windows live implementations still use `src/platform_legacy/legacy_platform_services.*`, a named fallback adapter that forwards to retained Apple/Android/Linux/Web bridge functions and retained no-op branches, including retained iOS canvas tip behavior, retained macOS directory picker/display-path behavior, retained iOS SonarPen bridge, retained non-Windows VR unsupported/no-op behavior, and retained macOS PPBR export directory override; `pp_platform_api` also owns the default network TLS policy helper consumed by retained curl sites that cannot yet depend on injected services | Preserve behavior while moving platform execution behind a testable service boundary before platform shell implementations are injected | `pp_platform_api_tests`; `pp_app_core_document_export_tests`; `pp_app_core_document_platform_io_tests`; `ctest --preset desktop-fast --build-config Debug`; `powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug` | Replace `src/platform_legacy/legacy_platform_services.*` with injected `pp_platform_*` service implementations owned by each non-Windows platform shell |
| DEBT-0019 | Open | Modernization | Unreferenced-parameter warnings are muted globally through `pp_project_warnings` with MSVC `/wd4100` and Clang/GCC `-Wno-unused-parameter` | Legacy callbacks, virtual hooks, serializer methods, and platform/API compatibility functions carry many intentionally unused parameters during the component split; muting this keeps stricter warning builds focused on higher-signal migration issues | `cmake --build --preset windows-msvc-default --config Debug --target PanoPainter`; `ctest --preset desktop-fast --build-config Debug`; `cmake --build --preset linux-clang --target pp_foundation` | Remove `/wd4100` and `-Wno-unused-parameter`, mark intentionally unused parameters with names/comments or `[[maybe_unused]]`, and make the Windows app plus headless Clang/GCC tests pass without unreferenced-parameter warnings |
| DEBT-0020 | Open | Modernization | Document resize dialog state, selected-resolution planning, and execution dispatch now consume pure `pp_app_core` through `NodeDialogResize`, `App::dialog_resize`, `pano_cli plan-document-resize`, and the `DocumentResizeServices` boundary, and live resize shares `src/legacy_document_canvas_services.*` with canvas clear commands, but the shared live bridge still calls legacy `Canvas::resize`, updates the legacy app title, and clears legacy `ActionManager` history through the history bridge | Preserve existing layer/frame GPU resize behavior while the document model and canvas execution boundary are extracted incrementally | `pp_app_core_document_resize_tests`; `pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 4`; `ctest --preset desktop-fast --build-config Debug` | Document resize execution is owned by injected document/app services with no legacy resize adapter, title shim, or direct `ActionManager` history clearing |
| DEBT-0021 | Open | Modernization | Layer rename planning/execution dispatch and layer panel operation planning/execution dispatch now consume pure `pp_app_core` through `App::dialog_layer_rename`, `App::init_sidebar` layer callbacks, `pano_cli plan-layer-rename`, `pano_cli plan-layer-operation`, `DocumentLayerRenameServices`, and `DocumentLayerOperationServices`, and the live execution adapters are centralized in `src/legacy_document_layer_services.*`, but that shared bridge still mutates legacy `Canvas` layer state, `NodeLayer`/`NodePanelLayer`, and `ActionManager` undo entries | Preserve existing UI/canvas behavior while document layer commands and undo history are extracted incrementally | `pp_app_core_document_layer_tests`; `pano_cli plan-layer-rename --old-name Base --new-name Paint`; `pano_cli plan-layer-operation --kind add --layer-count 2 --index 1 --name Paint`; `ctest --preset desktop-fast --build-config Debug` | Layer command execution is owned by the document/app command boundary with legacy `Canvas`/UI nodes acting only as adapters or removed entirely |

View File

@@ -766,7 +766,10 @@ preserving the previous Windows/macOS program-point-size and line-smoothing
enablement while removing the Windows/macOS branch from `App::init`. The
Windows service now delegates the actual OpenGL program-point-size and
line-smooth enable sequence to a tested `pp_renderer_gl` dispatch helper, so
the platform shell no longer owns those backend state tokens.
the platform shell no longer owns those backend state tokens. The legacy
non-Windows fallback now consumes the same helper for retained macOS render
platform hints, keeping the debt-tracked adapter as a thin GL call bridge
rather than a source of backend state policy.
Windows OpenGL debug callback setup now dispatches through `PlatformServices`,
moving Win32 console coloring and debug-break callback behavior into
`WindowsPlatformServices` while keeping other platform adapters as no-ops; the
@@ -1029,7 +1032,9 @@ directly. App OpenGL initialization debug severity, debug output, GL info
string, renderer API viewport/scissor rect conversion, default
depth/program-point/line-smooth state, blend factor/equation, and UI
render-target RGBA8 format tokens are now also cataloged and tested in
`pp_renderer_gl`; the legacy convert command and resize path consume the same
`pp_renderer_gl`; the legacy convert command now applies its depth,
program-point-size, source-alpha blend, and add-equation startup policy through
a tested backend dispatch contract, and the resize path consumes the same
backend-owned mapping. App clear color-buffer masks, default framebuffer
binding, scissor state, and sampler filter/wrap tokens now share that backend
mapping too. OpenGL extension enumeration query tokens used before runtime

View File

@@ -1,43 +1,49 @@
#include "pch.h"
#include "app.h"
#include "canvas.h"
#include "log.h"
#include "renderer_gl/opengl_capabilities.h"
namespace {
[[nodiscard]] GLenum depth_test_state() noexcept
void enable_opengl_state(std::uint32_t state) noexcept
{
return static_cast<GLenum>(pp::renderer::gl::depth_test_state());
glEnable(static_cast<GLenum>(state));
}
[[nodiscard]] GLenum program_point_size_state() noexcept
void disable_opengl_state(std::uint32_t state) noexcept
{
return static_cast<GLenum>(pp::renderer::gl::program_point_size_state());
glDisable(static_cast<GLenum>(state));
}
[[nodiscard]] GLenum source_alpha_blend_factor() noexcept
void set_opengl_blend_func(std::uint32_t source_factor, std::uint32_t destination_factor) noexcept
{
return static_cast<GLenum>(pp::renderer::gl::source_alpha_blend_factor());
glBlendFunc(static_cast<GLenum>(source_factor), static_cast<GLenum>(destination_factor));
}
[[nodiscard]] GLenum one_minus_source_alpha_blend_factor() noexcept
void set_opengl_blend_equation(std::uint32_t equation) noexcept
{
return static_cast<GLenum>(pp::renderer::gl::one_minus_source_alpha_blend_factor());
glBlendEquation(static_cast<GLenum>(equation));
}
[[nodiscard]] GLenum add_blend_equation() noexcept
void apply_convert_command_state()
{
return static_cast<GLenum>(pp::renderer::gl::add_blend_equation());
const auto status = pp::renderer::gl::apply_panopainter_convert_command_state(
pp::renderer::gl::OpenGlConvertCommandStateDispatch {
.enable = enable_opengl_state,
.disable = disable_opengl_state,
.blend_func = set_opengl_blend_func,
.blend_equation = set_opengl_blend_equation,
});
if (!status.ok())
LOG("OpenGL convert command state failed: %s", status.message);
}
}
void App::cmd_convert(std::string pano_path, std::string out_path)
{
glDisable(depth_test_state());
glEnable(program_point_size_state());
glBlendFunc(source_alpha_blend_factor(), one_minus_source_alpha_blend_factor());
glBlendEquation(add_blend_equation());
apply_convert_command_state();
Canvas* command_canvas = new Canvas;
const int canvas_resolution = default_canvas_resolution();

View File

@@ -3,6 +3,7 @@
#include "app.h"
#include "app_core/document_platform_io.h"
#include "log.h"
#include "platform_api/network_tls_policy.h"
#include "renderer_gl/opengl_capabilities.h"
@@ -57,6 +58,11 @@ void invoke_picked_path_if_selected(
callback(path);
}
void enable_gl_capability(std::uint32_t state) noexcept
{
glEnable(static_cast<GLenum>(state));
}
// DEBT-0017: fallback for platforms that do not inject PlatformServices yet.
class LegacyPlatformServices final : public pp::platform::PlatformServices {
public:
@@ -259,8 +265,12 @@ public:
void apply_render_platform_hints() override
{
#if defined(__OSX__)
glEnable(static_cast<GLenum>(pp::renderer::gl::program_point_size_state()));
glEnable(static_cast<GLenum>(pp::renderer::gl::line_smooth_state()));
const auto status = pp::renderer::gl::apply_opengl_render_platform_hints(
pp::renderer::gl::OpenGlRenderPlatformHintDispatch {
.enable = enable_gl_capability,
});
if (!status.ok())
LOG("OpenGL legacy render platform hints failed: %s", status.message);
#endif
}

View File

@@ -273,6 +273,47 @@ pp::foundation::Status apply_panopainter_initial_state(OpenGlStateDispatch dispa
return pp::foundation::Status::success();
}
OpenGlConvertCommandState panopainter_convert_command_state() noexcept
{
return OpenGlConvertCommandState {
.depth_test_enabled = false,
.program_point_size_enabled = true,
.depth_test_state = depth_test_state(),
.program_point_size_state = program_point_size_state(),
.source_color_factor = source_alpha_blend_factor(),
.destination_color_factor = one_minus_source_alpha_blend_factor(),
.blend_equation = add_blend_equation(),
};
}
pp::foundation::Status apply_panopainter_convert_command_state(
OpenGlConvertCommandStateDispatch dispatch) noexcept
{
if (dispatch.enable == nullptr
|| dispatch.disable == nullptr
|| dispatch.blend_func == nullptr
|| dispatch.blend_equation == nullptr)
{
return pp::foundation::Status::invalid_argument(
"OpenGL convert command state dispatch callbacks must not be null");
}
const auto state = panopainter_convert_command_state();
if (state.depth_test_enabled)
dispatch.enable(state.depth_test_state);
else
dispatch.disable(state.depth_test_state);
if (state.program_point_size_enabled)
dispatch.enable(state.program_point_size_state);
else
dispatch.disable(state.program_point_size_state);
dispatch.blend_func(state.source_color_factor, state.destination_color_factor);
dispatch.blend_equation(state.blend_equation);
return pp::foundation::Status::success();
}
pp::foundation::Result<OpenGlSavedState> snapshot_opengl_state(OpenGlStateSnapshotDispatch dispatch) noexcept
{
if (dispatch.is_enabled == nullptr

View File

@@ -272,6 +272,16 @@ struct OpenGlInitialState {
std::uint32_t alpha_equation = 0;
};
struct OpenGlConvertCommandState {
bool depth_test_enabled = false;
bool program_point_size_enabled = false;
std::uint32_t depth_test_state = 0;
std::uint32_t program_point_size_state = 0;
std::uint32_t source_color_factor = 0;
std::uint32_t destination_color_factor = 0;
std::uint32_t blend_equation = 0;
};
struct OpenGlSavedState {
std::uint8_t blend_enabled = 0;
std::uint8_t depth_test_enabled = 0;
@@ -297,6 +307,7 @@ using OpenGlClearFn = void (*)(std::uint32_t mask) noexcept;
using OpenGlViewportFn = void (*)(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept;
using OpenGlScissorFn = void (*)(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept;
using OpenGlBlendFuncFn = void (*)(std::uint32_t source_factor, std::uint32_t destination_factor) noexcept;
using OpenGlBlendEquationFn = void (*)(std::uint32_t equation) noexcept;
using OpenGlBlendEquationSeparateFn = void (*)(std::uint32_t color_equation, std::uint32_t alpha_equation) noexcept;
using OpenGlUseProgramFn = void (*)(std::uint32_t program) noexcept;
using OpenGlDeleteProgramFn = void (*)(std::uint32_t program) noexcept;
@@ -444,6 +455,13 @@ struct OpenGlStateDispatch {
OpenGlBlendEquationSeparateFn blend_equation_separate = nullptr;
};
struct OpenGlConvertCommandStateDispatch {
OpenGlCapabilityFn enable = nullptr;
OpenGlCapabilityFn disable = nullptr;
OpenGlBlendFuncFn blend_func = nullptr;
OpenGlBlendEquationFn blend_equation = nullptr;
};
struct OpenGlStateSnapshotDispatch {
OpenGlIsEnabledFn is_enabled = nullptr;
OpenGlGetIntegerFn get_integer = nullptr;
@@ -715,6 +733,9 @@ struct OpenGlMeshDeleteDispatch {
OpenGlRuntime runtime);
[[nodiscard]] OpenGlInitialState panopainter_initial_state() noexcept;
[[nodiscard]] pp::foundation::Status apply_panopainter_initial_state(OpenGlStateDispatch dispatch) noexcept;
[[nodiscard]] OpenGlConvertCommandState panopainter_convert_command_state() noexcept;
[[nodiscard]] pp::foundation::Status apply_panopainter_convert_command_state(
OpenGlConvertCommandStateDispatch dispatch) noexcept;
[[nodiscard]] pp::foundation::Result<OpenGlSavedState> snapshot_opengl_state(
OpenGlStateSnapshotDispatch dispatch) noexcept;
[[nodiscard]] pp::foundation::Status restore_opengl_state(

View File

@@ -17,6 +17,7 @@ struct RecordedOpenGlStateCall {
enable,
disable,
blend_func,
blend_equation,
blend_equation_separate,
};
@@ -254,6 +255,14 @@ void record_blend_func(std::uint32_t source_factor, std::uint32_t destination_fa
});
}
void record_blend_equation(std::uint32_t equation) noexcept
{
recorded_state_calls.push_back(RecordedOpenGlStateCall {
.kind = RecordedOpenGlStateCall::Kind::blend_equation,
.first = equation,
});
}
void record_blend_equation_separate(std::uint32_t color_equation, std::uint32_t alpha_equation) noexcept
{
recorded_state_calls.push_back(RecordedOpenGlStateCall {
@@ -1646,6 +1655,15 @@ void maps_app_initialization_parameters(pp::tests::Harness& h)
PP_EXPECT(h, initial_state.color_equation == 0x8006U);
PP_EXPECT(h, initial_state.alpha_equation == 0x8008U);
const auto convert_state = pp::renderer::gl::panopainter_convert_command_state();
PP_EXPECT(h, !convert_state.depth_test_enabled);
PP_EXPECT(h, convert_state.program_point_size_enabled);
PP_EXPECT(h, convert_state.depth_test_state == 0x0B71U);
PP_EXPECT(h, convert_state.program_point_size_state == 0x8642U);
PP_EXPECT(h, convert_state.source_color_factor == 0x0302U);
PP_EXPECT(h, convert_state.destination_color_factor == 0x0303U);
PP_EXPECT(h, convert_state.blend_equation == 0x8006U);
PP_EXPECT(h, pp::renderer::gl::rgba8_internal_format() == 0x8058U);
PP_EXPECT(h, pp::renderer::gl::rgba16f_internal_format() == 0x881AU);
PP_EXPECT(h, pp::renderer::gl::rgba32f_internal_format() == 0x8814U);
@@ -1698,6 +1716,44 @@ void rejects_incomplete_app_initialization_state_dispatch(pp::tests::Harness& h)
PP_EXPECT(h, status.code == pp::foundation::StatusCode::invalid_argument);
}
void applies_convert_command_state(pp::tests::Harness& h)
{
recorded_state_calls.clear();
const auto status = pp::renderer::gl::apply_panopainter_convert_command_state(
pp::renderer::gl::OpenGlConvertCommandStateDispatch {
.enable = record_enable,
.disable = record_disable,
.blend_func = record_blend_func,
.blend_equation = record_blend_equation,
});
PP_EXPECT(h, status.ok());
PP_EXPECT(h, recorded_state_calls.size() == 4U);
PP_EXPECT(h, recorded_state_calls[0].kind == RecordedOpenGlStateCall::Kind::disable);
PP_EXPECT(h, recorded_state_calls[0].first == 0x0B71U);
PP_EXPECT(h, recorded_state_calls[1].kind == RecordedOpenGlStateCall::Kind::enable);
PP_EXPECT(h, recorded_state_calls[1].first == 0x8642U);
PP_EXPECT(h, recorded_state_calls[2].kind == RecordedOpenGlStateCall::Kind::blend_func);
PP_EXPECT(h, recorded_state_calls[2].first == 0x0302U);
PP_EXPECT(h, recorded_state_calls[2].second == 0x0303U);
PP_EXPECT(h, recorded_state_calls[3].kind == RecordedOpenGlStateCall::Kind::blend_equation);
PP_EXPECT(h, recorded_state_calls[3].first == 0x8006U);
}
void rejects_incomplete_convert_command_state_dispatch(pp::tests::Harness& h)
{
const auto status = pp::renderer::gl::apply_panopainter_convert_command_state(
pp::renderer::gl::OpenGlConvertCommandStateDispatch {
.enable = record_enable,
.disable = record_disable,
.blend_func = record_blend_func,
});
PP_EXPECT(h, !status.ok());
PP_EXPECT(h, status.code == pp::foundation::StatusCode::invalid_argument);
}
void snapshots_legacy_gl_state(pp::tests::Harness& h)
{
recorded_integer_queries.clear();
@@ -4354,6 +4410,8 @@ int main()
harness.run("maps_app_initialization_parameters", maps_app_initialization_parameters);
harness.run("applies_app_initialization_state", applies_app_initialization_state);
harness.run("rejects_incomplete_app_initialization_state_dispatch", rejects_incomplete_app_initialization_state_dispatch);
harness.run("applies_convert_command_state", applies_convert_command_state);
harness.run("rejects_incomplete_convert_command_state_dispatch", rejects_incomplete_convert_command_state_dispatch);
harness.run("snapshots_legacy_gl_state", snapshots_legacy_gl_state);
harness.run("rejects_incomplete_gl_state_snapshot_dispatch", rejects_incomplete_gl_state_snapshot_dispatch);
harness.run("restores_legacy_gl_state", restores_legacy_gl_state);