diff --git a/src/steam/engine/buffer-proxy-provider.cpp b/src/steam/engine/buffer-proxy-provider.cpp new file mode 100644 index 000000000..f26628109 --- /dev/null +++ b/src/steam/engine/buffer-proxy-provider.cpp @@ -0,0 +1,55 @@ +/* + BufferProxyProvider - Adapt existing allocation for access through the Buffer protocol + + Copyright (C) + 2024, Hermann Vosseler + +  **Lumiera** is free software; you can redistribute it and/or modify it +  under the terms of the GNU General Public License as published by the +  Free Software Foundation; either version 2 of the License, or (at your +  option) any later version. See the file COPYING for further details. + +* *****************************************************************/ + + +/** @file buffer-proxy-provider.cpp + ** Implementation details of a forwarding BufferProvider stub implementation. + */ + + +#include "lib/error.hpp" +#include "steam/engine/buffer-proxy-provider.hpp" +//#include "steam/engine/buffer-metadata.hpp" +//#include "lib/util.hpp" + +//using util::isSameAdr; + +namespace steam { +namespace engine { + + // storage for the default-marker constants +// const TypeHandler TypeHandler::RAW{}; + + + namespace { // impl. details and definitions + +// const uint DEFAULT_DESCRIPTOR = 0; + + } + + + /** build a new + */ +// BufferProvider::BufferProvider (Literal implementationID) +// : meta_(new BufferMetadata (implementationID)) +// { } +// +// BufferProvider::~BufferProvider() { } + + + /** @internal verify the given descriptor. + */ + + + +}} // namespace engine diff --git a/src/steam/engine/buffer-proxy-provider.hpp b/src/steam/engine/buffer-proxy-provider.hpp new file mode 100644 index 000000000..e74877c1b --- /dev/null +++ b/src/steam/engine/buffer-proxy-provider.hpp @@ -0,0 +1,86 @@ +/* + BUFFER-PROXY-PROVIDER.hpp - Adapter to access existing allocation via buffer handling protocol + + Copyright (C) + 2024, Hermann Vosseler + +  **Lumiera** is free software; you can redistribute it and/or modify it +  under the terms of the GNU General Public License as published by the +  Free Software Foundation; either version 2 of the License, or (at your +  option) any later version. See the file COPYING for further details. + +*/ + +/** @file buffer-proxy-provider.hpp + ** Adapter to expose a given memory block through a BuffHandle. + ** This allows to integrate a specific data access (e.g. related to input / output) + ** with the buffer lifecycle protocol as defined by BufferProvider. + ** @see state.hpp + ** @see output-slot.hpp + */ + +#ifndef STEAM_ENGINE_BUFFER_PROXY_PROVIDER_H +#define STEAM_ENGINE_BUFFER_PROXY_PROVIDER_H + + +#include "lib/error.hpp" +#include "lib/symbol.hpp" +#include "lib/meta/util.hpp" +//#include "lib/hash-value.h" +#include "steam/engine/buffer-provider.hpp" +#include "steam/engine/buffer-metadata.hpp" +//#include "steam/engine/engine-ctx.hpp" +//#include "steam/engine/type-handler.hpp" +//#include "steam/engine/buffer-local-tag.hpp" +#include "lib/nocopy.hpp" + +#include +#include +//#include + + +namespace steam { +namespace engine { + + using lib::Literal; +// using std::unique_ptr; +// using std::forward; + + + + + /** + * Adapter to expose access to data blocks via BuffHandle and the BufferProvider protocol. + * @todo WIP-WIP 12/2024 this is a design sketch to explore extension capabilities of BufferProvider + */ + class BufferProxyProvider + : util::MoveOnly + { + + std::function listener_; + + public: + template> + BufferProxyProvider (LIS&& listener) + : listener_{std::forward (listener)} + { } + + template + BuffHandle + lockBuffer (TAR& dataBlock) + { + UNIMPLEMENTED ("setup type handler and then create a locked BuffHandle"); + } + + }; + + + + + /* === Implementation === */ + + /** convenience shortcut: */ + + +}} // namespace steam::engine +#endif /*STEAM_ENGINE_BUFFER_PROXY_PROVIDER_H*/ diff --git a/src/steam/play/output-slot.hpp b/src/steam/play/output-slot.hpp index 70f129788..e1f10c447 100644 --- a/src/steam/play/output-slot.hpp +++ b/src/steam/play/output-slot.hpp @@ -43,7 +43,7 @@ ** Size and other characteristics of the data frames are assumed to be suitable, which typically ** won't be verified at that level anymore. Besides that, the allocation of an output slot reveals ** detailed timing expectations. The client is required to comply to these timings when _emitting_ - ** data -- he's even required to provide a current time specification, alongside with the data. + ** data -- they are even required to provide a current time specification, alongside with the data. ** Based on this information, the output slot has the ability to handle timing failures gracefully; ** the concrete output slot implementation is expected to provide some kind of de-click or ** de-flicker facility, which kicks in automatically when a timing failure is detected. @@ -118,7 +118,7 @@ namespace play { public: virtual ~OutputSlot(); - typedef lib::IterSource::iterator OpenedSinks; + using OpenedSinks = lib::IterSource::iterator; class Allocation { diff --git a/tests/47engine.tests b/tests/47engine.tests index 58420ba1b..40cb864df 100644 --- a/tests/47engine.tests +++ b/tests/47engine.tests @@ -17,12 +17,17 @@ return: 0 END -TEST "buffer metadata type keys" BufferMetadataKey_test < + +  **Lumiera** is free software; you can redistribute it and/or modify it +  under the terms of the GNU General Public License as published by the +  Free Software Foundation; either version 2 of the License, or (at your +  option) any later version. See the file COPYING for further details. + +* *****************************************************************/ + +/** @file output-proxy-provider-test.cpp + ** unit test \ref OutputProxyProvider_test + */ + + +#include "lib/test/run.hpp" + +//#include "steam/play/diagnostic-output-slot.hpp" +#include "steam/engine/buffer-proxy-provider.hpp" +#include "steam/engine/test-rand-ontology.hpp" + + + +namespace steam { +namespace engine{ +namespace test { + + + + + /***************************************************************//** + * @test verify the OutputSlot interface and base implementation + * by performing full data exchange cycle. This is a + * kind of "dry run" for documentation purposes, + * both the actual OutputSlot implementation + * as the client using this slot are Mocks. + */ + class OutputProxyProvider_test : public Test + { + virtual void + run (Arg) + { + size_t seenID{0}; + BufferState lastState{NIL}; + auto listener = [&](size_t id, BufferState state) + { + seenID = id; + lastState = state; + }; + // setup with notification callback + BufferProxyProvider proxPro{listener}; + + // Assuming some data block is »given« + seedRand(); + TestFrame::reseed(); + size_t frameNr = defaultGen.u64(); + TestFrame dataBlock (frameNr); + CHECK ( dataBlock.isPristine()); + + BuffHandle handle = proxPro.lockBuffer (dataBlock); + + // Now a »client« can do awful things to the buffer... + CHECK (handle.isValid()); + auto& data = handle.accessAs(); + uint64_t param = defaultGen.u64(); + manipulateFrame (&data, &data, param); + + // »client« is done... + handle.emit(); + + // end usage cycle + handle.release(); + CHECK (not handle.isValid()); + CHECK (not dataBlock.isPristine()); + CHECK ( dataBlock.isValid()); + } + }; + + + /** Register this test class... */ + LAUNCHER (OutputProxyProvider_test, "unit play"); + + + +}}} // namespace steam::play::test diff --git a/tests/core/steam/engine/node-builder-test.cpp b/tests/core/steam/engine/node-builder-test.cpp index 31a39ea78..13dc05dab 100644 --- a/tests/core/steam/engine/node-builder-test.cpp +++ b/tests/core/steam/engine/node-builder-test.cpp @@ -18,6 +18,7 @@ #include "lib/test/run.hpp" #include "steam/engine/node-builder.hpp" +#include "steam/engine/diagnostic-buffer-provider.hpp" //#include "lib/util.hpp" @@ -63,6 +64,12 @@ namespace test { CHECK (watch(node).isSrc()); CHECK (watch(node).ports().size() == 1); + + // Prepare setup to invoke such a Render Node... + using Buffer = long; + BufferProvider& provider = DiagnosticBufferProvider::build(); + BuffHandle buff = provider.lockBufferFor (-55); + } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index f25bfa8d6..6ab98ebf3 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -28165,9 +28165,7 @@ - - - +

Style-Klasse: .fork__bracket @@ -28798,9 +28796,7 @@ - - - +

steht in keinem Verhältnis zum Zweck @@ -29305,9 +29301,7 @@ - - - +

Renderer ist bereits der Funktor @@ -30342,9 +30336,7 @@ - - - +

  • @@ -31488,9 +31480,7 @@ - - - +

        for (uint i=0; i<pos; ++i) @@ -32208,9 +32198,7 @@ - - - +

    /home/hiv/.local/share/themes/PanRosewoodHIV/gtk-3.0/gtk-contained.css @@ -32808,9 +32796,7 @@ - - - +

    ...aber das wird sich ganz gewiß ändern ⟶ Stichwort Bereichsmarkierungen @@ -33578,9 +33564,7 @@ - - - +

    er wird von GTK eigentlich korrekt über die Nachbarbereiche darüber gezeichnet. @@ -88795,15 +88779,19 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    + + + + - + - + @@ -94449,6 +94437,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

    +
    @@ -94723,7 +94712,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - + + + @@ -94805,7 +94796,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - + + + + + +
    @@ -95300,7 +95296,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - + @@ -97826,7 +97822,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - + @@ -97851,6 +97847,346 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    + + + + + + + +

    + müßte doch im Prinzip bereits alles funktionieren.... +

    + +
    + + +
    + + + + + + + + + + + + +

    + brauche also nur noch ein BuffHandle hier +

    + + +
    + +
    +
    + + + + + + + + + + + + + + + + + + +

    + das würde mir eigentlich gefallen ⟹ packe ich diesen Schritt JETZT? +

    + + +
    + + + + + + + +

    + die müssen dann auch ins default Turnout-System +

    + +
    +
    + + + + + + + +

    + im Scheduler ist nur noch ein freier Slot übrig +

    + +
    +
    + + + + + + + + + + + + + + + + + + + +

    + Es gibt N Timelines. Für jede und für jedes Segment habe ich eine Exit-Node. +

    +

    + ⟹ Also ~ 2000 pro Timeline +

    +

    + Das multipliziert nochmal mit ~20 Ports (Video, Audio, R,G,B,α, Full-Screen, + Probe-Point(s), Audio-Subgruppe(n)...) +

    +

    + mit 8 Byte pro Pointer sind das ~ 1.5 MiB +

    + +
    +
    + + + + +

    + ...und zwar wegen den Subgruppen und Probe-Points, die eben keinesfalls beschränkt werden dürfen +

    + +
    +
    + + + + +

    + ...wegen der Concurrency, außerdem müßte dann dort ja auch wieder das cartesische Produkt gespeichert werden, denn es sind ja grade alle möglichen Ports möglich +

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    + das was alle „vernünftigen Leute“ sowiso machen — allerdings tun sie das nicht aus Vernunft, sondern aus Gedankenlosigkeit, weshalb das kein weiter relevanter Einwand ist +

    + +
    + +
    + + + + +

    + Also einen Post-Processing-Schritt, der die gleiche Ausführungs-Logik effizienter im Speicher codiert +

    +
      +
    • + Flyweight-Pattern zur Deduplikation anwenden +
    • +
    • + VTables o.ä. wo möglich durch Funktionspointer ersetzen +
    • +
    +

    + Das könnte ggfs. sogar eine automatische Transformation sein, auf Basis des jetzt definierten Node-Modells; man würde dann eine DAG ⟼ Tree -Transformation machen und dann die jeweilge ausführbare Node über ein Lambda-Binding über eine Prototyp-Node erzeugen. +

    + + +
    + +
    +
    +
    +
    +
    +
    + + + + + +

    + alles andere würde eine Art Kollaboration oder Protokoll implizieren +

    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    + Ich hatte schon angefangen, über der mögilchen Implementierung zu »brüten« und mich wieder in BufferProvider + OutputSlot eingelesen. Erst nach etwa einer Stunde ist mir aufgefallen, daß OutputSlot ja eine DataSink erzeugt, und daß diese bereits eine lockBufferFor(FrameID)-Funktion hat, die ein (TADAA!) BuffHandle liefert. Nicht wirklich überraschend, da ich ja beide Protokolle (Buffer Provider und Output Slot) kurze Zeit nacheinander entworfen habe. Daher konnte ich wohl damals auch einen Proof-of-Concept-Test ziemlich einfach „aus dem Ärmel schütteln“... +

    +

    + +

    +

    + Heute aber kommt mir dieser ganze Zusammenhang ziemlich »anrüchig« vor. Ich war inzwischen x-mal in der Analyse in die Falle gegangen, den BufferProvider mit dem Output-Management zu verwechseln — und dann immer wieder festgestellt, daß beide auf komplett andere Architektur-Ebenen gehören.... +

    +

    + +

    +

    + Deshalb möchte ich nun doch einmal aus-implementieren, was denn erforderlich wäre, einen frei-stehenden Buffer-Provider neu zu implementieren, welcher an einen dahinter liegenden OutputSlot delegiert.... +

    + + +
    + + + + + + + + +

    + weil die tatsächlich zu unterstützenden Operationen die BufferMetadata brauchen +

    + +
    +
    + + + + + +

    + Konsequenz ⟹ was der User bekommt, ist kein BufferProvider +

    + +
    +
    +
    + + + + + + + + + + + + +

    + ...und zwar schon längere Zeit bezüglich der Implementierung  des BufferProvider — das Konzept halte ich für sehr wichtig und auch gelngen. Aber immer wieder, wenn ich dann die Implementierung anschaue, dann springt man irgendwo zwischen dieser Default-Implementierung und dem TrackingHeapBlockProvider hin und her — und der ganze Code „riecht schief“, irgendwie (weiß aber nicht warum) ... Hinzu kommen Probleme (und, wie ich inzwischen weiß, tatsächliche Bugs) in der Typ-Registrierung, also BufferMetadata +

    + + +
    +
    + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + @@ -98610,8 +98946,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - - + + @@ -99738,6 +100074,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    + + + +