1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/viz/common/frame_sinks/copy_output_util.h"
#include <stdint.h>
#include <string>
#include "base/check_op.h"
#include "base/strings/stringprintf.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
namespace viz {
namespace copy_output {
namespace {
// Returns the same values as std::ceil(t * numerator / denominator), but
// without introducing floating-point math and using 64-bit integer ops to avoid
// overflow.
int64_t CeilScale(int32_t t, int32_t numerator, int32_t denominator) {
int64_t x = static_cast<int64_t>(t) * numerator;
if (x > 0)
x += denominator - 1;
return x / denominator;
}
// Returns the same values as std::floor(t * numerator / denominator), but
// without introducing floating-point math and using 64-bit integer ops to avoid
// overflow.
int64_t FloorScale(int32_t t, int32_t numerator, int32_t denominator) {
if (t < 0)
return -CeilScale(-t, numerator, denominator);
return (static_cast<int64_t>(t) * numerator) / denominator;
}
} // namespace
std::string RenderPassGeometry::ToString() const {
return base::StringPrintf(
"sampling_bounds: %s, result_bounds: %s, result_selection: %s, "
"readback_offset: %s",
sampling_bounds.ToString().c_str(), result_bounds.ToString().c_str(),
result_selection.ToString().c_str(), readback_offset.ToString().c_str());
}
gfx::Rect ComputeResultRect(const gfx::Rect& area,
const gfx::Vector2d& scale_from,
const gfx::Vector2d& scale_to) {
DCHECK_GT(scale_from.x(), 0);
DCHECK_GT(scale_from.y(), 0);
DCHECK_GE(scale_to.x(), 0);
DCHECK_GE(scale_to.y(), 0);
const int64_t x = FloorScale(area.x(), scale_to.x(), scale_from.x());
const int64_t y = FloorScale(area.y(), scale_to.y(), scale_from.y());
const int64_t w =
area.width() == 0
? 0
: (CeilScale(area.right(), scale_to.x(), scale_from.x()) - x);
const int64_t h =
area.height() == 0
? 0
: (CeilScale(area.bottom(), scale_to.y(), scale_from.y()) - y);
// These constants define the "reasonable" range of result Rect coordinates.
constexpr int kMaxOriginOffset = (1 << 24) - 1; // Arbitrary, but practical.
constexpr int kMaxDimension = (1 << 15) - 1; // From media/base/limits.h.
// If the result Rect is not "safely reasonable," return an empty Rect instead
// to indicate to the client that scaling should not be attempted.
if (x < -kMaxOriginOffset || x > kMaxOriginOffset || y < -kMaxOriginOffset ||
y > kMaxOriginOffset || w <= 0 || w > kMaxDimension || h <= 0 ||
h > kMaxDimension) {
return gfx::Rect();
}
return gfx::Rect(static_cast<int>(x), static_cast<int>(y),
static_cast<int>(w), static_cast<int>(h));
}
RenderPassGeometry::RenderPassGeometry() = default;
RenderPassGeometry::~RenderPassGeometry() = default;
} // namespace copy_output
} // namespace viz
|