Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1b0b011 authored by Yiwei Zhang's avatar Yiwei Zhang
Browse files

vkjson: correctly handle std::numeric_limits<float>::infinity()

Java JSON library can't handle infinity value. So if vkjson reports infinity
limit, we need to manually clamp the value within the Java JSON value range.
Up-casting float infinity will be equal to double infinity, and we need to make
sure the text representation is not going out of range between the cppjson to
Java json converison, so we have to clamp to a safe min/max range of double.

Bug: 134453786
Test: adb shell cmd gpu vkjson
Change-Id: I498fbcdb76ec55d6443ca202af191d6fb12fec12
parent 42e353bc
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -21,11 +21,14 @@
#include "vkjson.h"

#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>

#include <cmath>
#include <json/json.h>

#include <algorithm>
#include <cinttypes>
#include <cmath>
#include <cstdio>
#include <limits>
#include <memory>
@@ -33,8 +36,6 @@
#include <type_traits>
#include <utility>

#include <json/json.h>

namespace {

inline bool IsIntegral(double value) {
@@ -46,6 +47,14 @@ inline bool IsIntegral(double value) {
#endif
}

// Floating point fields of Vulkan structure use single precision. The string
// output of max double value in c++ will be larger than Java double's infinity
// value. Below fake double max/min values are only to serve the safe json text
// parsing in between C++ and Java, becasue Java json library simply cannot
// handle infinity.
static const double SAFE_DOUBLE_MAX = 0.99 * std::numeric_limits<double>::max();
static const double SAFE_DOUBLE_MIN = 0.99 * std::numeric_limits<double>::min();

template <typename T> struct EnumTraits;
template <> struct EnumTraits<VkPhysicalDeviceType> {
  static uint32_t min() { return VK_PHYSICAL_DEVICE_TYPE_BEGIN_RANGE; }
@@ -851,7 +860,8 @@ Json::Value ToJsonValue(const T& value);

template <typename T, typename = EnableForArithmetic<T>>
inline Json::Value ToJsonValue(const T& value) {
  return Json::Value(static_cast<double>(value));
  return Json::Value(
      std::clamp(static_cast<double>(value), SAFE_DOUBLE_MIN, SAFE_DOUBLE_MAX));
}

inline Json::Value ToJsonValue(const uint64_t& value) {