#ifndef _TCUPIXELFORMAT_HPP #define _TCUPIXELFORMAT_HPP /*------------------------------------------------------------------------- * drawElements Quality Program Tester Core * ---------------------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Pixel format descriptor. *//*--------------------------------------------------------------------*/ #include "tcuDefs.hpp" #include "tcuRGBA.hpp" namespace tcu { /*--------------------------------------------------------------------*//*! * \brief Fixed-point render target pixel format *//*--------------------------------------------------------------------*/ struct PixelFormat { int redBits; int greenBits; int blueBits; int alphaBits; PixelFormat (int red, int green, int blue, int alpha) : redBits(red) , greenBits(green) , blueBits(blue) , alphaBits(alpha) { } PixelFormat (void) : redBits(0) , greenBits(0) , blueBits(0) , alphaBits(0) { } static inline int channelThreshold(int bits) { if (bits <= 8) { // Threshold is 2^(8 - bits) return 1 << (8 - bits); } else { // Threshold is bound by the 8-bit buffer value return 1; } } /*--------------------------------------------------------------------*//*! * \brief Get default threshold for per-pixel comparison for this format * * Per-channel threshold is 2^(8-bits). If alpha channel bits are zero, * threshold for that channel is 0. *//*--------------------------------------------------------------------*/ inline RGBA getColorThreshold (void) const { return RGBA( channelThreshold(redBits), channelThreshold(greenBits), channelThreshold(blueBits), alphaBits ? channelThreshold(alphaBits) : 0); } static inline int convertChannel (int val, int bits) { if (bits == 0) { return 0; } else if (bits == 1) { return (val & 0x80) ? 0xff : 0; } else if (bits < 8) { // Emulate precision reduction by replicating the upper bits as the fractional component int intComp = val >> (8 - bits); int fractComp = (intComp << (24 - bits)) | (intComp << (24 - 2 * bits)) | (intComp << (24 - 3 * bits)); return (intComp << (8 - bits)) | (fractComp >> (bits + 16)); } else { // Bits greater than or equal to 8 will have full precision, so no reduction return val; } } /*--------------------------------------------------------------------*//*! * \brief Emulate reduced bit depth * * The color value bit depth is reduced and converted back. The lowest * bits are filled by replicating the upper bits. *//*--------------------------------------------------------------------*/ inline RGBA convertColor (const RGBA& col) const { return RGBA(convertChannel(col.getRed(), redBits), convertChannel(col.getGreen(), greenBits), convertChannel(col.getBlue(), blueBits), alphaBits ? convertChannel(col.getAlpha(), alphaBits) : 0xff); } inline bool operator== (const PixelFormat& other) const { return redBits == other.redBits && greenBits == other.greenBits && blueBits == other.blueBits && alphaBits == other.alphaBits; } inline bool operator!= (const PixelFormat& other) const { return !(*this == other); } } DE_WARN_UNUSED_TYPE; } // namespace tcu #endif // _TCUPIXELFORMAT_HPP