// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "cc/tiles/mipmap_util.h" namespace cc { namespace { // Calculates the size of |axis_base_size| at the given |mip_level| using // OpenGL rounding rules. int ScaleAxisToMipLevel(int axis_base_size, int mip_level) { DCHECK_GE(mip_level, 0); DCHECK_LT(mip_level, 32); return std::max(1, axis_base_size >> mip_level); } } // namespace int MipMapUtil::GetLevelForSize(const gfx::Size& src_size, const gfx::Size& target_size) { int src_height = src_size.height(); int src_width = src_size.width(); int target_height = target_size.height(); int target_width = target_size.width(); DCHECK_GT(target_height, 0); DCHECK_GT(target_width, 0); DCHECK_GT(src_width, 0); DCHECK_GT(src_height, 0); int next_mip_height = src_height; int next_mip_width = src_width; for (int current_mip_level = 0;; current_mip_level++) { int mip_height = next_mip_height; int mip_width = next_mip_width; next_mip_height = ScaleAxisToMipLevel(src_height, current_mip_level + 1); next_mip_width = ScaleAxisToMipLevel(src_width, current_mip_level + 1); // Check if an axis on the next mip level would be smaller than the target. // If so, use the current mip level. // This effectively always uses the larger image and always scales down. if (next_mip_height < target_height || next_mip_width < target_width) { return current_mip_level; } if (mip_height == 1 && mip_width == 1) { // We have reached the final mip level return current_mip_level; } } } SkSize MipMapUtil::GetScaleAdjustmentForLevel(const gfx::Size& src_size, int mip_level) { DCHECK_GT(src_size.width(), 0); DCHECK_GT(src_size.height(), 0); DCHECK_GE(mip_level, 0); gfx::Size target_size = GetSizeForLevel(src_size, mip_level); return SkSize::Make( static_cast(target_size.width()) / src_size.width(), static_cast(target_size.height()) / src_size.height()); } gfx::Size MipMapUtil::GetSizeForLevel(const gfx::Size& src_size, int mip_level) { DCHECK_GT(src_size.width(), 0); DCHECK_GT(src_size.height(), 0); DCHECK_GE(mip_level, 0); return gfx::Size(ScaleAxisToMipLevel(src_size.width(), mip_level), ScaleAxisToMipLevel(src_size.height(), mip_level)); } SkSize MipMapUtil::GetScaleAdjustmentForSize(const gfx::Size& src_size, const gfx::Size& target_size) { int target_mip_level = GetLevelForSize(src_size, target_size); return GetScaleAdjustmentForLevel(src_size, target_mip_level); } } // namespace cc