Extract retained stroke preview pass orchestration plan
This commit is contained in:
@@ -18,6 +18,14 @@ agent or engineer to remove them without reconstructing context from chat.
|
|||||||
|
|
||||||
## Recent Reductions
|
## Recent Reductions
|
||||||
|
|
||||||
|
- 2026-06-13: DEBT-0036 was narrowed again. `NodeStrokePreview::draw_stroke_immediate()`
|
||||||
|
now routes retained preview feedback/material/composite planning plus stroke
|
||||||
|
shader uniform assembly through
|
||||||
|
`plan_legacy_node_stroke_preview_pass_orchestration(...)`; focused compositor
|
||||||
|
coverage now locks the retained destination-feedback fallback, composite-slot
|
||||||
|
intent, and pattern/dual shader-uniform handoff while brush mutation, retained
|
||||||
|
`Stroke` population, and live GL callback execution remain in the preview
|
||||||
|
node.
|
||||||
- 2026-06-13: DEBT-0036 was narrowed again. `NodeStrokePreview::draw_stroke_immediate()`
|
- 2026-06-13: DEBT-0036 was narrowed again. `NodeStrokePreview::draw_stroke_immediate()`
|
||||||
now routes retained preview stroke max-size fallback, dual-preview max-size
|
now routes retained preview stroke max-size fallback, dual-preview max-size
|
||||||
derivation, pattern-scale flips, and Bezier preview-point generation through
|
derivation, pattern-scale flips, and Bezier preview-point generation through
|
||||||
|
|||||||
@@ -62,6 +62,12 @@ queue, blocked queue, validation commands, and completion rules. Do not move the
|
|||||||
percentage for a narrowed adapter or added planner unless a task in that file is
|
percentage for a narrowed adapter or added planner unless a task in that file is
|
||||||
marked `Done` with validation and a debt/roadmap update.
|
marked `Done` with validation and a debt/roadmap update.
|
||||||
|
|
||||||
|
Recent 2026-06-13 retained preview reductions continue to narrow DEBT-0036:
|
||||||
|
`NodeStrokePreview::draw_stroke_immediate()` now also routes
|
||||||
|
feedback/material/composite planning and stroke-shader uniform assembly through
|
||||||
|
`plan_legacy_node_stroke_preview_pass_orchestration(...)`, leaving the preview
|
||||||
|
node with a smaller live-GL callback surface around pass execution.
|
||||||
|
|
||||||
## Target Component Architecture
|
## Target Component Architecture
|
||||||
|
|
||||||
The refactor should move toward one-way dependencies:
|
The refactor should move toward one-way dependencies:
|
||||||
|
|||||||
@@ -509,6 +509,15 @@ Done Checks:
|
|||||||
|
|
||||||
Progress Notes:
|
Progress Notes:
|
||||||
|
|
||||||
|
- 2026-06-13: `NodeStrokePreview::draw_stroke_immediate()` now routes retained
|
||||||
|
preview feedback/material/composite planning plus stroke-shader uniform
|
||||||
|
assembly through `plan_legacy_node_stroke_preview_pass_orchestration(...)`;
|
||||||
|
compositor coverage now locks destination-feedback fallback, composite-slot
|
||||||
|
intent, and the retained pattern/dual shader-uniform handoff. The preview
|
||||||
|
node still owns brush object mutation, retained `Stroke` population, and the
|
||||||
|
concrete GL pass callbacks. Next slice should target another narrow preview
|
||||||
|
execution seam without reopening the landed preview setup, mix, pass-sequence,
|
||||||
|
or final-composite helpers.
|
||||||
- 2026-06-13: `NodeStrokePreview::draw_stroke_immediate()` now routes preview
|
- 2026-06-13: `NodeStrokePreview::draw_stroke_immediate()` now routes preview
|
||||||
stroke max-size fallback, dual-preview max-size derivation, pattern-scale
|
stroke max-size fallback, dual-preview max-size derivation, pattern-scale
|
||||||
flips, and Bezier preview-point generation through
|
flips, and Bezier preview-point generation through
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "../libs/glm/glm/glm.hpp"
|
#include "../libs/glm/glm/glm.hpp"
|
||||||
#include "../libs/glm/glm/ext/matrix_clip_space.hpp"
|
#include "../libs/glm/glm/ext/matrix_clip_space.hpp"
|
||||||
|
|
||||||
|
#include "legacy_canvas_stroke_shader_services.h"
|
||||||
#include "legacy_canvas_stroke_services.h"
|
#include "legacy_canvas_stroke_services.h"
|
||||||
#include "paint_renderer/compositor.h"
|
#include "paint_renderer/compositor.h"
|
||||||
|
|
||||||
@@ -224,6 +225,98 @@ struct LegacyNodeStrokePreviewPassSequenceRequest {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct LegacyNodeStrokePreviewPassOrchestrationPlan {
|
||||||
|
pp::paint_renderer::CanvasStrokeFeedbackPlan feedback {};
|
||||||
|
pp::paint_renderer::CanvasStrokeMaterialPlan material {};
|
||||||
|
pp::paint_renderer::StrokePreviewCompositePlan composite {};
|
||||||
|
LegacyStrokeShaderSetupUniforms stroke_shader {};
|
||||||
|
bool copy_stroke_destination = false;
|
||||||
|
bool background_colorize = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LegacyNodeStrokePreviewPassOrchestrationRequest {
|
||||||
|
pp::renderer::RenderDeviceFeatures features {};
|
||||||
|
glm::vec2 preview_size {};
|
||||||
|
float pattern_scale = 0.0f;
|
||||||
|
bool pattern_flipx = false;
|
||||||
|
bool pattern_flipy = false;
|
||||||
|
bool pattern_invert = false;
|
||||||
|
float pattern_brightness = 0.0f;
|
||||||
|
float pattern_contrast = 0.0f;
|
||||||
|
float pattern_depth = 0.0f;
|
||||||
|
bool pattern_rand_offset = false;
|
||||||
|
bool pattern_enabled = false;
|
||||||
|
bool pattern_eachsample = false;
|
||||||
|
float tip_mix = 0.0f;
|
||||||
|
float tip_wet = 0.0f;
|
||||||
|
float tip_noise = 0.0f;
|
||||||
|
bool dual_enabled = false;
|
||||||
|
int dual_blend_mode = 0;
|
||||||
|
float dual_opacity = 0.0f;
|
||||||
|
int pattern_blend_mode = 0;
|
||||||
|
int blend_mode = 0;
|
||||||
|
glm::mat4 mvp { 1.0f };
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] inline LegacyNodeStrokePreviewPassOrchestrationPlan
|
||||||
|
plan_legacy_node_stroke_preview_pass_orchestration(
|
||||||
|
const LegacyNodeStrokePreviewPassOrchestrationRequest& request) noexcept
|
||||||
|
{
|
||||||
|
LegacyNodeStrokePreviewPassOrchestrationPlan plan;
|
||||||
|
plan.feedback = plan_legacy_node_stroke_preview_feedback(
|
||||||
|
request.features,
|
||||||
|
static_cast<int>(request.preview_size.x),
|
||||||
|
static_cast<int>(request.preview_size.y));
|
||||||
|
plan.copy_stroke_destination = !plan.feedback.reads_destination_color;
|
||||||
|
plan.material = plan_legacy_canvas_stroke_material(
|
||||||
|
pp::paint_renderer::CanvasStrokeMaterialRequest {
|
||||||
|
.destination_feedback_needed = plan.copy_stroke_destination,
|
||||||
|
.pattern_enabled = request.pattern_enabled,
|
||||||
|
.pattern_eachsample = request.pattern_eachsample,
|
||||||
|
.wet_blend = request.tip_wet > 0.0f,
|
||||||
|
.mix_blend = request.tip_mix > 0.0f,
|
||||||
|
.noise_enabled = request.tip_noise > 0.0f,
|
||||||
|
.dual_brush_enabled = request.dual_enabled,
|
||||||
|
.dual_blend_mode = request.dual_blend_mode,
|
||||||
|
.pattern_blend_mode = request.pattern_blend_mode,
|
||||||
|
.dual_alpha = request.dual_opacity,
|
||||||
|
});
|
||||||
|
plan.composite = plan_legacy_node_stroke_preview_composite(
|
||||||
|
request.tip_mix > 0.0f,
|
||||||
|
plan.material.composite_pass.use_dual,
|
||||||
|
plan.material.composite_pass.use_pattern);
|
||||||
|
|
||||||
|
glm::vec2 preview_pattern_scale(request.pattern_scale);
|
||||||
|
if (request.pattern_flipx) {
|
||||||
|
preview_pattern_scale.x *= -1.0f;
|
||||||
|
}
|
||||||
|
if (request.pattern_flipy) {
|
||||||
|
preview_pattern_scale.y *= -1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
plan.stroke_shader = LegacyStrokeShaderSetupUniforms {
|
||||||
|
.resolution = request.preview_size,
|
||||||
|
.pattern = {
|
||||||
|
.scale = preview_pattern_scale,
|
||||||
|
.invert = static_cast<float>(request.pattern_invert),
|
||||||
|
.brightness = request.pattern_brightness,
|
||||||
|
.contrast = request.pattern_contrast,
|
||||||
|
.depth = request.pattern_depth,
|
||||||
|
.blend_mode = request.pattern_blend_mode,
|
||||||
|
.offset = glm::vec2(request.pattern_rand_offset ? 0.5f : 0.0f),
|
||||||
|
},
|
||||||
|
.mvp = request.mvp,
|
||||||
|
.uses_destination_feedback = plan.copy_stroke_destination,
|
||||||
|
.uses_pattern = false,
|
||||||
|
.mix_alpha = 0.0f,
|
||||||
|
.wet = 0.0f,
|
||||||
|
.noise = 0.0f,
|
||||||
|
.set_opacity = false,
|
||||||
|
};
|
||||||
|
plan.background_colorize = request.tip_mix > 0.0f || request.blend_mode != 0;
|
||||||
|
return plan;
|
||||||
|
}
|
||||||
|
|
||||||
struct LegacyNodeStrokePreviewStrokePoint {
|
struct LegacyNodeStrokePreviewStrokePoint {
|
||||||
glm::vec3 position {};
|
glm::vec3 position {};
|
||||||
float pressure = 0.0f;
|
float pressure = 0.0f;
|
||||||
|
|||||||
@@ -27,35 +27,6 @@ pp::renderer::RenderDeviceFeatures stroke_preview_render_device_features() noexc
|
|||||||
return ShaderManager::render_device_features();
|
return ShaderManager::render_device_features();
|
||||||
}
|
}
|
||||||
|
|
||||||
pp::paint_renderer::CanvasStrokeFeedbackPlan stroke_preview_destination_feedback_plan(
|
|
||||||
int width,
|
|
||||||
int height) noexcept
|
|
||||||
{
|
|
||||||
return pp::panopainter::plan_legacy_node_stroke_preview_feedback(
|
|
||||||
stroke_preview_render_device_features(),
|
|
||||||
width,
|
|
||||||
height);
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::paint_renderer::CanvasStrokeMaterialPlan stroke_preview_material_plan(
|
|
||||||
const Brush& brush,
|
|
||||||
bool destination_feedback_needed) noexcept
|
|
||||||
{
|
|
||||||
return pp::panopainter::plan_legacy_canvas_stroke_material(
|
|
||||||
pp::paint_renderer::CanvasStrokeMaterialRequest {
|
|
||||||
.destination_feedback_needed = destination_feedback_needed,
|
|
||||||
.pattern_enabled = brush.m_pattern_enabled,
|
|
||||||
.pattern_eachsample = brush.m_pattern_eachsample,
|
|
||||||
.wet_blend = brush.m_tip_wet > 0.F,
|
|
||||||
.mix_blend = brush.m_tip_mix > 0.F,
|
|
||||||
.noise_enabled = brush.m_tip_noise > 0.F,
|
|
||||||
.dual_brush_enabled = brush.m_dual_enabled,
|
|
||||||
.dual_blend_mode = brush.m_dual_blend_mode,
|
|
||||||
.pattern_blend_mode = brush.m_pattern_blend_mode,
|
|
||||||
.dual_alpha = brush.m_dual_opacity,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_active_texture_unit(std::uint32_t unit_index)
|
void set_active_texture_unit(std::uint32_t unit_index)
|
||||||
{
|
{
|
||||||
pp::legacy::ui_gl::activate_texture_unit(unit_index, "NodeStrokePreview");
|
pp::legacy::ui_gl::activate_texture_unit(unit_index, "NodeStrokePreview");
|
||||||
@@ -761,33 +732,33 @@ void NodeStrokePreview::draw_stroke_immediate()
|
|||||||
const glm::vec2 patt_scale = stroke_setup.pattern_scale;
|
const glm::vec2 patt_scale = stroke_setup.pattern_scale;
|
||||||
|
|
||||||
apply_stroke_preview_capability(pp::renderer::gl::blend_state(), false);
|
apply_stroke_preview_capability(pp::renderer::gl::blend_state(), false);
|
||||||
const auto stroke_feedback = stroke_preview_destination_feedback_plan(m_rtt.getWidth(), m_rtt.getHeight());
|
const auto pass_orchestration = pp::panopainter::plan_legacy_node_stroke_preview_pass_orchestration(
|
||||||
const bool copy_stroke_destination = !stroke_feedback.reads_destination_color;
|
pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationRequest {
|
||||||
const auto material = stroke_preview_material_plan(*b, copy_stroke_destination);
|
.features = stroke_preview_render_device_features(),
|
||||||
const auto preview_composite_plan = pp::panopainter::plan_legacy_node_stroke_preview_composite(
|
.preview_size = size,
|
||||||
b->m_tip_mix > 0.0f,
|
.pattern_scale = b->m_pattern_scale,
|
||||||
material.composite_pass.use_dual,
|
.pattern_flipx = b->m_pattern_flipx,
|
||||||
material.composite_pass.use_pattern);
|
.pattern_flipy = b->m_pattern_flipy,
|
||||||
pp::panopainter::setup_legacy_stroke_shader(
|
.pattern_invert = b->m_pattern_invert,
|
||||||
pp::panopainter::LegacyStrokeShaderSetupUniforms {
|
.pattern_brightness = b->m_pattern_brightness,
|
||||||
.resolution = size,
|
.pattern_contrast = b->m_pattern_contrast,
|
||||||
.pattern = {
|
.pattern_depth = b->m_pattern_depth,
|
||||||
.scale = patt_scale,
|
.pattern_rand_offset = b->m_pattern_rand_offset,
|
||||||
.invert = static_cast<float>(b->m_pattern_invert),
|
.pattern_enabled = b->m_pattern_enabled,
|
||||||
.brightness = b->m_pattern_brightness,
|
.pattern_eachsample = b->m_pattern_eachsample,
|
||||||
.contrast = b->m_pattern_contrast,
|
.tip_mix = b->m_tip_mix,
|
||||||
.depth = b->m_pattern_depth,
|
.tip_wet = b->m_tip_wet,
|
||||||
.blend_mode = b->m_pattern_blend_mode,
|
.tip_noise = b->m_tip_noise,
|
||||||
.offset = glm::vec2(b->m_pattern_rand_offset ? 0.5f : 0.0f),
|
.dual_enabled = b->m_dual_enabled,
|
||||||
},
|
.dual_blend_mode = b->m_dual_blend_mode,
|
||||||
|
.dual_opacity = b->m_dual_opacity,
|
||||||
|
.pattern_blend_mode = b->m_pattern_blend_mode,
|
||||||
|
.blend_mode = b->m_blend_mode,
|
||||||
.mvp = ortho_proj,
|
.mvp = ortho_proj,
|
||||||
.uses_destination_feedback = copy_stroke_destination,
|
|
||||||
.uses_pattern = false,
|
|
||||||
.mix_alpha = 0.0f,
|
|
||||||
.wet = 0.0f,
|
|
||||||
.noise = 0.0f,
|
|
||||||
.set_opacity = false,
|
|
||||||
});
|
});
|
||||||
|
const bool copy_stroke_destination = pass_orchestration.copy_stroke_destination;
|
||||||
|
const auto& material = pass_orchestration.material;
|
||||||
|
pp::panopainter::setup_legacy_stroke_shader(pass_orchestration.stroke_shader);
|
||||||
|
|
||||||
const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_pass_sequence(
|
const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_pass_sequence(
|
||||||
pp::panopainter::LegacyNodeStrokePreviewPassSequenceRequest {
|
pp::panopainter::LegacyNodeStrokePreviewPassSequenceRequest {
|
||||||
@@ -817,7 +788,7 @@ void NodeStrokePreview::draw_stroke_immediate()
|
|||||||
.capture_background = [&] {
|
.capture_background = [&] {
|
||||||
execute_stroke_preview_background_capture_pass(
|
execute_stroke_preview_background_capture_pass(
|
||||||
size,
|
size,
|
||||||
b->m_tip_mix > 0.f || b->m_blend_mode != 0,
|
pass_orchestration.background_colorize,
|
||||||
m_tex_background,
|
m_tex_background,
|
||||||
[&] {
|
[&] {
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
@@ -836,7 +807,7 @@ void NodeStrokePreview::draw_stroke_immediate()
|
|||||||
m_tex,
|
m_tex,
|
||||||
m_rtt_mixer,
|
m_rtt_mixer,
|
||||||
copy_stroke_destination,
|
copy_stroke_destination,
|
||||||
preview_composite_plan.uses_mixer);
|
pass_orchestration.composite.uses_mixer);
|
||||||
},
|
},
|
||||||
.execute_main_pass = [&] {
|
.execute_main_pass = [&] {
|
||||||
execute_stroke_preview_live_pass(
|
execute_stroke_preview_live_pass(
|
||||||
|
|||||||
157
src/shader.h
157
src/shader.h
@@ -1,91 +1,104 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "renderer_api/renderer_api.h"
|
#include "renderer_api/renderer_api.h"
|
||||||
#include "util.h"
|
|
||||||
|
#include "../libs/glm/glm/glm.hpp"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
uint16_t constexpr shader_const_hash(const char* input)
|
||||||
|
{
|
||||||
|
return *input ?
|
||||||
|
static_cast<uint16_t>(*input) + 33 * shader_const_hash(input + 1) :
|
||||||
|
5381;
|
||||||
|
}
|
||||||
|
|
||||||
bool check_uniform_uniqueness();
|
bool check_uniform_uniqueness();
|
||||||
|
|
||||||
enum class kShaderUniform : uint16_t
|
enum class kShaderUniform : uint16_t
|
||||||
{
|
{
|
||||||
MVP = const_hash("mvp"),
|
MVP = shader_const_hash("mvp"),
|
||||||
Tex = const_hash("tex"),
|
Tex = shader_const_hash("tex"),
|
||||||
TexFG = const_hash("tex_fg"),
|
TexFG = shader_const_hash("tex_fg"),
|
||||||
TexBG = const_hash("tex_bg"),
|
TexBG = shader_const_hash("tex_bg"),
|
||||||
TexMix = const_hash("tex_mix"),
|
TexMix = shader_const_hash("tex_mix"),
|
||||||
TexMixA = const_hash("tex_mix_alpha"),
|
TexMixA = shader_const_hash("tex_mix_alpha"),
|
||||||
TexMask = const_hash("tex_mask"),
|
TexMask = shader_const_hash("tex_mask"),
|
||||||
TexDual = const_hash("tex_dual"),
|
TexDual = shader_const_hash("tex_dual"),
|
||||||
TexStroke = const_hash("tex_stroke"),
|
TexStroke = shader_const_hash("tex_stroke"),
|
||||||
TexPattern = const_hash("tex_pattern"),
|
TexPattern = shader_const_hash("tex_pattern"),
|
||||||
PatternOffset = const_hash("pattern_offset"),
|
PatternOffset = shader_const_hash("pattern_offset"),
|
||||||
PatternAlpha = const_hash("pattern_alpha"),
|
PatternAlpha = shader_const_hash("pattern_alpha"),
|
||||||
MixAlpha = const_hash("mix_alpha"),
|
MixAlpha = shader_const_hash("mix_alpha"),
|
||||||
Opacity = const_hash("opacity"),
|
Opacity = shader_const_hash("opacity"),
|
||||||
Wet = const_hash("wet"),
|
Wet = shader_const_hash("wet"),
|
||||||
Lock = const_hash("lock"),
|
Lock = shader_const_hash("lock"),
|
||||||
Col = const_hash("col"),
|
Col = shader_const_hash("col"),
|
||||||
Tof = const_hash("tof"),
|
Tof = shader_const_hash("tof"),
|
||||||
Tsz = const_hash("tsz"),
|
Tsz = shader_const_hash("tsz"),
|
||||||
Alpha = const_hash("alpha"),
|
Alpha = shader_const_hash("alpha"),
|
||||||
Mask = const_hash("mask"),
|
Mask = shader_const_hash("mask"),
|
||||||
Resolution = const_hash("resolution"),
|
Resolution = shader_const_hash("resolution"),
|
||||||
Highlight = const_hash("highlight"),
|
Highlight = shader_const_hash("highlight"),
|
||||||
BlendMode = const_hash("blend_mode"),
|
BlendMode = shader_const_hash("blend_mode"),
|
||||||
DualBlendMode = const_hash("dual_blend_mode"),
|
DualBlendMode = shader_const_hash("dual_blend_mode"),
|
||||||
Noise = const_hash("noise"),
|
Noise = shader_const_hash("noise"),
|
||||||
Direction = const_hash("dir"),
|
Direction = shader_const_hash("dir"),
|
||||||
UseDual = const_hash("use_dual"),
|
UseDual = shader_const_hash("use_dual"),
|
||||||
UsePattern = const_hash("use_pattern"),
|
UsePattern = shader_const_hash("use_pattern"),
|
||||||
LightDir = const_hash("light_dir"),
|
LightDir = shader_const_hash("light_dir"),
|
||||||
Mode = const_hash("mode"),
|
Mode = shader_const_hash("mode"),
|
||||||
Ambient = const_hash("ambient"),
|
Ambient = shader_const_hash("ambient"),
|
||||||
PatternInvert = const_hash("pattern_invert"),
|
PatternInvert = shader_const_hash("pattern_invert"),
|
||||||
PatternScale = const_hash("pattern_scale"),
|
PatternScale = shader_const_hash("pattern_scale"),
|
||||||
PatternBright = const_hash("pattern_bright"),
|
PatternBright = shader_const_hash("pattern_bright"),
|
||||||
PatternContrast = const_hash("pattern_contr"),
|
PatternContrast = shader_const_hash("pattern_contr"),
|
||||||
PatternDepth = const_hash("pattern_depth"),
|
PatternDepth = shader_const_hash("pattern_depth"),
|
||||||
PatternBlendMode = const_hash("patt_blend_mode"),
|
PatternBlendMode = shader_const_hash("patt_blend_mode"),
|
||||||
Colorize = const_hash("colorize"),
|
Colorize = shader_const_hash("colorize"),
|
||||||
DualAlpha = const_hash("dual_alpha"),
|
DualAlpha = shader_const_hash("dual_alpha"),
|
||||||
UseFragcoord = const_hash("use_fragcoord"),
|
UseFragcoord = shader_const_hash("use_fragcoord"),
|
||||||
DrawOutline = const_hash("draw_outline"),
|
DrawOutline = shader_const_hash("draw_outline"),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class kShader : uint16_t
|
enum class kShader : uint16_t
|
||||||
{
|
{
|
||||||
Color = const_hash("color"),
|
Color = shader_const_hash("color"),
|
||||||
ColorQuad = const_hash("color-quad"),
|
ColorQuad = shader_const_hash("color-quad"),
|
||||||
ColorTri = const_hash("color-tri"),
|
ColorTri = shader_const_hash("color-tri"),
|
||||||
ColorHue = const_hash("color-hue"),
|
ColorHue = shader_const_hash("color-hue"),
|
||||||
Texture = const_hash("texture"),
|
Texture = shader_const_hash("texture"),
|
||||||
TextureMask = const_hash("texture-mask"),
|
TextureMask = shader_const_hash("texture-mask"),
|
||||||
TextureColorize = const_hash("texture-colorize"),
|
TextureColorize = shader_const_hash("texture-colorize"),
|
||||||
TextureAlpha= const_hash("texture-alpha"),
|
TextureAlpha= shader_const_hash("texture-alpha"),
|
||||||
TextureBlend= const_hash("texture-blend"),
|
TextureBlend= shader_const_hash("texture-blend"),
|
||||||
CompErase = const_hash("comp-erase"),
|
CompErase = shader_const_hash("comp-erase"),
|
||||||
CompDraw = const_hash("comp-draw"),
|
CompDraw = shader_const_hash("comp-draw"),
|
||||||
UVs = const_hash("uvs"),
|
UVs = shader_const_hash("uvs"),
|
||||||
UVs_2 = const_hash("uvs2"),
|
UVs_2 = shader_const_hash("uvs2"),
|
||||||
Font = const_hash("font"),
|
Font = shader_const_hash("font"),
|
||||||
Atlas = const_hash("atlas"),
|
Atlas = shader_const_hash("atlas"),
|
||||||
Stroke = const_hash("stroke"),
|
Stroke = shader_const_hash("stroke"),
|
||||||
StrokePad = const_hash("stroke-pad"),
|
StrokePad = shader_const_hash("stroke-pad"),
|
||||||
StrokeDilate= const_hash("stroke-dilate"),
|
StrokeDilate= shader_const_hash("stroke-dilate"),
|
||||||
StrokePreview = const_hash("stroke-preview"),
|
StrokePreview = shader_const_hash("stroke-preview"),
|
||||||
Checkerboard= const_hash("checkerboard"),
|
Checkerboard= shader_const_hash("checkerboard"),
|
||||||
Equirect = const_hash("equirect"),
|
Equirect = shader_const_hash("equirect"),
|
||||||
BrushStroke = const_hash("brush-stroke"),
|
BrushStroke = shader_const_hash("brush-stroke"),
|
||||||
VertexColor = const_hash("vertex-color"),
|
VertexColor = shader_const_hash("vertex-color"),
|
||||||
Lambert = const_hash("lambert"),
|
Lambert = shader_const_hash("lambert"),
|
||||||
LambertLightmap = const_hash("lambert-lightmap"),
|
LambertLightmap = shader_const_hash("lambert-lightmap"),
|
||||||
BakeUV = const_hash("bakeuv"),
|
BakeUV = shader_const_hash("bakeuv"),
|
||||||
};
|
};
|
||||||
|
|
||||||
class Shader
|
class Shader
|
||||||
{
|
{
|
||||||
std::map<std::string, struct stat> m_deps;
|
std::map<std::string, struct stat> m_deps;
|
||||||
std::string m_path;
|
std::string m_path;
|
||||||
std::map<kShaderUniform, GLuint> m_umap;
|
std::map<kShaderUniform, unsigned int> m_umap;
|
||||||
GLuint prog;
|
unsigned int prog;
|
||||||
std::string read(const std::string& path);
|
std::string read(const std::string& path);
|
||||||
public:
|
public:
|
||||||
kShader name;
|
kShader name;
|
||||||
@@ -102,7 +115,7 @@ public:
|
|||||||
void u_int(kShaderUniform id, int i);
|
void u_int(kShaderUniform id, int i);
|
||||||
void u_int(const char* uniform_name, int i);
|
void u_int(const char* uniform_name, int i);
|
||||||
void u_float(kShaderUniform id, float f);
|
void u_float(kShaderUniform id, float f);
|
||||||
GLint GetAttribLocation(const char* attribute_name);
|
int GetAttribLocation(const char* attribute_name);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShaderManager
|
class ShaderManager
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <deque>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define GL(stmt) stmt; check_OpenGLError(#stmt, __FILE__, __LINE__);
|
#define GL(stmt) stmt; check_OpenGLError(#stmt, __FILE__, __LINE__);
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -2514,6 +2514,77 @@ void legacy_node_stroke_preview_stroke_setup_plan_preserves_curve_and_dual_input
|
|||||||
PP_EXPECT(h, pressure_fallback.points.empty());
|
PP_EXPECT(h, pressure_fallback.points.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void legacy_node_stroke_preview_pass_orchestration_plan_preserves_feedback_material_and_composite_inputs(
|
||||||
|
pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
const auto plan = pp::panopainter::plan_legacy_node_stroke_preview_pass_orchestration(
|
||||||
|
pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationRequest {
|
||||||
|
.features = RenderDeviceFeatures { .framebuffer_fetch = false },
|
||||||
|
.preview_size = glm::vec2(96.0F, 48.0F),
|
||||||
|
.pattern_scale = 0.75F,
|
||||||
|
.pattern_flipx = true,
|
||||||
|
.pattern_flipy = false,
|
||||||
|
.pattern_invert = true,
|
||||||
|
.pattern_brightness = 0.2F,
|
||||||
|
.pattern_contrast = 0.3F,
|
||||||
|
.pattern_depth = 0.4F,
|
||||||
|
.pattern_rand_offset = true,
|
||||||
|
.pattern_enabled = true,
|
||||||
|
.pattern_eachsample = false,
|
||||||
|
.tip_mix = 0.5F,
|
||||||
|
.tip_wet = 0.25F,
|
||||||
|
.tip_noise = 0.1F,
|
||||||
|
.dual_enabled = true,
|
||||||
|
.dual_blend_mode = 2,
|
||||||
|
.dual_opacity = 0.6F,
|
||||||
|
.pattern_blend_mode = 3,
|
||||||
|
.blend_mode = 4,
|
||||||
|
.mvp = glm::ortho(-2.0F, 2.0F, -1.0F, 1.0F),
|
||||||
|
});
|
||||||
|
|
||||||
|
PP_EXPECT(h, plan.feedback.compatibility_fallback);
|
||||||
|
PP_EXPECT(h, !plan.feedback.reads_destination_color);
|
||||||
|
PP_EXPECT(h, plan.copy_stroke_destination);
|
||||||
|
PP_EXPECT(h, plan.background_colorize);
|
||||||
|
|
||||||
|
PP_EXPECT(h, plan.material.stroke_pass.uses_destination_feedback);
|
||||||
|
PP_EXPECT(h, plan.material.composite_pass.use_dual);
|
||||||
|
PP_EXPECT(h, plan.material.composite_pass.use_pattern);
|
||||||
|
PP_EXPECT(h, plan.material.composite_pass.pattern_blend_mode == 3);
|
||||||
|
PP_EXPECT(h, plan.material.composite_pass.dual_blend_mode == 2);
|
||||||
|
PP_EXPECT(h, near(plan.material.composite_pass.dual_alpha, 0.6F));
|
||||||
|
|
||||||
|
PP_EXPECT(h, plan.composite.uses_mixer);
|
||||||
|
PP_EXPECT(h, plan.composite.uses_dual == plan.material.composite_pass.use_dual);
|
||||||
|
PP_EXPECT(h, plan.composite.uses_pattern == plan.material.composite_pass.use_pattern);
|
||||||
|
const std::size_t expected_texture_slots =
|
||||||
|
2U +
|
||||||
|
(plan.composite.uses_dual ? 1U : 0U) +
|
||||||
|
(plan.composite.uses_pattern ? 1U : 0U) +
|
||||||
|
(plan.composite.uses_mixer ? 1U : 0U);
|
||||||
|
PP_EXPECT(h, plan.composite.texture_slot_count == expected_texture_slots);
|
||||||
|
PP_EXPECT(h, has_preview_texture_slot(plan.composite, StrokePreviewTextureRole::background, 0));
|
||||||
|
PP_EXPECT(h, has_preview_texture_slot(plan.composite, StrokePreviewTextureRole::stroke, 1));
|
||||||
|
PP_EXPECT(h, has_preview_texture_slot(plan.composite, StrokePreviewTextureRole::dual, 3));
|
||||||
|
PP_EXPECT(h, has_preview_texture_slot(plan.composite, StrokePreviewTextureRole::mixer, 3));
|
||||||
|
PP_EXPECT(h, has_preview_texture_slot(plan.composite, StrokePreviewTextureRole::pattern, 4));
|
||||||
|
|
||||||
|
PP_EXPECT(h, near(plan.stroke_shader.resolution, glm::vec2(96.0F, 48.0F)));
|
||||||
|
PP_EXPECT(h, near(plan.stroke_shader.pattern.scale, glm::vec2(-0.75F, 0.75F)));
|
||||||
|
PP_EXPECT(h, near(plan.stroke_shader.pattern.invert, 1.0F));
|
||||||
|
PP_EXPECT(h, near(plan.stroke_shader.pattern.brightness, 0.2F));
|
||||||
|
PP_EXPECT(h, near(plan.stroke_shader.pattern.contrast, 0.3F));
|
||||||
|
PP_EXPECT(h, near(plan.stroke_shader.pattern.depth, 0.4F));
|
||||||
|
PP_EXPECT(h, plan.stroke_shader.pattern.blend_mode == 3);
|
||||||
|
PP_EXPECT(h, near(plan.stroke_shader.pattern.offset, glm::vec2(0.5F, 0.5F)));
|
||||||
|
PP_EXPECT(h, plan.stroke_shader.uses_destination_feedback);
|
||||||
|
PP_EXPECT(h, !plan.stroke_shader.uses_pattern);
|
||||||
|
PP_EXPECT(h, !plan.stroke_shader.set_opacity);
|
||||||
|
PP_EXPECT(h, near(plan.stroke_shader.mix_alpha, 0.0F));
|
||||||
|
PP_EXPECT(h, near(plan.stroke_shader.wet, 0.0F));
|
||||||
|
PP_EXPECT(h, near(plan.stroke_shader.noise, 0.0F));
|
||||||
|
}
|
||||||
|
|
||||||
void plans_canvas_blend_gate_from_persisted_indices(pp::tests::Harness& h)
|
void plans_canvas_blend_gate_from_persisted_indices(pp::tests::Harness& h)
|
||||||
{
|
{
|
||||||
const std::vector<int> normal_layers { 0, 0, 0 };
|
const std::vector<int> normal_layers { 0, 0, 0 };
|
||||||
@@ -2977,6 +3048,9 @@ int main()
|
|||||||
harness.run(
|
harness.run(
|
||||||
"legacy_node_stroke_preview_stroke_setup_plan_preserves_curve_and_dual_inputs",
|
"legacy_node_stroke_preview_stroke_setup_plan_preserves_curve_and_dual_inputs",
|
||||||
legacy_node_stroke_preview_stroke_setup_plan_preserves_curve_and_dual_inputs);
|
legacy_node_stroke_preview_stroke_setup_plan_preserves_curve_and_dual_inputs);
|
||||||
|
harness.run(
|
||||||
|
"legacy_node_stroke_preview_pass_orchestration_plan_preserves_feedback_material_and_composite_inputs",
|
||||||
|
legacy_node_stroke_preview_pass_orchestration_plan_preserves_feedback_material_and_composite_inputs);
|
||||||
harness.run("plans_canvas_blend_gate_from_persisted_indices", plans_canvas_blend_gate_from_persisted_indices);
|
harness.run("plans_canvas_blend_gate_from_persisted_indices", plans_canvas_blend_gate_from_persisted_indices);
|
||||||
harness.run("canvas_blend_gate_preserves_legacy_fallbacks", canvas_blend_gate_preserves_legacy_fallbacks);
|
harness.run("canvas_blend_gate_preserves_legacy_fallbacks", canvas_blend_gate_preserves_legacy_fallbacks);
|
||||||
harness.run("plans_canvas_stroke_feedback_paths", plans_canvas_stroke_feedback_paths);
|
harness.run("plans_canvas_stroke_feedback_paths", plans_canvas_stroke_feedback_paths);
|
||||||
|
|||||||
Reference in New Issue
Block a user