Photon Engine C API 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
api_helpers.ipp
Go to the documentation of this file.
1#pragma once
2
3#include "Api/api_helpers.h"
4
5#include <Common/assertion.h>
6#include <Common/memory.h>
7#include <Utility/ByteBuffer.h>
8#include <Core/Renderer/RenderRegionStatus.h>
9
10#include <type_traits>
11#include <memory>
12
13namespace ph
14{
15
16inline bool is_reversing_bytes_needed(PhEndian desiredEndianness)
17{
18 constexpr auto native = std::endian::native;
19
20 return
21 (native == std::endian::little && desiredEndianness == PhEndian::PH_BIG_ENDIAN) ||
22 (native == std::endian::big && desiredEndianness == PhEndian::PH_LITTLE_ENDIAN);
23}
24
25inline PhFrameRegionStatus to_frame_region_status(ERegionStatus regionStatus)
26{
27 switch(regionStatus)
28 {
29 case ERegionStatus::Finished:
31
32 case ERegionStatus::Updating:
34
35 default:
37 }
38}
39
40inline void to_frame_region_info(const RenderRegionStatus& regionStatus, PhFrameRegionInfo* out_regionInfo)
41{
42 PH_ASSERT(out_regionInfo);
43
44 const Region region = regionStatus.getRegion();
45 const ERegionStatus status = regionStatus.getStatus();
46
47 out_regionInfo->xPx = static_cast<PhUInt32>(region.getMinVertex().x());
48 out_regionInfo->yPx = static_cast<PhUInt32>(region.getMinVertex().y());
49 out_regionInfo->widthPx = static_cast<PhUInt32>(region.getWidth());
50 out_regionInfo->heightPx = static_cast<PhUInt32>(region.getHeight());
51 out_regionInfo->status = to_frame_region_status(status);
52}
53
54template<typename T>
55inline TSpan<T> make_array_from_buffer(
56 std::size_t numArrayElements,
57 ByteBuffer& buffer,
58 bool allowBufferGrowth)
59{
60 // To not violate [basic.life] section 8.3 later
61 // (https://timsong-cpp.github.io/cppwp/basic.life#8.3)
62 using NonConstT = std::remove_const_t<T>;
63
64 static_assert(std::is_default_constructible_v<NonConstT>);
65 static_assert(std::is_trivially_destructible_v<NonConstT>);
66
67 const auto alignmentInBytes = alignof(NonConstT);
68 const auto arraySizeInBytes = sizeof(NonConstT) * numArrayElements;
69
70 void* ptr = buffer.getBytes().data() + buffer.getWritePosition();
71 std::size_t availableBytes = buffer.numBytes() - buffer.getWritePosition();
72 void* alignedPtr = std::align(alignmentInBytes, arraySizeInBytes, ptr, availableBytes);
73
74 // Grow the buffer if allowed
75 if(!alignedPtr && allowBufferGrowth)
76 {
77 // Set to a size that the alignment should always work
78 buffer.setNumBytes(buffer.getWritePosition() + arraySizeInBytes + alignmentInBytes);
79
80 // Align again
81 ptr = buffer.getBytes().data() + buffer.getWritePosition();
82 availableBytes = buffer.numBytes() - buffer.getWritePosition();
83 alignedPtr = std::align(alignmentInBytes, arraySizeInBytes, ptr, availableBytes);
84
85 PH_ASSERT(alignedPtr);
86 }
87
88 // Return empty span if there is not enough space left
89 if(!alignedPtr)
90 {
91 return {};
92 }
93
94 PH_ASSERT(alignedPtr);
95
96 // We have a successfully aligned pointer here, update buffer states
97
98 // `std::align()` only adjusts `ptr` to the aligned memory location
99 std::byte* endPtr = static_cast<std::byte*>(ptr) + arraySizeInBytes;
100 buffer.setWritePosition(endPtr - buffer.getBytes().data());
101
102 // `std::align()` only decreases `availableBytes` by the number of bytes used for alignment
103 PH_ASSERT_GE(availableBytes, arraySizeInBytes);
104
105 // Prepare the array to return
106
107 // IOC of array of size `numArrayElements`
108 NonConstT* const storage = start_implicit_lifetime_as_array<NonConstT>(alignedPtr, arraySizeInBytes);
109
110 // Part of the contract of this function--default construct array elements
111 std::uninitialized_default_construct_n(storage, numArrayElements);
112
113 // Potentially do implicit non-const -> const conversion
114 return TSpan<NonConstT>(storage, numArrayElements);
115}
116
117}// end namespace ph
Definition api_helpers.cpp:8
PhFrameRegionStatus to_frame_region_status(ERegionStatus regionStatus)
Definition api_helpers.ipp:25
void to_frame_region_info(const RenderRegionStatus &regionStatus, PhFrameRegionInfo *out_regionInfo)
Definition api_helpers.ipp:40
bool is_reversing_bytes_needed(PhEndian desiredEndianness)
Definition api_helpers.ipp:16
TSpan< T > make_array_from_buffer(std::size_t numArrayElements, ByteBuffer &buffer, bool allowBufferGrowth=false)
Make an array of default constructed objects of type T.
Definition api_helpers.ipp:55
uint32_t PhUInt32
Definition ph_c_core_types.h:13
PhFrameRegionStatus
Definition ph_c_core_types.h:51
@ PH_FRAME_REGION_STATUS_FINISHED
Definition ph_c_core_types.h:53
@ PH_FRAME_REGION_STATUS_INVALID
Definition ph_c_core_types.h:52
@ PH_FRAME_REGION_STATUS_UPDATING
Definition ph_c_core_types.h:54
PhEndian
Indicates the endianness. This type is not for detecting endianness of the current platform,...
Definition ph_c_core_types.h:35
Definition ph_c_core_types.h:65
PhUInt32 yPx
Definition ph_c_core_types.h:67
PhFrameRegionStatus status
Definition ph_c_core_types.h:70
PhUInt32 xPx
Definition ph_c_core_types.h:66
PhUInt32 widthPx
Definition ph_c_core_types.h:68
PhUInt32 heightPx
Definition ph_c_core_types.h:69