mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-22 07:01:30 +00:00
177 lines
5.3 KiB
C++
177 lines
5.3 KiB
C++
/**
|
|
* Looking Glass
|
|
* Copyright © 2017-2026 The Looking Glass Authors
|
|
* https://looking-glass.io
|
|
*
|
|
* This program 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.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
|
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "postprocess/D12FrameFormat.h"
|
|
#include "transport/FrameProfile.h"
|
|
#include "transport/TransportConfig.h"
|
|
|
|
#include <Windows.h>
|
|
#include <limits.h>
|
|
#include <stdint.h>
|
|
|
|
static const unsigned FRAME_DAMAGE_MAX = 256;
|
|
static const unsigned FRAME_GRAPH_ROOT = UINT_MAX;
|
|
static const unsigned FRAME_GRAPH_MAX_NODES =
|
|
1 + 5 * TRANSPORT_MAX_INSTANCES;
|
|
|
|
enum class FrameOp : uint8_t
|
|
{
|
|
SRC,
|
|
CAL,
|
|
LUT,
|
|
SCALE,
|
|
SDR,
|
|
SCRGB,
|
|
HDR10,
|
|
};
|
|
|
|
enum class FrameDamage : uint8_t
|
|
{
|
|
NONE,
|
|
RECTS,
|
|
FULL,
|
|
};
|
|
|
|
struct GraphCfg
|
|
{
|
|
GpuMode mode = GpuMode::HARDWARE;
|
|
LUID adapter = {};
|
|
unsigned srcWidth = 0;
|
|
unsigned srcHeight = 0;
|
|
FrameProfile src;
|
|
std::shared_ptr<const D12ColorTransform> transform;
|
|
unsigned width = 0;
|
|
unsigned height = 0;
|
|
FrameProfile checkpoint;
|
|
};
|
|
|
|
namespace Frame
|
|
{
|
|
bool Same(const GraphCfg& left, const GraphCfg& right);
|
|
bool Valid(FrameDamage damage, const RECT * rects, unsigned count,
|
|
unsigned width, unsigned height);
|
|
}
|
|
|
|
struct GraphNode
|
|
{
|
|
FrameOp op = FrameOp::SRC;
|
|
unsigned parent = FRAME_GRAPH_ROOT;
|
|
// refs covers every route; texRefs is the direct texture-route closure.
|
|
unsigned refs = 0;
|
|
unsigned texRefs = 0;
|
|
unsigned width = 0;
|
|
unsigned height = 0;
|
|
FrameProfile profile;
|
|
};
|
|
|
|
struct GraphLeaf
|
|
{
|
|
BackendId id = 0;
|
|
uint32_t epoch = 0;
|
|
unsigned node = 0;
|
|
bool required = false;
|
|
bool primary = false;
|
|
bool tex = false;
|
|
// Partial damage remains valid across the preceding graph generation.
|
|
bool continuous = false;
|
|
FrameCfg cfg;
|
|
};
|
|
|
|
// All products derived from one capture retain the same immutable content.
|
|
// It contains no acquired IddCx or Direct3D resource.
|
|
struct FrameContent
|
|
{
|
|
uint64_t serial = 0;
|
|
uint64_t captureTime = 0;
|
|
FrameDamage damage = FrameDamage::NONE;
|
|
RECT rects[FRAME_DAMAGE_MAX] = {};
|
|
unsigned count = 0;
|
|
D12FrameFormat format = {};
|
|
};
|
|
|
|
using FrameContentRef = std::shared_ptr<const FrameContent>;
|
|
|
|
// FrameDesc adds one graph node's representation and damage to the shared
|
|
// content identity. It remains resource-free.
|
|
struct FrameDesc
|
|
{
|
|
FrameContentRef content;
|
|
FrameDamage damage = FrameDamage::NONE;
|
|
RECT rects[FRAME_DAMAGE_MAX] = {};
|
|
unsigned count = 0;
|
|
D12FrameFormat format = {};
|
|
};
|
|
|
|
struct LeafDesc
|
|
{
|
|
BackendId id = 0;
|
|
uint32_t epoch = 0;
|
|
unsigned node = 0;
|
|
FrameProfile profile;
|
|
FrameDesc frame = {};
|
|
};
|
|
|
|
class CFrameGraph
|
|
{
|
|
private:
|
|
GraphCfg m_cfg;
|
|
GraphNode m_nodes[FRAME_GRAPH_MAX_NODES] = {};
|
|
GraphLeaf m_leaves[TRANSPORT_MAX_INSTANCES] = {};
|
|
uint64_t m_generation = 0;
|
|
unsigned m_nodeCount = 0;
|
|
unsigned m_leafCount = 0;
|
|
bool m_begun = false;
|
|
bool m_sealed = false;
|
|
|
|
unsigned Find(FrameOp op, unsigned parent, unsigned width, unsigned height,
|
|
const FrameProfile& profile) const;
|
|
unsigned AddNode(FrameOp op, unsigned parent, unsigned width,
|
|
unsigned height,
|
|
const FrameProfile& profile);
|
|
unsigned Checkpoint(const FrameProfile& profile);
|
|
|
|
public:
|
|
void Reset();
|
|
bool Begin(const GraphCfg& cfg);
|
|
bool Can(const FrameCfg& cfg) const;
|
|
bool Add(BackendId id, uint32_t epoch, bool required, bool primary,
|
|
bool tex, bool continuous, const FrameCfg& cfg);
|
|
bool Seal();
|
|
bool Stamp(uint64_t generation);
|
|
bool Ready() const { return m_sealed && m_generation; }
|
|
bool Same(const GraphCfg& cfg) const;
|
|
const GraphLeaf * FindLeaf(BackendId id, uint32_t epoch, bool tex,
|
|
const FrameCfg& frame) const;
|
|
bool Want(FrameSignal signal) const;
|
|
bool Need(FrameOp op) const;
|
|
bool Shared(unsigned node) const;
|
|
bool Desc(unsigned node, const FrameContentRef& content,
|
|
FrameDesc& desc) const;
|
|
bool Desc(unsigned leaf, const FrameContentRef& content,
|
|
LeafDesc& desc) const;
|
|
|
|
const GraphCfg& Cfg() const { return m_cfg; }
|
|
uint64_t Generation() const { return Ready() ? m_generation : 0; }
|
|
const GraphNode * Nodes(unsigned& count) const;
|
|
const GraphLeaf * Leaves(unsigned& count) const;
|
|
};
|