1// Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
2// Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "renderstateset_p.h"
6
7#include <bitset>
8
9#include <Qt3DRender/private/renderstates_p.h>
10#include <Qt3DRender/private/qrenderstate_p.h>
11
12QT_BEGIN_NAMESPACE
13
14namespace Qt3DRender {
15namespace Render {
16
17RenderStateSet::RenderStateSet()
18 : m_stateMask(0)
19{
20}
21
22RenderStateSet::~RenderStateSet()
23{
24}
25
26template<>
27void RenderStateSet::addState<StateVariant>(const StateVariant &ds)
28{
29 m_states.push_back(x: ds);
30 m_stateMask |= ds.type;
31}
32
33int RenderStateSet::changeCost(RenderStateSet *previousState)
34{
35 if (previousState == this)
36 return 0;
37
38 int cost = 0;
39
40 // first, find cost of any resets
41 StateMaskSet invOurState = ~stateMask();
42 StateMaskSet stateToReset = previousState->stateMask() & invOurState;
43
44 std::bitset<64> bs(stateToReset);
45 cost += int(bs.count());
46
47 // now, find out how many states we're changing
48 for (const StateVariant &ds : std::as_const(t&: m_states)) {
49 // if the other state contains matching, then doesn't
50 // contribute to cost at all
51 if (previousState->contains(ds))
52 continue;
53
54 // flat cost for now; could be replaced with a cost() method on
55 // RenderState
56 cost += 2;
57 }
58
59 return cost;
60}
61
62StateMaskSet RenderStateSet::stateMask() const
63{
64 return m_stateMask;
65}
66
67// This modifies our state to add states from others
68// if we don't already contain a state with that type set
69void RenderStateSet::merge(const RenderStateSet *other)
70{
71 const std::vector<StateVariant> &otherStates = other->states();
72
73 // We only add states which are new (different type)
74 for (const StateVariant &otherState : otherStates) {
75 const bool canAdd = canAddStateOfType(type: otherState.type);
76 if (canAdd)
77 m_states.push_back(x: otherState);
78 }
79 m_stateMask |= other->stateMask();
80}
81
82bool RenderStateSet::canAddStateOfType(StateMask type) const
83{
84 return !hasStateOfType(type) || allowMultipleStatesOfType(type);
85}
86
87bool RenderStateSet::hasStateOfType(StateMask type) const
88{
89 return (type & stateMask());
90}
91
92bool RenderStateSet::allowMultipleStatesOfType(StateMask type) const
93{
94 return (type == BlendEquationArgumentsMask) ||
95 (type == ClipPlaneMask);
96}
97
98bool RenderStateSet::contains(const StateVariant &ds) const
99{
100 // trivial reject using the state mask bits
101 if (!(ds.type & stateMask()))
102 return false;
103
104 for (const StateVariant &rs : m_states) {
105 if (rs == ds)
106 return true;
107 }
108 return false;
109}
110
111} // namespace Render
112} // namespace Qt3DRender
113
114QT_END_NAMESPACE
115

source code of qt3d/src/render/renderstates/renderstateset.cpp