diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-01 10:36:58 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-01 10:36:58 +0200 |
commit | b1e9e47fa11f608ae16bc07f97a2acf95bf80272 (patch) | |
tree | c88c45e80c9c44506e7cdf9a3bb39ebf82a8cd5b /Source/WebCore/platform | |
parent | be01689f43cf6882cf670d33df49ead1f570c53a (diff) | |
download | qtwebkit-b1e9e47fa11f608ae16bc07f97a2acf95bf80272.tar.gz |
Imported WebKit commit 499c84c99aa98e9870fa7eaa57db476c6d160d46 (http://svn.webkit.org/repository/webkit/trunk@119200)
Weekly update :). Particularly relevant changes for Qt are the use of the WebCore image decoders and direct usage
of libpng/libjpeg if available in the system.
Diffstat (limited to 'Source/WebCore/platform')
148 files changed, 3550 insertions, 1984 deletions
diff --git a/Source/WebCore/platform/Decimal.cpp b/Source/WebCore/platform/Decimal.cpp new file mode 100644 index 000000000..d2dd8329c --- /dev/null +++ b/Source/WebCore/platform/Decimal.cpp @@ -0,0 +1,1007 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Decimal.h" + +#include <algorithm> +#include <float.h> + +#include <wtf/Assertions.h> +#include <wtf/MathExtras.h> +#include <wtf/Noncopyable.h> +#include <wtf/text/StringBuilder.h> + +namespace WebCore { + +namespace DecimalPrivate { + +static int const ExponentMax = 1023; +static int const ExponentMin = -1023; +static int const Precision = 18; + +static const uint64_t MaxCoefficient = UINT64_C(0x16345785D89FFFF); // 999999999999999999 == 18 9's + +// This class handles Decimal special values. +class SpecialValueHandler { + WTF_MAKE_NONCOPYABLE(SpecialValueHandler); +public: + enum HandleResult { + BothFinite, + BothInfinity, + EitherNaN, + LHSIsInfinity, + RHSIsInfinity, + }; + + SpecialValueHandler(const Decimal& lhs, const Decimal& rhs); + HandleResult handle(); + Decimal value() const; + +private: + enum Result { + ResultIsLHS, + ResultIsRHS, + ResultIsUnknown, + }; + + const Decimal& m_lhs; + const Decimal& m_rhs; + Result m_result; +}; + +SpecialValueHandler::SpecialValueHandler(const Decimal& lhs, const Decimal& rhs) + : m_lhs(lhs), m_rhs(rhs), m_result(ResultIsUnknown) +{ +} + +SpecialValueHandler::HandleResult SpecialValueHandler::handle() +{ + if (m_lhs.isFinite() && m_rhs.isFinite()) + return BothFinite; + + const Decimal::EncodedData::FormatClass lhsClass = m_lhs.value().formatClass(); + const Decimal::EncodedData::FormatClass rhsClass = m_rhs.value().formatClass(); + if (lhsClass == Decimal::EncodedData::ClassNaN) { + m_result = ResultIsLHS; + return EitherNaN; + } + + if (rhsClass == Decimal::EncodedData::ClassNaN) { + m_result = ResultIsRHS; + return EitherNaN; + } + + if (lhsClass == Decimal::EncodedData::ClassInfinity) + return rhsClass == Decimal::EncodedData::ClassInfinity ? BothInfinity : LHSIsInfinity; + + if (rhsClass == Decimal::EncodedData::ClassInfinity) + return RHSIsInfinity; + + ASSERT_NOT_REACHED(); + return BothFinite; +} + +Decimal SpecialValueHandler::value() const +{ + switch (m_result) { + case ResultIsLHS: + return m_lhs; + case ResultIsRHS: + return m_rhs; + case ResultIsUnknown: + default: + ASSERT_NOT_REACHED(); + return m_lhs; + } +} + +// This class is used for 128 bit unsigned integer arithmetic. +class UInt128 { +public: + UInt128(uint64_t low, uint64_t high) + : m_high(high), m_low(low) + { + } + + UInt128& operator/=(uint32_t); + + uint64_t high() const { return m_high; } + uint64_t low() const { return m_low; } + + static UInt128 multiply(uint64_t u, uint64_t v) { return UInt128(u * v, multiplyHigh(u, v)); } + +private: + static uint32_t highUInt32(uint64_t x) { return static_cast<uint32_t>(x >> 32); } + static uint32_t lowUInt32(uint64_t x) { return static_cast<uint32_t>(x & ((static_cast<uint64_t>(1) << 32) - 1)); } + bool isZero() const { return !m_low && !m_high; } + static uint64_t makeUInt64(uint32_t low, uint32_t high) { return low | (static_cast<uint64_t>(high) << 32); } + + static uint64_t multiplyHigh(uint64_t, uint64_t); + + uint64_t m_high; + uint64_t m_low; +}; + +UInt128& UInt128::operator/=(const uint32_t divisor) +{ + ASSERT(divisor); + + if (!m_high) { + m_low /= divisor; + return *this; + } + + uint32_t dividend[4]; + dividend[0] = lowUInt32(m_low); + dividend[1] = highUInt32(m_low); + dividend[2] = lowUInt32(m_high); + dividend[3] = highUInt32(m_high); + + uint32_t quotient[4]; + uint32_t remainder = 0; + for (int i = 3; i >= 0; --i) { + const uint64_t work = makeUInt64(remainder, dividend[i]); + remainder = static_cast<uint32_t>(work % divisor); + quotient[i] = static_cast<uint32_t>(work / divisor); + } + m_low = makeUInt64(quotient[0], quotient[1]); + m_high = makeUInt64(quotient[2], quotient[3]); + return *this; +} + +// Returns high 64bit of 128bit product. +uint64_t UInt128::multiplyHigh(uint64_t u, uint64_t v) +{ + const uint64_t uLow = lowUInt32(u); + const uint64_t uHigh = highUInt32(u); + const uint64_t vLow = lowUInt32(v); + const uint64_t vHigh = highUInt32(v); + const uint64_t partialProduct = uHigh * vLow + highUInt32(uLow * vLow); + return uHigh * vHigh + highUInt32(partialProduct) + highUInt32(uLow * vHigh + lowUInt32(partialProduct)); +} + +static int countDigits(uint64_t x) +{ + int numberOfDigits = 0; + for (uint64_t powerOfTen = 1; x >= powerOfTen; powerOfTen *= 10) { + ++numberOfDigits; + if (powerOfTen >= std::numeric_limits<uint64_t>::max() / 10) + break; + } + return numberOfDigits; +} + +static uint64_t scaleDown(uint64_t x, int n) +{ + ASSERT(n >= 0); + while (n > 0 && x) { + x /= 10; + --n; + } + return x; +} + +static uint64_t scaleUp(uint64_t x, int n) +{ + ASSERT(n >= 0); + ASSERT(n < Precision); + + uint64_t y = 1; + uint64_t z = 10; + for (;;) { + if (n & 1) + y = y * z; + + n >>= 1; + if (!n) + return x * y; + + z = z * z; + } +} + +} // namespace DecimalPrivate + +using namespace DecimalPrivate; + +Decimal::EncodedData::EncodedData(Sign sign, FormatClass formatClass) + : m_coefficient(0) + , m_exponent(0) + , m_formatClass(formatClass) + , m_sign(sign) +{ +} + +Decimal::EncodedData::EncodedData(Sign sign, int exponent, uint64_t coefficient) + : m_formatClass(coefficient ? ClassNormal : ClassZero) + , m_sign(sign) +{ + if (exponent >= ExponentMin && exponent <= ExponentMax) { + while (coefficient >= MaxCoefficient) { + coefficient /= 10; + ++exponent; + } + } + + if (exponent > ExponentMax) { + m_coefficient = 0; + m_exponent = 0; + m_formatClass = ClassInfinity; + return; + } + + if (exponent < ExponentMin) { + m_coefficient = 0; + m_exponent = 0; + m_formatClass = ClassZero; + return; + } + + m_coefficient = coefficient; + m_exponent = static_cast<int16_t>(exponent); +} + +bool Decimal::EncodedData::operator==(const EncodedData& another) const +{ + return m_sign == another.m_sign + && m_formatClass == another.m_formatClass + && m_exponent == another.m_exponent + && m_coefficient == another.m_coefficient; +} + +Decimal::Decimal(int32_t i32) + : m_data(i32 < 0 ? Negative : Positive, 0, i32 < 0 ? static_cast<uint64_t>(-static_cast<int64_t>(i32)) : static_cast<uint64_t>(i32)) +{ +} + +Decimal::Decimal(Sign sign, int exponent, uint64_t coefficient) + : m_data(sign, exponent, coefficient) +{ +} + +Decimal::Decimal(const EncodedData& data) + : m_data(data) +{ +} + +Decimal::Decimal(const Decimal& other) + : m_data(other.m_data) +{ +} + +Decimal& Decimal::operator=(const Decimal& other) +{ + m_data = other.m_data; + return *this; +} + +Decimal& Decimal::operator+=(const Decimal& other) +{ + m_data = (*this + other).m_data; + return *this; +} + +Decimal& Decimal::operator-=(const Decimal& other) +{ + m_data = (*this - other).m_data; + return *this; +} + +Decimal& Decimal::operator*=(const Decimal& other) +{ + m_data = (*this * other).m_data; + return *this; +} + +Decimal& Decimal::operator/=(const Decimal& other) +{ + m_data = (*this / other).m_data; + return *this; +} + +Decimal Decimal::operator-() const +{ + if (isNaN()) + return *this; + + Decimal result(*this); + result.m_data.setSign(invertSign(m_data.sign())); + return result; +} + +Decimal Decimal::operator+(const Decimal& rhs) const +{ + const Decimal& lhs = *this; + const Sign lhsSign = lhs.sign(); + const Sign rhsSign = rhs.sign(); + + SpecialValueHandler handler(lhs, rhs); + switch (handler.handle()) { + case SpecialValueHandler::BothFinite: + break; + + case SpecialValueHandler::BothInfinity: + return lhsSign == rhsSign ? lhs : nan(); + + case SpecialValueHandler::EitherNaN: + return handler.value(); + + case SpecialValueHandler::LHSIsInfinity: + return lhs; + + case SpecialValueHandler::RHSIsInfinity: + return rhs; + } + + const AlignedOperands alignedOperands = alignOperands(lhs, rhs); + + const uint64_t result = lhsSign == rhsSign + ? alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient + : alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient; + + if (lhsSign == Negative && rhsSign == Positive && !result) + return Decimal(Positive, alignedOperands.exponent, 0); + + return static_cast<int64_t>(result) >= 0 + ? Decimal(lhsSign, alignedOperands.exponent, result) + : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<int64_t>(result)); +} + +Decimal Decimal::operator-(const Decimal& rhs) const +{ + const Decimal& lhs = *this; + const Sign lhsSign = lhs.sign(); + const Sign rhsSign = rhs.sign(); + + SpecialValueHandler handler(lhs, rhs); + switch (handler.handle()) { + case SpecialValueHandler::BothFinite: + break; + + case SpecialValueHandler::BothInfinity: + return lhsSign == rhsSign ? nan() : lhs; + + case SpecialValueHandler::EitherNaN: + return handler.value(); + + case SpecialValueHandler::LHSIsInfinity: + return lhs; + + case SpecialValueHandler::RHSIsInfinity: + return infinity(invertSign(rhsSign)); + } + + const AlignedOperands alignedOperands = alignOperands(lhs, rhs); + + const uint64_t result = lhsSign == rhsSign + ? alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient + : alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient; + + if (lhsSign == Negative && rhsSign == Negative && !result) + return Decimal(Positive, alignedOperands.exponent, 0); + + return static_cast<int64_t>(result) >= 0 + ? Decimal(lhsSign, alignedOperands.exponent, result) + : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<int64_t>(result)); +} + +Decimal Decimal::operator*(const Decimal& rhs) const +{ + const Decimal& lhs = *this; + const Sign lhsSign = lhs.sign(); + const Sign rhsSign = rhs.sign(); + const Sign resultSign = lhsSign == rhsSign ? Positive : Negative; + + SpecialValueHandler handler(lhs, rhs); + switch (handler.handle()) { + case SpecialValueHandler::BothFinite: { + const uint64_t lhsCoefficient = lhs.m_data.coefficient(); + const uint64_t rhsCoefficient = rhs.m_data.coefficient(); + int resultExponent = lhs.exponent() + rhs.exponent(); + UInt128 work(UInt128::multiply(lhsCoefficient, rhsCoefficient)); + while (work.high()) { + work /= 10; + ++resultExponent; + } + return Decimal(resultSign, resultExponent, work.low()); + } + + case SpecialValueHandler::BothInfinity: + return infinity(resultSign); + + case SpecialValueHandler::EitherNaN: + return handler.value(); + + case SpecialValueHandler::LHSIsInfinity: + return rhs.isZero() ? nan() : infinity(resultSign); + + case SpecialValueHandler::RHSIsInfinity: + return lhs.isZero() ? nan() : infinity(resultSign); + } + + ASSERT_NOT_REACHED(); + return nan(); +} + +Decimal Decimal::operator/(const Decimal& rhs) const +{ + const Decimal& lhs = *this; + const Sign lhsSign = lhs.sign(); + const Sign rhsSign = rhs.sign(); + const Sign resultSign = lhsSign == rhsSign ? Positive : Negative; + + SpecialValueHandler handler(lhs, rhs); + switch (handler.handle()) { + case SpecialValueHandler::BothFinite: + break; + + case SpecialValueHandler::BothInfinity: + return nan(); + + case SpecialValueHandler::EitherNaN: + return handler.value(); + + case SpecialValueHandler::LHSIsInfinity: + return infinity(resultSign); + + case SpecialValueHandler::RHSIsInfinity: + return zero(resultSign); + } + + ASSERT(lhs.isFinite()); + ASSERT(rhs.isFinite()); + + if (rhs.isZero()) + return lhs.isZero() ? nan() : infinity(resultSign); + + int resultExponent = lhs.exponent() - rhs.exponent(); + + if (lhs.isZero()) + return Decimal(resultSign, resultExponent, 0); + + uint64_t remainder = lhs.m_data.coefficient(); + const uint64_t divisor = rhs.m_data.coefficient(); + uint64_t result = 0; + while (result < MaxCoefficient / 100) { + while (remainder < divisor) { + remainder *= 10; + result *= 10; + --resultExponent; + } + result += remainder / divisor; + remainder %= divisor; + if (!remainder) + break; + } + + if (remainder > divisor / 2) + ++result; + + return Decimal(resultSign, resultExponent, result); +} + +bool Decimal::operator==(const Decimal& rhs) const +{ + return m_data == rhs.m_data || compareTo(rhs).isZero(); +} + +bool Decimal::operator!=(const Decimal& rhs) const +{ + if (m_data == rhs.m_data) + return false; + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return !result.isZero(); +} + +bool Decimal::operator<(const Decimal& rhs) const +{ + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return !result.isZero() && result.isNegative(); +} + +bool Decimal::operator<=(const Decimal& rhs) const +{ + if (m_data == rhs.m_data) + return true; + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return result.isZero() || result.isNegative(); +} + +bool Decimal::operator>(const Decimal& rhs) const +{ + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return !result.isZero() && result.isPositive(); +} + +bool Decimal::operator>=(const Decimal& rhs) const +{ + if (m_data == rhs.m_data) + return true; + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return result.isZero() || !result.isNegative(); +} + +Decimal Decimal::abs() const +{ + Decimal result(*this); + result.m_data.setSign(Positive); + return result; +} + +Decimal::AlignedOperands Decimal::alignOperands(const Decimal& lhs, const Decimal& rhs) +{ + ASSERT(lhs.isFinite()); + ASSERT(rhs.isFinite()); + + const int lhsExponent = lhs.exponent(); + const int rhsExponent = rhs.exponent(); + int exponent = std::min(lhsExponent, rhsExponent); + uint64_t lhsCoefficient = lhs.m_data.coefficient(); + uint64_t rhsCoefficient = rhs.m_data.coefficient(); + + if (lhsExponent > rhsExponent) { + const int numberOfLHSDigits = countDigits(lhsCoefficient); + if (numberOfLHSDigits) { + const int lhsShiftAmount = lhsExponent - rhsExponent; + const int overflow = numberOfLHSDigits + lhsShiftAmount - Precision; + if (overflow <= 0) + lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount); + else { + lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount - overflow); + rhsCoefficient = scaleDown(rhsCoefficient, overflow); + exponent += overflow; + } + } + + } else if (lhsExponent < rhsExponent) { + const int numberOfRHSDigits = countDigits(rhsCoefficient); + if (numberOfRHSDigits) { + const int rhsShiftAmount = rhsExponent - lhsExponent; + const int overflow = numberOfRHSDigits + rhsShiftAmount - Precision; + if (overflow <= 0) + rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount); + else { + rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount - overflow); + lhsCoefficient = scaleDown(lhsCoefficient, overflow); + exponent += overflow; + } + } + } + + AlignedOperands alignedOperands; + alignedOperands.exponent = exponent; + alignedOperands.lhsCoefficient = lhsCoefficient; + alignedOperands.rhsCoefficient = rhsCoefficient; + return alignedOperands; +} + +// Round toward positive infinity. +// Note: Mac ports defines ceil(x) as wtf_ceil(x), so we can't use name "ceil" here. +Decimal Decimal::ceiling() const +{ + if (isSpecial()) + return *this; + + if (exponent() >= 0) + return *this; + + uint64_t result = m_data.coefficient(); + const int numberOfDigits = countDigits(result); + const int numberOfDropDigits = -exponent(); + if (numberOfDigits < numberOfDropDigits) + return zero(Positive); + + result = scaleDown(result, numberOfDropDigits - 1); + if (sign() == Positive && result % 10 > 0) + result += 10; + result /= 10; + return Decimal(sign(), 0, result); +} + +Decimal Decimal::compareTo(const Decimal& rhs) const +{ + const Decimal result(*this - rhs); + switch (result.m_data.formatClass()) { + case EncodedData::ClassInfinity: + return result.isNegative() ? Decimal(-1) : Decimal(1); + + case EncodedData::ClassNaN: + case EncodedData::ClassNormal: + return result; + + case EncodedData::ClassZero: + return zero(Positive); + + default: + ASSERT_NOT_REACHED(); + return nan(); + } +} + +// Round toward negative infinity. +Decimal Decimal::floor() const +{ + if (isSpecial()) + return *this; + + if (exponent() >= 0) + return *this; + + uint64_t result = m_data.coefficient(); + const int numberOfDigits = countDigits(result); + const int numberOfDropDigits = -exponent(); + if (numberOfDigits < numberOfDropDigits) + return zero(Positive); + + result = scaleDown(result, numberOfDropDigits - 1); + if (isNegative() && result % 10 > 0) + result += 10; + result /= 10; + return Decimal(sign(), 0, result); +} + +Decimal Decimal::fromString(const String& str) +{ + int exponent = 0; + Sign exponentSign = Positive; + int numberOfDigits = 0; + int numberOfDigitsAfterDot = 0; + int numberOfExtraDigits = 0; + Sign sign = Positive; + + enum { + StateDigit, + StateDot, + StateDotDigit, + StateE, + StateEDigit, + StateESign, + StateSign, + StateStart, + StateZero, + } state = StateStart; + +#define HandleCharAndBreak(expected, nextState) \ + if (ch == expected) { \ + state = nextState; \ + break; \ + } + +#define HandleTwoCharsAndBreak(expected1, expected2, nextState) \ + if (ch == expected1 || ch == expected2) { \ + state = nextState; \ + break; \ + } + + uint64_t accumulator = 0; + for (unsigned index = 0; index < str.length(); ++index) { + const int ch = str[index]; + switch (state) { + case StateDigit: + if (ch >= '0' && ch <= '9') { + if (numberOfDigits < Precision) { + ++numberOfDigits; + accumulator *= 10; + accumulator += ch - '0'; + } else + ++numberOfExtraDigits; + break; + } + + HandleCharAndBreak('.', StateDot); + HandleTwoCharsAndBreak('E', 'e', StateE); + return nan(); + + case StateDot: + if (ch >= '0' && ch <= '9') { + if (numberOfDigits < Precision) { + ++numberOfDigits; + ++numberOfDigitsAfterDot; + accumulator *= 10; + accumulator += ch - '0'; + } + state = StateDotDigit; + break; + } + + case StateDotDigit: + if (ch >= '0' && ch <= '9') { + if (numberOfDigits < Precision) { + ++numberOfDigits; + ++numberOfDigitsAfterDot; + accumulator *= 10; + accumulator += ch - '0'; + } + break; + } + + HandleTwoCharsAndBreak('E', 'e', StateE); + return nan(); + + case StateE: + if (ch == '+') { + exponentSign = Positive; + state = StateESign; + break; + } + + if (ch == '-') { + exponentSign = Negative; + state = StateESign; + break; + } + + if (ch >= '0' && ch <= '9') { + exponent = ch - '0'; + state = StateEDigit; + break; + } + + return nan(); + + case StateEDigit: + if (ch >= '0' && ch <= '9') { + exponent *= 10; + exponent += ch - '0'; + if (exponent > ExponentMax + Precision) { + if (accumulator) + return exponentSign == Negative ? zero(Positive) : infinity(sign); + return zero(sign); + } + state = StateEDigit; + break; + } + + return nan(); + + case StateESign: + if (ch >= '0' && ch <= '9') { + exponent = ch - '0'; + state = StateEDigit; + break; + } + + return nan(); + + case StateSign: + if (ch >= '1' && ch <= '9') { + accumulator = ch - '0'; + numberOfDigits = 1; + state = StateDigit; + break; + } + + HandleCharAndBreak('0', StateZero); + return nan(); + + case StateStart: + if (ch >= '1' && ch <= '9') { + accumulator = ch - '0'; + numberOfDigits = 1; + state = StateDigit; + break; + } + + if (ch == '-') { + sign = Negative; + state = StateSign; + break; + } + + if (ch == '+') { + sign = Positive; + state = StateSign; + break; + } + + HandleCharAndBreak('0', StateZero); + HandleCharAndBreak('.', StateDot); + return nan(); + + case StateZero: + if (ch == '0') + break; + + if (ch >= '1' && ch <= '9') { + accumulator = ch - '0'; + numberOfDigits = 1; + state = StateDigit; + break; + } + + HandleCharAndBreak('.', StateDot); + HandleTwoCharsAndBreak('E', 'e', StateE); + return nan(); + + default: + ASSERT_NOT_REACHED(); + return nan(); + } + } + + if (state == StateZero) + return zero(sign); + + if (state == StateDigit || state == StateEDigit || state == StateDotDigit) { + int resultExponent = exponent * (exponentSign == Negative ? -1 : 1) - numberOfDigitsAfterDot + numberOfExtraDigits; + if (resultExponent < ExponentMin) + return zero(Positive); + + const int overflow = resultExponent - ExponentMax + 1; + if (overflow > 0) { + if (overflow + numberOfDigits - numberOfDigitsAfterDot > Precision) + return infinity(sign); + accumulator = scaleUp(accumulator, overflow); + resultExponent -= overflow; + } + + return Decimal(sign, resultExponent, accumulator); + } + + return nan(); +} + +Decimal Decimal::infinity(const Sign sign) +{ + return Decimal(EncodedData(sign, EncodedData::ClassInfinity)); +} + +Decimal Decimal::nan() +{ + return Decimal(EncodedData(Positive, EncodedData::ClassNaN)); +} + +Decimal Decimal::remainder(const Decimal& rhs) const +{ + const Decimal quotient = (*this / rhs).round(); + return quotient.isSpecial() ? quotient : *this - quotient * rhs; +} + +Decimal Decimal::round() const +{ + if (isSpecial()) + return *this; + + if (exponent() >= 0) + return *this; + + uint64_t result = m_data.coefficient(); + const int numberOfDigits = countDigits(result); + const int numberOfDropDigits = -exponent(); + if (numberOfDigits < numberOfDropDigits) + return zero(Positive); + + result = scaleDown(result, numberOfDropDigits - 1); + if (result % 10 >= 5) + result += 10; + result /= 10; + return Decimal(sign(), 0, result); +} + +String Decimal::toString() const +{ + switch (m_data.formatClass()) { + case EncodedData::ClassInfinity: + return sign() ? "-Infinity" : "Infinity"; + + case EncodedData::ClassNaN: + return "NaN"; + + case EncodedData::ClassNormal: + case EncodedData::ClassZero: + break; + + default: + ASSERT_NOT_REACHED(); + return ""; + } + + StringBuilder builder; + if (sign()) + builder.append('-'); + + int originalExponent = exponent(); + + const int maxDigits = DBL_DIG; + uint64_t coefficient = m_data.coefficient(); + uint64_t lastDigit = 0; + while (countDigits(coefficient) > maxDigits) { + lastDigit = coefficient % 10; + coefficient /= 10; + ++originalExponent; + } + + if (lastDigit >= 5) + ++coefficient; + + while (originalExponent < 0 && coefficient && !(coefficient % 10)) { + coefficient /= 10; + ++originalExponent; + } + + const String digits = String::number(coefficient); + int coefficientLength = static_cast<int>(digits.length()); + const int adjustedExponent = originalExponent + coefficientLength - 1; + if (originalExponent <= 0 && adjustedExponent >= -6) { + if (!originalExponent) { + builder.append(digits); + return builder.toString(); + } + + if (adjustedExponent >= 0) { + for (int i = 0; i < coefficientLength; ++i) { + builder.append(digits[i]); + if (i == adjustedExponent) + builder.append('.'); + } + return builder.toString(); + } + + builder.append("0."); + for (int i = adjustedExponent + 1; i < 0; ++i) + builder.append('0'); + + builder.append(digits); + + } else { + builder.append(digits[0]); + while (coefficientLength >= 2 && digits[coefficientLength - 1] == '0') + --coefficientLength; + if (coefficientLength >= 2) { + builder.append('.'); + for (int i = 1; i < coefficientLength; ++i) + builder.append(digits[i]); + } + + if (adjustedExponent) { + builder.append(adjustedExponent < 0 ? "e" : "e+"); + builder.append(String::number(adjustedExponent)); + } + } + return builder.toString(); +} + +Decimal Decimal::zero(Sign sign) +{ + return Decimal(EncodedData(sign, EncodedData::ClassZero)); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/Decimal.h b/Source/WebCore/platform/Decimal.h new file mode 100644 index 000000000..2ef886200 --- /dev/null +++ b/Source/WebCore/platform/Decimal.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Decimal_h +#define Decimal_h + +#include <stdint.h> +#include <wtf/Assertions.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +namespace DecimalPrivate { +class SpecialValueHandler; +} + +// This class represents decimal base floating point number. +// +// FIXME: Once all C++ compiler support decimal type, we should replace this +// class to compiler supported one. See below URI for current status of decimal +// type for C++: // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1977.html +class Decimal { +public: + enum Sign { + Positive, + Negative, + }; + + // You should not use EncodedData other than unit testing. + class EncodedData { + // For accessing FormatClass. + friend class Decimal; + friend class DecimalPrivate::SpecialValueHandler; + public: + EncodedData(Sign, int exponent, uint64_t coefficient); + + bool operator==(const EncodedData&) const; + bool operator!=(const EncodedData& another) const { return !operator==(another); } + + uint64_t coefficient() const { return m_coefficient; } + int countDigits() const; + int exponent() const { return m_exponent; } + bool isFinite() const { return !isSpecial(); } + bool isNaN() const { return m_formatClass == ClassNaN; } + bool isSpecial() const { return m_formatClass == ClassInfinity || m_formatClass == ClassNaN; } + bool isZero() const { return m_formatClass == ClassZero; } + Sign sign() const { return m_sign; } + void setSign(Sign sign) { m_sign = sign; } + + private: + enum FormatClass { + ClassInfinity, + ClassNormal, + ClassNaN, + ClassZero, + }; + + EncodedData(Sign, FormatClass); + FormatClass formatClass() const { return m_formatClass; } + + uint64_t m_coefficient; + int16_t m_exponent; + FormatClass m_formatClass; + Sign m_sign; + }; + + Decimal(int32_t = 0); + Decimal(Sign, int exponent, uint64_t coefficient); + Decimal(const Decimal&); + + Decimal& operator=(const Decimal&); + Decimal& operator+=(const Decimal&); + Decimal& operator-=(const Decimal&); + Decimal& operator*=(const Decimal&); + Decimal& operator/=(const Decimal&); + + Decimal operator-() const; + + bool operator==(const Decimal&) const; + bool operator!=(const Decimal&) const; + bool operator<(const Decimal&) const; + bool operator<=(const Decimal&) const; + bool operator>(const Decimal&) const; + bool operator>=(const Decimal&) const; + + Decimal operator+(const Decimal&) const; + Decimal operator-(const Decimal&) const; + Decimal operator*(const Decimal&) const; + Decimal operator/(const Decimal&) const; + + int exponent() const + { + ASSERT(isFinite()); + return m_data.exponent(); + } + + bool isFinite() const { return m_data.isFinite(); } + bool isNaN() const { return m_data.isNaN(); } + bool isNegative() const { return sign() == Negative; } + bool isPositive() const { return sign() == Positive; } + bool isSpecial() const { return m_data.isSpecial(); } + bool isZero() const { return m_data.isZero(); } + + Decimal abs() const; + Decimal ceiling() const; + Decimal floor() const; + Decimal remainder(const Decimal&) const; + Decimal round() const; + + // Note: toString method supports infinity and nan but fromString not. + String toString() const; + + // fromString supports following syntax EBNF: + // number ::= sign? digit+ ('.' digit*) (exponent-marker sign? digit+)? + // | sign? '.' digit+ (exponent-marker sign? digit+)? + // sign ::= '+' | '-' + // exponent-marker ::= 'e' | 'E' + // digit ::= '0' | '1' | ... | '9' + // Note: fromString doesn't support "infinity" and "nan". + static Decimal fromString(const String&); + static Decimal infinity(Sign); + static Decimal nan(); + static Decimal zero(Sign); + + // You should not use below methods. We expose them for unit testing. + explicit Decimal(const EncodedData&); + const EncodedData& value() const { return m_data; } + +private: + struct AlignedOperands { + uint64_t lhsCoefficient; + uint64_t rhsCoefficient; + int exponent; + }; + + Decimal(double); + Decimal compareTo(const Decimal&) const; + + static AlignedOperands alignOperands(const Decimal& lhs, const Decimal& rhs); + static inline Sign invertSign(Sign sign) { return sign == Negative ? Positive : Negative; } + + Sign sign() const { return m_data.sign(); } + + EncodedData m_data; +}; + +} // namespace WebCore + +#endif // Decimal_h diff --git a/Source/WebCore/platform/LocalizedStrings.cpp b/Source/WebCore/platform/LocalizedStrings.cpp index 21bb58c19..b140f9c07 100644 --- a/Source/WebCore/platform/LocalizedStrings.cpp +++ b/Source/WebCore/platform/LocalizedStrings.cpp @@ -675,7 +675,7 @@ String crashedPluginText() String insecurePluginVersionText() { - return WEB_UI_STRING("Insecure Plug-In Version", "Label text to be used when an insecure plug-in version was blocked from loading"); + return WEB_UI_STRING("Blocked Plug-in", "Label text to be used when an insecure plug-in version was blocked from loading"); } String multipleFileUploadText(unsigned numberOfFiles) diff --git a/Source/WebCore/platform/MIMETypeRegistry.cpp b/Source/WebCore/platform/MIMETypeRegistry.cpp index de2aca671..289c6699b 100755 --- a/Source/WebCore/platform/MIMETypeRegistry.cpp +++ b/Source/WebCore/platform/MIMETypeRegistry.cpp @@ -39,9 +39,9 @@ #include <ApplicationServices/ApplicationServices.h> #include <wtf/RetainPtr.h> #endif -#if PLATFORM(QT) && USE(QT_IMAGE_DECODER) -#include <qimagereader.h> -#include <qimagewriter.h> +#if PLATFORM(QT) +#include <QImageReader> +#include <QImageWriter> #endif #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML) @@ -227,22 +227,6 @@ static void initializeSupportedImageMIMETypes() supportedImageMIMETypes->remove("application/pdf"); supportedImageMIMETypes->remove("application/postscript"); -#elif PLATFORM(QT) && USE(QT_IMAGE_DECODER) - QList<QByteArray> formats = QImageReader::supportedImageFormats(); - for (size_t i = 0; i < static_cast<size_t>(formats.size()); ++i) { -#if ENABLE(SVG) - /* - * Qt has support for SVG, but we want to use KSVG2 - */ - if (formats.at(i).toLower().startsWith("svg")) - continue; -#endif - String mimeType = MIMETypeRegistry::getMIMETypeForExtension(formats.at(i).constData()); - if (!mimeType.isEmpty()) { - supportedImageMIMETypes->add(mimeType); - supportedImageResourceMIMETypes->add(mimeType); - } - } #else // assume that all implementations at least support the following standard // image types: @@ -259,6 +243,22 @@ static void initializeSupportedImageMIMETypes() supportedImageMIMETypes->add(types[i]); supportedImageResourceMIMETypes->add(types[i]); } + +#if PLATFORM(QT) + QList<QByteArray> formats = QImageReader::supportedImageFormats(); + for (size_t i = 0; i < static_cast<size_t>(formats.size()); ++i) { +#if ENABLE(SVG) + // Qt has support for SVG, but we want to use KSVG2 + if (formats.at(i).toLower().startsWith("svg")) + continue; +#endif // ENABLE(SVG) + String mimeType = MIMETypeRegistry::getMIMETypeForExtension(formats.at(i).constData()); + if (!mimeType.isEmpty()) { + supportedImageMIMETypes->add(mimeType); + supportedImageResourceMIMETypes->add(mimeType); + } + } +#endif // PLATFORM(QT) #endif } @@ -283,14 +283,14 @@ static void initializeSupportedImageMIMETypesForEncoding() supportedImageMIMETypesForEncoding->add("image/jpeg"); supportedImageMIMETypesForEncoding->add("image/gif"); #endif -#elif PLATFORM(QT) && USE(QT_IMAGE_DECODER) +#elif PLATFORM(QT) QList<QByteArray> formats = QImageWriter::supportedImageFormats(); for (int i = 0; i < formats.size(); ++i) { String mimeType = MIMETypeRegistry::getMIMETypeForExtension(formats.at(i).constData()); if (!mimeType.isEmpty()) supportedImageMIMETypesForEncoding->add(mimeType); } -#elif PLATFORM(GTK) || (PLATFORM(QT) && !USE(QT_IMAGE_DECODER)) +#elif PLATFORM(GTK) supportedImageMIMETypesForEncoding->add("image/png"); supportedImageMIMETypesForEncoding->add("image/jpeg"); supportedImageMIMETypesForEncoding->add("image/tiff"); diff --git a/Source/WebCore/platform/MemoryUsageSupport.cpp b/Source/WebCore/platform/MemoryUsageSupport.cpp index 2f06c7639..77eb4f46f 100644 --- a/Source/WebCore/platform/MemoryUsageSupport.cpp +++ b/Source/WebCore/platform/MemoryUsageSupport.cpp @@ -58,4 +58,9 @@ int MemoryUsageSupport::highUsageDeltaMB() return 0; } +bool MemoryUsageSupport::processMemorySizesInBytes(size_t*, size_t*) +{ + return false; +} + } // namespace WebCore diff --git a/Source/WebCore/platform/MemoryUsageSupport.h b/Source/WebCore/platform/MemoryUsageSupport.h index 9d12e3740..4f1a0bdd7 100644 --- a/Source/WebCore/platform/MemoryUsageSupport.h +++ b/Source/WebCore/platform/MemoryUsageSupport.h @@ -52,6 +52,11 @@ public: // Delta of memory usage growth (vs. last actualMemoryUsageMB()) // to force GC when memory usage is high. static int highUsageDeltaMB(); + + // Returns private and shared usage, in bytes. Private bytes is the amount of + // memory currently allocated to this process that cannot be shared. Returns + // false on platform specific error conditions. + static bool processMemorySizesInBytes(size_t* privateBytes, size_t* sharedBytes); }; } // namespace WebCore diff --git a/Source/WebCore/platform/Timer.h b/Source/WebCore/platform/Timer.h index 637bbc055..3a5cd9d6f 100644 --- a/Source/WebCore/platform/Timer.h +++ b/Source/WebCore/platform/Timer.h @@ -109,6 +109,52 @@ inline bool TimerBase::isActive() const return m_nextFireTime; } +template <typename TimerFiredClass> class DeferrableOneShotTimer : private TimerBase { +public: + typedef void (TimerFiredClass::*TimerFiredFunction)(DeferrableOneShotTimer*); + + DeferrableOneShotTimer(TimerFiredClass* o, TimerFiredFunction f, double delay) + : m_object(o) + , m_function(f) + , m_delay(delay) + , m_shouldRestartWhenTimerFires(false) + { + } + + void restart() + { + // Setting this boolean is much more efficient than calling startOneShot + // again, which might result in rescheduling the system timer which + // can be quite expensive. + + if (isActive()) { + m_shouldRestartWhenTimerFires = true; + return; + } + startOneShot(m_delay); + } + + using TimerBase::stop; + using TimerBase::isActive; +private: + virtual void fired() + { + if (m_shouldRestartWhenTimerFires) { + m_shouldRestartWhenTimerFires = false; + startOneShot(m_delay); + return; + } + + (m_object->*m_function)(this); + } + + TimerFiredClass* m_object; + TimerFiredFunction m_function; + + double m_delay; + bool m_shouldRestartWhenTimerFires; +}; + } #endif diff --git a/Source/WebCore/platform/blackberry/PageClientBlackBerry.h b/Source/WebCore/platform/blackberry/PageClientBlackBerry.h index 8f959dcdd..8a1f8870f 100644 --- a/Source/WebCore/platform/blackberry/PageClientBlackBerry.h +++ b/Source/WebCore/platform/blackberry/PageClientBlackBerry.h @@ -70,7 +70,7 @@ public: virtual int showAlertDialog(BlackBerry::WebKit::WebPageClient::AlertType) = 0; virtual bool isActive() const = 0; virtual bool isVisible() const = 0; - virtual WebCore::Credential authenticationChallenge(const WebCore::KURL&, const WebCore::ProtectionSpace&) = 0; + virtual bool authenticationChallenge(const WebCore::KURL&, const WebCore::ProtectionSpace&, WebCore::Credential&) = 0; virtual SaveCredentialType notifyShouldSaveCredential(bool) = 0; }; diff --git a/Source/WebCore/platform/blackberry/RenderThemeBlackBerry.cpp b/Source/WebCore/platform/blackberry/RenderThemeBlackBerry.cpp index 70c4389b9..dcc73e5c2 100644 --- a/Source/WebCore/platform/blackberry/RenderThemeBlackBerry.cpp +++ b/Source/WebCore/platform/blackberry/RenderThemeBlackBerry.cpp @@ -905,14 +905,13 @@ Color RenderThemeBlackBerry::platformFocusRingColor() const #if ENABLE(TOUCH_EVENTS) Color RenderThemeBlackBerry::platformTapHighlightColor() const { - // Same color as 'focusRingPen' + 80 of alpha channel. - return Color(163, 200, 254, 80); + return Color(0, 168, 223, 50); } #endif Color RenderThemeBlackBerry::platformActiveSelectionBackgroundColor() const { - return Color(selection); + return Color(0, 168, 223, 50); } double RenderThemeBlackBerry::animationRepeatIntervalForProgressBar(RenderProgress* renderProgress) const diff --git a/Source/WebCore/platform/chromium/DragDataChromium.cpp b/Source/WebCore/platform/chromium/DragDataChromium.cpp index 021a6569f..de41342e3 100644 --- a/Source/WebCore/platform/chromium/DragDataChromium.cpp +++ b/Source/WebCore/platform/chromium/DragDataChromium.cpp @@ -38,9 +38,11 @@ #include "KURL.h" #include "NotImplemented.h" #include "PlatformString.h" -#include "PlatformSupport.h" #include "markup.h" +#include <public/Platform.h> +#include <public/WebFileUtilities.h> + namespace WebCore { static bool containsHTML(const ChromiumDataObject* dropData) @@ -60,7 +62,8 @@ String DragData::asURL(Frame*, FilenameConversionPolicy filenamePolicy, String* if (m_platformDragData->types().contains(mimeTypeTextURIList)) m_platformDragData->urlAndTitle(url, title); else if (filenamePolicy == ConvertFilenames && containsFiles()) { - url = PlatformSupport::filePathToURL(PlatformSupport::getAbsolutePath(m_platformDragData->filenames()[0])); + String path = String(WebKit::Platform::current()->fileUtilities()->getAbsolutePath(m_platformDragData->filenames()[0])); + url = KURL(WebKit::Platform::current()->fileUtilities()->filePathToURL(path)); } return url; } diff --git a/Source/WebCore/platform/chromium/FileSystemChromium.cpp b/Source/WebCore/platform/chromium/FileSystemChromium.cpp index d7ac34c81..21e0937b2 100644 --- a/Source/WebCore/platform/chromium/FileSystemChromium.cpp +++ b/Source/WebCore/platform/chromium/FileSystemChromium.cpp @@ -34,24 +34,27 @@ #include "FileMetadata.h" #include "NotImplemented.h" #include "PlatformString.h" -#include "PlatformSupport.h" + +#include <public/Platform.h> +#include <public/WebFileInfo.h> +#include <public/WebFileUtilities.h> namespace WebCore { bool deleteFile(const String& path) { - return PlatformSupport::deleteFile(path); + return WebKit::Platform::current()->fileUtilities()->deleteFile(path); } bool deleteEmptyDirectory(const String& path) { - return PlatformSupport::deleteEmptyDirectory(path); + return WebKit::Platform::current()->fileUtilities()->deleteEmptyDirectory(path); } bool getFileSize(const String& path, long long& result) { FileMetadata metadata; - if (!PlatformSupport::getFileMetadata(path, metadata)) + if (!getFileMetadata(path, metadata)) return false; result = metadata.length; return true; @@ -60,7 +63,7 @@ bool getFileSize(const String& path, long long& result) bool getFileModificationTime(const String& path, time_t& result) { FileMetadata metadata; - if (!PlatformSupport::getFileMetadata(path, metadata)) + if (!getFileMetadata(path, metadata)) return false; result = metadata.modificationTime; return true; @@ -68,57 +71,63 @@ bool getFileModificationTime(const String& path, time_t& result) bool getFileMetadata(const String& path, FileMetadata& metadata) { - return PlatformSupport::getFileMetadata(path, metadata); + WebKit::WebFileInfo webFileInfo; + if (!WebKit::Platform::current()->fileUtilities()->getFileInfo(path, webFileInfo)) + return false; + metadata.modificationTime = webFileInfo.modificationTime; + metadata.length = webFileInfo.length; + metadata.type = static_cast<FileMetadata::Type>(webFileInfo.type); + return true; } String directoryName(const String& path) { - return PlatformSupport::directoryName(path); + return WebKit::Platform::current()->fileUtilities()->directoryName(path); } String pathByAppendingComponent(const String& path, const String& component) { - return PlatformSupport::pathByAppendingComponent(path, component); + return WebKit::Platform::current()->fileUtilities()->pathByAppendingComponent(path, component); } bool makeAllDirectories(const String& path) { - return PlatformSupport::makeAllDirectories(path); + return WebKit::Platform::current()->fileUtilities()->makeAllDirectories(path); } bool fileExists(const String& path) { - return PlatformSupport::fileExists(path); + return WebKit::Platform::current()->fileUtilities()->fileExists(path); } PlatformFileHandle openFile(const String& path, FileOpenMode mode) { - return PlatformSupport::openFile(path, mode); + return WebKit::Platform::current()->fileUtilities()->openFile(path, mode); } void closeFile(PlatformFileHandle& handle) { - return PlatformSupport::closeFile(handle); + WebKit::Platform::current()->fileUtilities()->closeFile(handle); } long long seekFile(PlatformFileHandle handle, long long offset, FileSeekOrigin origin) { - return PlatformSupport::seekFile(handle, offset, origin); + return WebKit::Platform::current()->fileUtilities()->seekFile(handle, offset, origin); } bool truncateFile(PlatformFileHandle handle, long long offset) { - return PlatformSupport::truncateFile(handle, offset); + return WebKit::Platform::current()->fileUtilities()->truncateFile(handle, offset); } int readFromFile(PlatformFileHandle handle, char* data, int length) { - return PlatformSupport::readFromFile(handle, data, length); + return WebKit::Platform::current()->fileUtilities()->readFromFile(handle, data, length); } int writeToFile(PlatformFileHandle handle, const char* data, int length) { - return PlatformSupport::writeToFile(handle, data, length); + return WebKit::Platform::current()->fileUtilities()->writeToFile(handle, data, length); } Vector<String> listDirectory(const String& path, const String& filter) diff --git a/Source/WebCore/platform/chromium/MemoryUsageSupportChromium.cpp b/Source/WebCore/platform/chromium/MemoryUsageSupportChromium.cpp index 0c3553eae..d21dece90 100644 --- a/Source/WebCore/platform/chromium/MemoryUsageSupportChromium.cpp +++ b/Source/WebCore/platform/chromium/MemoryUsageSupportChromium.cpp @@ -60,4 +60,9 @@ int MemoryUsageSupport::highUsageDeltaMB() return WebKit::Platform::current()->highUsageDeltaMB(); } +bool MemoryUsageSupport::processMemorySizesInBytes(size_t* privateBytes, size_t* sharedBytes) +{ + return WebKit::Platform::current()->processMemorySizesInBytes(privateBytes, sharedBytes); +} + } // namespace WebCore diff --git a/Source/WebCore/platform/chromium/PlatformSupport.h b/Source/WebCore/platform/chromium/PlatformSupport.h index 7800f0cef..c4864b88e 100644 --- a/Source/WebCore/platform/chromium/PlatformSupport.h +++ b/Source/WebCore/platform/chromium/PlatformSupport.h @@ -122,24 +122,6 @@ public: static void deleteCookie(const Document*, const KURL&, const String& cookieName); static bool cookiesEnabled(const Document*); - // File --------------------------------------------------------------- - static bool fileExists(const String&); - static bool deleteFile(const String&); - static bool deleteEmptyDirectory(const String&); - static bool getFileMetadata(const String&, FileMetadata& result); - static String directoryName(const String& path); - static String pathByAppendingComponent(const String& path, const String& component); - static bool makeAllDirectories(const String& path); - static String getAbsolutePath(const String&); - static bool isDirectory(const String&); - static KURL filePathToURL(const String&); - static PlatformFileHandle openFile(const String& path, FileOpenMode); - static void closeFile(PlatformFileHandle&); - static long long seekFile(PlatformFileHandle, long long offset, FileSeekOrigin); - static bool truncateFile(PlatformFileHandle, long long offset); - static int readFromFile(PlatformFileHandle, char* data, int length); - static int writeToFile(PlatformFileHandle, const char* data, int length); - #if ENABLE(FILE_SYSTEM) static PassOwnPtr<AsyncFileSystem> createAsyncFileSystem(); #endif diff --git a/Source/WebCore/platform/chromium/PopupContainer.cpp b/Source/WebCore/platform/chromium/PopupContainer.cpp index 825716d08..b806b3c55 100644 --- a/Source/WebCore/platform/chromium/PopupContainer.cpp +++ b/Source/WebCore/platform/chromium/PopupContainer.cpp @@ -185,13 +185,10 @@ IntRect PopupContainer::layoutAndCalculateWidgetRect(int targetControlHeight, co else m_listBox->setMaxHeight(spaceBelow); layoutAndGetRTLOffset(); - // Our height has changed, so recompute only Y axis of widgetRect. - // We don't have to recompute X axis, so we only replace Y axis - // in widgetRect. - IntRect frameInScreen = chromeClient->rootViewToScreen(frameRect()); - widgetRectInScreen.setY(frameInScreen.y()); - widgetRectInScreen.setHeight(frameInScreen.height()); - // And move upwards if necessary. + // Container height may have changed in layoutAndGetRTLOffset(), + // so set the WebWidget height to the container height. + widgetRectInScreen.setHeight(height()); + // Move WebWidget upwards if necessary. if (spaceAbove > spaceBelow) widgetRectInScreen.move(0, -(widgetRectInScreen.height() + targetControlHeight)); } diff --git a/Source/WebCore/platform/chromium/PopupListBox.cpp b/Source/WebCore/platform/chromium/PopupListBox.cpp index d437bc882..0d4c0ef05 100644 --- a/Source/WebCore/platform/chromium/PopupListBox.cpp +++ b/Source/WebCore/platform/chromium/PopupListBox.cpp @@ -632,7 +632,7 @@ int PopupListBox::getRowHeight(int index) { int scale = m_settings.defaultDeviceScaleFactor; int paddingForTouch = 0; - if (RuntimeEnabledFeatures::touchEnabled()) + if (m_settings.deviceSupportsTouch) paddingForTouch = PopupMenuChromium::optionPaddingForTouch(); if (index < 0 || m_popupClient->itemStyle(index).isDisplayNone()) return PopupMenuChromium::minimumRowHeight() * scale; diff --git a/Source/WebCore/platform/chromium/PopupListBox.h b/Source/WebCore/platform/chromium/PopupListBox.h index b685313cc..c7309e5e8 100644 --- a/Source/WebCore/platform/chromium/PopupListBox.h +++ b/Source/WebCore/platform/chromium/PopupListBox.h @@ -80,7 +80,13 @@ struct PopupContainerSettings { // Autocomplete popups are restricted, combo-boxes (select tags) aren't. bool restrictWidthOfListBox; + // The default device scale factor of the screen used to draw the menu + // at this scale suitable for the device DPI. int defaultDeviceScaleFactor; + + // If the device is a touch screen we increase the height of menu items + // to make it easier to unambiguously touch them. + bool deviceSupportsTouch; }; // A container for the data for each menu item (e.g. represented by <option> diff --git a/Source/WebCore/platform/chromium/PopupMenuChromium.cpp b/Source/WebCore/platform/chromium/PopupMenuChromium.cpp index 62e1008fb..daca45bea 100644 --- a/Source/WebCore/platform/chromium/PopupMenuChromium.cpp +++ b/Source/WebCore/platform/chromium/PopupMenuChromium.cpp @@ -66,17 +66,18 @@ PopupMenuChromium::~PopupMenuChromium() hide(); } -void PopupMenuChromium::show(const IntRect& r, FrameView* v, int index) +void PopupMenuChromium::show(const IntRect& rect, FrameView* frameView, int index) { if (!p.popup) { + Settings* settings = frameView->frame()->page()->settings(); PopupContainerSettings popupSettings = dropDownSettings; - popupSettings.defaultDeviceScaleFactor = - v->frame()->page()->settings()->defaultDeviceScaleFactor(); + popupSettings.defaultDeviceScaleFactor = settings->defaultDeviceScaleFactor(); if (!popupSettings.defaultDeviceScaleFactor) popupSettings.defaultDeviceScaleFactor = 1; + popupSettings.deviceSupportsTouch = settings->deviceSupportsTouch(); p.popup = PopupContainer::create(client(), PopupContainer::Select, popupSettings); } - p.popup->showInRect(r, v, index); + p.popup->showInRect(rect, frameView, index); } void PopupMenuChromium::hide() diff --git a/Source/WebCore/platform/chromium/Prerender.cpp b/Source/WebCore/platform/chromium/Prerender.cpp index 933a8aa71..0ece44056 100644 --- a/Source/WebCore/platform/chromium/Prerender.cpp +++ b/Source/WebCore/platform/chromium/Prerender.cpp @@ -47,9 +47,6 @@ Prerender::Prerender(const KURL& url, const String& referrer, ReferrerPolicy pol : m_url(url) , m_referrer(referrer) , m_referrerPolicy(policy) -#ifndef NDEBUG - , m_state(Inactive) -#endif { } @@ -57,24 +54,13 @@ Prerender::~Prerender() { } -void Prerender::setState(State state) -{ -#ifdef NDEBUG - UNUSED_PARAM(state); -#else - m_state = state; -#endif -} - void Prerender::add() { - ASSERT(m_state == Inactive); WebKit::WebPrerenderingSupport* platform = WebKit::WebPrerenderingSupport::current(); if (!platform) return; WebKit::WebPrerender webPrerender(this); platform->add(webPrerender); - setState(Active); } void Prerender::cancel() @@ -83,10 +69,8 @@ void Prerender::cancel() WebKit::WebPrerenderingSupport* platform = WebKit::WebPrerenderingSupport::current(); if (!platform) return; - ASSERT(m_state == Active); WebKit::WebPrerender webPrerender(this); platform->cancel(webPrerender); - setState(Inactive); } void Prerender::abandon() @@ -94,12 +78,8 @@ void Prerender::abandon() WebKit::WebPrerenderingSupport* platform = WebKit::WebPrerenderingSupport::current(); if (!platform) return; - // FIXME: Assert on the state as Inactive here. It is currently common to call abandon() on an Inactive - // prerender, as the Prerenderer doesn't keep track of which prerenders are active, and so any page that - // ever had a now-canceled Prerender will get this bogus stop() call. WebKit::WebPrerender webPrerender(this); platform->abandon(webPrerender); - setState(Inactive); } void Prerender::suspend() diff --git a/Source/WebCore/platform/chromium/Prerender.h b/Source/WebCore/platform/chromium/Prerender.h index 9465b22ca..ce4ccc7fa 100644 --- a/Source/WebCore/platform/chromium/Prerender.h +++ b/Source/WebCore/platform/chromium/Prerender.h @@ -71,22 +71,11 @@ public: ExtraData* extraData() { return m_extraData.get(); } private: - enum State { - Inactive, - Active, - }; - - void setState(State); - const KURL m_url; const String m_referrer; const ReferrerPolicy m_referrerPolicy; RefPtr<ExtraData> m_extraData; - -#ifndef NDEBUG - State m_state; -#endif }; } diff --git a/Source/WebCore/platform/chromium/support/WebTransformOperations.cpp b/Source/WebCore/platform/chromium/support/WebTransformOperations.cpp new file mode 100644 index 000000000..12bd00b26 --- /dev/null +++ b/Source/WebCore/platform/chromium/support/WebTransformOperations.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include <public/WebTransformOperations.h> + +#include <wtf/Vector.h> + +namespace WebKit { + +struct WebTransformOperation { + enum Type { + WebTransformOperationTranslate, + WebTransformOperationRotate, + WebTransformOperationScale, + WebTransformOperationSkew, + WebTransformOperationPerspective, + WebTransformOperationMatrix + }; + + Type type; + WebTransformationMatrix matrix; +}; + +class WebTransformOperationsPrivate { +public: + Vector<WebTransformOperation> operations; +}; + +WebTransformationMatrix WebTransformOperations::apply() const +{ + WebTransformationMatrix toReturn; + for (size_t i = 0; i < m_private->operations.size(); ++i) + toReturn.multiply(m_private->operations[i].matrix); + return toReturn; +} + +WebTransformationMatrix WebTransformOperations::blend(const WebTransformOperations& from, double progress) const +{ + WebTransformationMatrix toReturn; + if (matchesTypes(from)) { + for (size_t i = 0; i < m_private->operations.size(); ++i) { + WebTransformationMatrix blended = m_private->operations[i].matrix; + blended.blend(from.m_private->operations[i].matrix, progress); + toReturn.multiply(blended); + } + } else { + toReturn = apply(); + WebTransformationMatrix fromTransform = from.apply(); + toReturn.blend(fromTransform, progress); + } + return toReturn; +} + +bool WebTransformOperations::matchesTypes(const WebTransformOperations& other) const +{ + if (m_private->operations.size() != other.m_private->operations.size()) + return false; + + for (size_t i = 0; i < m_private->operations.size(); ++i) { + if (m_private->operations[i].type != other.m_private->operations[i].type) + return false; + } + + return true; +} + +void WebTransformOperations::appendTranslate(double x, double y, double z) +{ + WebTransformOperation toAdd; + toAdd.matrix.translate3d(x, y, z); + toAdd.type = WebTransformOperation::WebTransformOperationTranslate; + m_private->operations.append(toAdd); +} + +void WebTransformOperations::appendRotate(double x, double y, double z, double degrees) +{ + WebTransformOperation toAdd; + toAdd.matrix.rotate3d(x, y, z, degrees); + toAdd.type = WebTransformOperation::WebTransformOperationRotate; + m_private->operations.append(toAdd); +} + +void WebTransformOperations::appendScale(double x, double y, double z) +{ + WebTransformOperation toAdd; + toAdd.matrix.scale3d(x, y, z); + toAdd.type = WebTransformOperation::WebTransformOperationScale; + m_private->operations.append(toAdd); +} + +void WebTransformOperations::appendSkew(double x, double y) +{ + WebTransformOperation toAdd; + toAdd.matrix.skewX(x); + toAdd.matrix.skewY(y); + toAdd.type = WebTransformOperation::WebTransformOperationSkew; + m_private->operations.append(toAdd); +} + +void WebTransformOperations::appendPerspective(double depth) +{ + WebTransformOperation toAdd; + toAdd.matrix.applyPerspective(depth); + toAdd.type = WebTransformOperation::WebTransformOperationPerspective; + m_private->operations.append(toAdd); +} + +void WebTransformOperations::appendMatrix(const WebTransformationMatrix& matrix) +{ + WebTransformOperation toAdd; + toAdd.matrix = matrix; + toAdd.type = WebTransformOperation::WebTransformOperationMatrix; + m_private->operations.append(toAdd); +} + +void WebTransformOperations::reset() +{ + m_private.reset(0); +} + +void WebTransformOperations::initialize() +{ + m_private.reset(new WebTransformOperationsPrivate); +} + +void WebTransformOperations::initialize(const WebTransformOperations& other) +{ + if (m_private.get() != other.m_private.get()) + m_private.reset(new WebTransformOperationsPrivate(*other.m_private.get())); + else + initialize(); +} + +} // namespace WebKit diff --git a/Source/WebCore/platform/chromium/support/WebTransformationMatrix.cpp b/Source/WebCore/platform/chromium/support/WebTransformationMatrix.cpp index bc86a5e2e..eefd154e8 100644 --- a/Source/WebCore/platform/chromium/support/WebTransformationMatrix.cpp +++ b/Source/WebCore/platform/chromium/support/WebTransformationMatrix.cpp @@ -32,44 +32,43 @@ using namespace WebCore; namespace WebKit { -// FIXME: The overhead of allocating a new TransformationMatrix in these constructors needs to go away as soon -// as possible. - WebTransformationMatrix::WebTransformationMatrix() - : m_private(new TransformationMatrix()) + : m_private() { } WebTransformationMatrix::WebTransformationMatrix(double a, double b, double c, double d, double e, double f) - : m_private(new TransformationMatrix(a, b, c, d, e, f)) + : m_private(a, b, c, d, e, f) { } -WebTransformationMatrix::WebTransformationMatrix(const WebTransformationMatrix& t) - : m_private(new TransformationMatrix(*t.m_private.get())) +WebTransformationMatrix::WebTransformationMatrix(double m11, double m12, double m13, double m14, + double m21, double m22, double m23, double m24, + double m31, double m32, double m33, double m34, + double m41, double m42, double m43, double m44) + : m_private(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44) { } -WebTransformationMatrix::WebTransformationMatrix(const TransformationMatrix& t) - : m_private(new TransformationMatrix(t)) +WebTransformationMatrix::WebTransformationMatrix(const WebTransformationMatrix& t) + : m_private(t.m_private) { } -void WebTransformationMatrix::reset() +WebTransformationMatrix::WebTransformationMatrix(const TransformationMatrix& t) + : m_private(t) { - m_private.reset(0); } WebTransformationMatrix& WebTransformationMatrix::operator=(const WebTransformationMatrix& t) { - *m_private.get() = *t.m_private.get(); + m_private = t.m_private; return *this; } bool WebTransformationMatrix::operator==(const WebTransformationMatrix& t) const { - bool isEqual = (*m_private.get() == *t.m_private.get()); - return isEqual; + return m_private == t.m_private; } WebTransformationMatrix WebTransformationMatrix::operator*(const WebTransformationMatrix& t) const @@ -82,380 +81,380 @@ WebTransformationMatrix WebTransformationMatrix::operator*(const WebTransformati WebTransformationMatrix WebTransformationMatrix::inverse() const { WebTransformationMatrix result; - *result.m_private.get() = m_private->inverse(); + result.m_private = m_private.inverse(); return result; } WebTransformationMatrix WebTransformationMatrix::to2dTransform() const { WebTransformationMatrix result; - *result.m_private.get() = m_private->to2dTransform(); + result.m_private = m_private.to2dTransform(); return result; } void WebTransformationMatrix::multiply(const WebTransformationMatrix& t) { - m_private->multiply(*t.m_private.get()); + m_private.multiply(t.m_private); } void WebTransformationMatrix::makeIdentity() { - m_private->makeIdentity(); + m_private.makeIdentity(); } void WebTransformationMatrix::translate(double tx, double ty) { - m_private->translate(tx, ty); + m_private.translate(tx, ty); } void WebTransformationMatrix::translate3d(double tx, double ty, double tz) { - m_private->translate3d(tx, ty, tz); + m_private.translate3d(tx, ty, tz); } void WebTransformationMatrix::translateRight3d(double tx, double ty, double tz) { - m_private->translateRight3d(tx, ty, tz); + m_private.translateRight3d(tx, ty, tz); } void WebTransformationMatrix::scale(double s) { - m_private->scale(s); + m_private.scale(s); } void WebTransformationMatrix::scaleNonUniform(double sx, double sy) { - m_private->scaleNonUniform(sx, sy); + m_private.scaleNonUniform(sx, sy); } void WebTransformationMatrix::scale3d(double sx, double sy, double sz) { - m_private->scale3d(sx, sy, sz); + m_private.scale3d(sx, sy, sz); } void WebTransformationMatrix::rotate(double angle) { - m_private->rotate(angle); + m_private.rotate(angle); } void WebTransformationMatrix::rotate3d(double rx, double ry, double rz) { - m_private->rotate3d(rx, ry, rz); + m_private.rotate3d(rx, ry, rz); } void WebTransformationMatrix::rotate3d(double x, double y, double z, double angle) { - m_private->rotate3d(x, y, z, angle); + m_private.rotate3d(x, y, z, angle); } void WebTransformationMatrix::skewX(double angle) { - m_private->skewX(angle); + m_private.skewX(angle); } void WebTransformationMatrix::skewY(double angle) { - m_private->skewY(angle); + m_private.skewY(angle); } void WebTransformationMatrix::applyPerspective(double p) { - m_private->applyPerspective(p); + m_private.applyPerspective(p); } void WebTransformationMatrix::blend(const WebTransformationMatrix& from, double progress) { - m_private->blend(*from.m_private.get(), progress); + m_private.blend(from.m_private, progress); } bool WebTransformationMatrix::hasPerspective() const { - return m_private->hasPerspective(); + return m_private.hasPerspective(); } bool WebTransformationMatrix::isInvertible() const { - return m_private->isInvertible(); + return m_private.isInvertible(); } bool WebTransformationMatrix::isBackFaceVisible() const { - return m_private->isBackFaceVisible(); + return m_private.isBackFaceVisible(); } bool WebTransformationMatrix::isIdentity() const { - return m_private->isIdentity(); + return m_private.isIdentity(); } bool WebTransformationMatrix::isIdentityOrTranslation() const { - return m_private->isIdentityOrTranslation(); + return m_private.isIdentityOrTranslation(); } bool WebTransformationMatrix::isIntegerTranslation() const { - return m_private->isIntegerTranslation(); + return m_private.isIntegerTranslation(); } double WebTransformationMatrix::m11() const { - return m_private->m11(); + return m_private.m11(); } void WebTransformationMatrix::setM11(double f) { - m_private->setM11(f); + m_private.setM11(f); } double WebTransformationMatrix::m12() const { - return m_private->m12(); + return m_private.m12(); } void WebTransformationMatrix::setM12(double f) { - m_private->setM12(f); + m_private.setM12(f); } double WebTransformationMatrix::m13() const { - return m_private->m13(); + return m_private.m13(); } void WebTransformationMatrix::setM13(double f) { - m_private->setM13(f); + m_private.setM13(f); } double WebTransformationMatrix::m14() const { - return m_private->m14(); + return m_private.m14(); } void WebTransformationMatrix::setM14(double f) { - m_private->setM14(f); + m_private.setM14(f); } double WebTransformationMatrix::m21() const { - return m_private->m21(); + return m_private.m21(); } void WebTransformationMatrix::setM21(double f) { - m_private->setM21(f); + m_private.setM21(f); } double WebTransformationMatrix::m22() const { - return m_private->m22(); + return m_private.m22(); } void WebTransformationMatrix::setM22(double f) { - m_private->setM22(f); + m_private.setM22(f); } double WebTransformationMatrix::m23() const { - return m_private->m23(); + return m_private.m23(); } void WebTransformationMatrix::setM23(double f) { - m_private->setM23(f); + m_private.setM23(f); } double WebTransformationMatrix::m24() const { - return m_private->m24(); + return m_private.m24(); } void WebTransformationMatrix::setM24(double f) { - m_private->setM24(f); + m_private.setM24(f); } double WebTransformationMatrix::m31() const { - return m_private->m31(); + return m_private.m31(); } void WebTransformationMatrix::setM31(double f) { - m_private->setM31(f); + m_private.setM31(f); } double WebTransformationMatrix::m32() const { - return m_private->m32(); + return m_private.m32(); } void WebTransformationMatrix::setM32(double f) { - m_private->setM32(f); + m_private.setM32(f); } double WebTransformationMatrix::m33() const { - return m_private->m33(); + return m_private.m33(); } void WebTransformationMatrix::setM33(double f) { - m_private->setM33(f); + m_private.setM33(f); } double WebTransformationMatrix::m34() const { - return m_private->m34(); + return m_private.m34(); } void WebTransformationMatrix::setM34(double f) { - m_private->setM34(f); + m_private.setM34(f); } double WebTransformationMatrix::m41() const { - return m_private->m41(); + return m_private.m41(); } void WebTransformationMatrix::setM41(double f) { - m_private->setM41(f); + m_private.setM41(f); } double WebTransformationMatrix::m42() const { - return m_private->m42(); + return m_private.m42(); } void WebTransformationMatrix::setM42(double f) { - m_private->setM42(f); + m_private.setM42(f); } double WebTransformationMatrix::m43() const { - return m_private->m43(); + return m_private.m43(); } void WebTransformationMatrix::setM43(double f) { - m_private->setM43(f); + m_private.setM43(f); } double WebTransformationMatrix::m44() const { - return m_private->m44(); + return m_private.m44(); } void WebTransformationMatrix::setM44(double f) { - m_private->setM44(f); + m_private.setM44(f); } double WebTransformationMatrix::a() const { - return m_private->a(); + return m_private.a(); } void WebTransformationMatrix::setA(double a) { - m_private->setA(a); + m_private.setA(a); } double WebTransformationMatrix::b() const { - return m_private->b(); + return m_private.b(); } void WebTransformationMatrix::setB(double b) { - m_private->setB(b); + m_private.setB(b); } double WebTransformationMatrix::c() const { - return m_private->c(); + return m_private.c(); } void WebTransformationMatrix::setC(double c) { - m_private->setC(c); + m_private.setC(c); } double WebTransformationMatrix::d() const { - return m_private->d(); + return m_private.d(); } void WebTransformationMatrix::setD(double d) { - m_private->setD(d); + m_private.setD(d); } double WebTransformationMatrix::e() const { - return m_private->e(); + return m_private.e(); } void WebTransformationMatrix::setE(double e) { - m_private->setE(e); + m_private.setE(e); } double WebTransformationMatrix::f() const { - return m_private->f(); + return m_private.f(); } void WebTransformationMatrix::setF(double f) { - m_private->setF(f); + m_private.setF(f); } -TransformationMatrix& WebTransformationMatrix::toWebCoreTransform() const +TransformationMatrix WebTransformationMatrix::toWebCoreTransform() const { - return *m_private.get(); + return m_private; } FloatRect WebTransformationMatrix::mapRect(const FloatRect& rect) const { - return m_private->mapRect(rect); + return m_private.mapRect(rect); } IntRect WebTransformationMatrix::mapRect(const IntRect& rect) const { - return m_private->mapRect(rect); + return m_private.mapRect(rect); } FloatPoint3D WebTransformationMatrix::mapPoint(const FloatPoint3D& p) const { - return m_private->mapPoint(p); + return m_private.mapPoint(p); } FloatPoint WebTransformationMatrix::mapPoint(const FloatPoint& p) const { - return m_private->mapPoint(p); + return m_private.mapPoint(p); } IntPoint WebTransformationMatrix::mapPoint(const IntPoint& p) const { - return m_private->mapPoint(p); + return m_private.mapPoint(p); } FloatQuad WebTransformationMatrix::mapQuad(const FloatQuad& quad) const { - return m_private->mapQuad(quad); + return m_private.mapQuad(quad); } FloatPoint WebTransformationMatrix::projectPoint(const FloatPoint& p, bool* clamped) const { - return m_private->projectPoint(p, clamped); + return m_private.projectPoint(p, clamped); } } // namespace WebKit diff --git a/Source/WebCore/platform/efl/EflKeyboardUtilities.cpp b/Source/WebCore/platform/efl/EflKeyboardUtilities.cpp index 16b2c6ad9..65c7b4968 100644 --- a/Source/WebCore/platform/efl/EflKeyboardUtilities.cpp +++ b/Source/WebCore/platform/efl/EflKeyboardUtilities.cpp @@ -215,22 +215,6 @@ String keyIdentifierForEvasKeyName(const String& keyName) return keyName; } -String singleCharacterString(const String& keyName) -{ - if (keyName == "Return") - return String("\r"); - if (keyName == "BackSpace") - return String("\x8"); - if (keyName == "Tab") - return String("\t"); - if (keyName == "Print") - return String(""); - if (keyName == "Escape") - return String("\x1b"); - - return keyName; -} - int windowsKeyCodeForEvasKeyName(const String& keyName) { if (windowsKeyMap().isEmpty()) diff --git a/Source/WebCore/platform/efl/PlatformKeyboardEventEfl.cpp b/Source/WebCore/platform/efl/PlatformKeyboardEventEfl.cpp index 7487948d2..dc7969969 100644 --- a/Source/WebCore/platform/efl/PlatformKeyboardEventEfl.cpp +++ b/Source/WebCore/platform/efl/PlatformKeyboardEventEfl.cpp @@ -42,8 +42,8 @@ namespace WebCore { PlatformKeyboardEvent::PlatformKeyboardEvent(const Evas_Event_Key_Down* event) : PlatformEvent(PlatformEvent::KeyDown, evas_key_modifier_is_set(event->modifiers, "Shift"), evas_key_modifier_is_set(event->modifiers, "Control"), evas_key_modifier_is_set(event->modifiers, "Alt"), evas_key_modifier_is_set(event->modifiers, "Meta"), currentTime()) - , m_text(singleCharacterString(String::fromUTF8(event->string))) - , m_unmodifiedText(singleCharacterString(String::fromUTF8(event->string))) + , m_text(String::fromUTF8(event->string)) + , m_unmodifiedText(String::fromUTF8(event->string)) , m_keyIdentifier(keyIdentifierForEvasKeyName(String(event->key))) , m_windowsVirtualKeyCode(windowsKeyCodeForEvasKeyName(String(event->key))) , m_nativeVirtualKeyCode(0) @@ -56,8 +56,8 @@ PlatformKeyboardEvent::PlatformKeyboardEvent(const Evas_Event_Key_Down* event) PlatformKeyboardEvent::PlatformKeyboardEvent(const Evas_Event_Key_Up* event) : PlatformEvent(PlatformEvent::KeyUp, evas_key_modifier_is_set(event->modifiers, "Shift"), evas_key_modifier_is_set(event->modifiers, "Control"), evas_key_modifier_is_set(event->modifiers, "Alt"), evas_key_modifier_is_set(event->modifiers, "Meta"), currentTime()) - , m_text(singleCharacterString(String::fromUTF8(event->string))) - , m_unmodifiedText(singleCharacterString(String::fromUTF8(event->string))) + , m_text(String::fromUTF8(event->string)) + , m_unmodifiedText(String::fromUTF8(event->string)) , m_keyIdentifier(keyIdentifierForEvasKeyName(String(event->key))) , m_windowsVirtualKeyCode(windowsKeyCodeForEvasKeyName(String(event->key))) , m_nativeVirtualKeyCode(0) diff --git a/Source/WebCore/platform/efl/RenderThemeEfl.cpp b/Source/WebCore/platform/efl/RenderThemeEfl.cpp index 68a7eaa93..8766f6578 100644 --- a/Source/WebCore/platform/efl/RenderThemeEfl.cpp +++ b/Source/WebCore/platform/efl/RenderThemeEfl.cpp @@ -295,7 +295,8 @@ void RenderThemeEfl::applyEdjeStateFromForm(Evas_Object* object, ControlStates s "read-only", "default", "window-inactive", - "indeterminate" + "indeterminate", + "spinup" }; edje_object_signal_emit(object, "reset", ""); @@ -579,6 +580,7 @@ const char* RenderThemeEfl::edjeGroupFromFormType(FormType type) const W("mediacontrol/seekbackward_button"), W("mediacontrol/fullscreen_button"), #endif + W("spinner"), #undef W 0 }; @@ -983,6 +985,20 @@ bool RenderThemeEfl::paintSearchField(RenderObject* object, const PaintInfo& inf return paintThemePart(object, SearchField, info, rect); } +void RenderThemeEfl::adjustInnerSpinButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const +{ + if (!m_page && element && element->document()->page()) { + static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustInnerSpinButtonStyle(styleResolver, style, element); + return; + } + adjustSizeConstraints(style, Spinner); +} + +bool RenderThemeEfl::paintInnerSpinButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) +{ + return paintThemePart(object, Spinner, info, rect); +} + void RenderThemeEfl::setDefaultFontSize(int size) { defaultFontSize = size; diff --git a/Source/WebCore/platform/efl/RenderThemeEfl.h b/Source/WebCore/platform/efl/RenderThemeEfl.h index 7e0ff3930..a31598e9e 100644 --- a/Source/WebCore/platform/efl/RenderThemeEfl.h +++ b/Source/WebCore/platform/efl/RenderThemeEfl.h @@ -65,6 +65,7 @@ enum FormType { // KEEP IN SYNC WITH edjeGroupFromFormType() SeekBackwardButton, FullScreenButton, #endif + Spinner, FormTypeLast }; @@ -162,6 +163,9 @@ public: virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&); + virtual void adjustInnerSpinButtonStyle(StyleResolver*, RenderStyle*, Element*) const; + virtual bool paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&); + static void setDefaultFontSize(int fontsize); #if ENABLE(PROGRESS_TAG) diff --git a/Source/WebCore/platform/graphics/GeneratorGeneratedImage.cpp b/Source/WebCore/platform/graphics/GeneratorGeneratedImage.cpp index dd706b00f..f337dd0e7 100644 --- a/Source/WebCore/platform/graphics/GeneratorGeneratedImage.cpp +++ b/Source/WebCore/platform/graphics/GeneratorGeneratedImage.cpp @@ -90,4 +90,10 @@ void GeneratedImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicRatio = FloatSize(); } +void GeneratorGeneratedImage::invalidateCacheTimerFired(DeferrableOneShotTimer<GeneratorGeneratedImage>*) +{ + m_cachedImageBuffer.clear(); + m_cachedAdjustedSize = IntSize(); +} + } diff --git a/Source/WebCore/platform/graphics/GeneratorGeneratedImage.h b/Source/WebCore/platform/graphics/GeneratorGeneratedImage.h index f3b9595d3..55ac38d3a 100644 --- a/Source/WebCore/platform/graphics/GeneratorGeneratedImage.h +++ b/Source/WebCore/platform/graphics/GeneratorGeneratedImage.h @@ -58,49 +58,19 @@ protected: virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect); + void invalidateCacheTimerFired(DeferrableOneShotTimer<GeneratorGeneratedImage>*); + GeneratorGeneratedImage(PassRefPtr<Generator> generator, const IntSize& size) : m_generator(generator) - , m_cacheTimer(this) + , m_cacheTimer(this, &GeneratorGeneratedImage::invalidateCacheTimerFired, generatedImageCacheClearDelay) { m_size = size; } - - class GeneratedImageCacheTimer : public TimerBase { - public: - GeneratedImageCacheTimer(GeneratorGeneratedImage * parent) - : m_shouldRestartWhenTimerFires(false) - , m_parent(parent) { } - - void restart() - { - if (isActive()) { - m_shouldRestartWhenTimerFires = true; - return; - } - startOneShot(generatedImageCacheClearDelay); - }; - private: - virtual void fired() OVERRIDE - { - if (m_shouldRestartWhenTimerFires) { - m_shouldRestartWhenTimerFires = false; - startOneShot(generatedImageCacheClearDelay); - return; - } - - if (m_parent) { - m_parent->m_cachedImageBuffer.clear(); - m_parent->m_cachedAdjustedSize = IntSize(); - } - }; - bool m_shouldRestartWhenTimerFires; - GeneratorGeneratedImage* m_parent; - }; RefPtr<Generator> m_generator; OwnPtr<ImageBuffer> m_cachedImageBuffer; - GeneratedImageCacheTimer m_cacheTimer; + DeferrableOneShotTimer<GeneratorGeneratedImage> m_cacheTimer; IntSize m_cachedAdjustedSize; unsigned m_cachedGeneratorHash; }; diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h index 692da56a5..b0bc5c009 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext3D.h +++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h @@ -68,7 +68,7 @@ typedef unsigned int GLuint; #if PLATFORM(MAC) typedef CGLContextObj PlatformGraphicsContext3D; #elif PLATFORM(QT) -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) typedef QOpenGLContext* PlatformGraphicsContext3D; typedef QSurface* PlatformGraphicsSurface3D; #else diff --git a/Source/WebCore/platform/graphics/Image.cpp b/Source/WebCore/platform/graphics/Image.cpp index bb7d3f73c..0ace7ac20 100644 --- a/Source/WebCore/platform/graphics/Image.cpp +++ b/Source/WebCore/platform/graphics/Image.cpp @@ -167,6 +167,23 @@ void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& dstRect, const Flo startAnimation(); } +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) +FloatRect Image::adjustSourceRectForDownSampling(const FloatRect& srcRect, const IntSize& scaledSize) const +{ + const IntSize unscaledSize = size(); + if (unscaledSize == scaledSize) + return srcRect; + + // Image has been down-sampled. + float xscale = static_cast<float>(scaledSize.width()) / unscaledSize.width(); + float yscale = static_cast<float>(scaledSize.height()) / unscaledSize.height(); + FloatRect scaledSrcRect = srcRect; + scaledSrcRect.scale(xscale, yscale); + + return scaledSrcRect; +} +#endif + void Image::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) { intrinsicRatio = size(); diff --git a/Source/WebCore/platform/graphics/Image.h b/Source/WebCore/platform/graphics/Image.h index b78fc7d81..3ff48236a 100644 --- a/Source/WebCore/platform/graphics/Image.h +++ b/Source/WebCore/platform/graphics/Image.h @@ -163,6 +163,10 @@ public: virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect); +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + FloatRect adjustSourceRectForDownSampling(const FloatRect& srcRect, const IntSize& scaledSize) const; +#endif + #if !ASSERT_DISABLED virtual bool notSolidColor() { return true; } #endif diff --git a/Source/WebCore/platform/graphics/ImageSource.cpp b/Source/WebCore/platform/graphics/ImageSource.cpp index ff9fe0d9f..75ed5a1a2 100644 --- a/Source/WebCore/platform/graphics/ImageSource.cpp +++ b/Source/WebCore/platform/graphics/ImageSource.cpp @@ -29,11 +29,7 @@ #include "config.h" #include "ImageSource.h" -#if PLATFORM(QT) -#include "ImageDecoderQt.h" -#else #include "ImageDecoder.h" -#endif #include "ImageOrientation.h" #include "NotImplemented.h" diff --git a/Source/WebCore/platform/graphics/ImageSource.h b/Source/WebCore/platform/graphics/ImageSource.h index 6d01c8605..ed625bc66 100644 --- a/Source/WebCore/platform/graphics/ImageSource.h +++ b/Source/WebCore/platform/graphics/ImageSource.h @@ -70,10 +70,6 @@ class ImageDecoder; class TiledImageOpenVG; typedef ImageDecoder* NativeImageSourcePtr; typedef TiledImageOpenVG* NativeImagePtr; -#elif PLATFORM(QT) -class ImageDecoderQt; -typedef ImageDecoderQt* NativeImageSourcePtr; -typedef QPixmap* NativeImagePtr; #else class ImageDecoder; typedef ImageDecoder* NativeImageSourcePtr; @@ -93,6 +89,8 @@ typedef RefPtr<SharedBitmap> NativeImagePtr; class ImageDecoder; typedef ImageDecoder* NativeImageSourcePtr; typedef void* NativeImagePtr; +#elif PLATFORM(QT) +typedef QPixmap* NativeImagePtr; #endif #endif diff --git a/Source/WebCore/platform/graphics/MediaPlayer.cpp b/Source/WebCore/platform/graphics/MediaPlayer.cpp index af30eb123..9357330e4 100644 --- a/Source/WebCore/platform/graphics/MediaPlayer.cpp +++ b/Source/WebCore/platform/graphics/MediaPlayer.cpp @@ -131,7 +131,7 @@ public: virtual PassRefPtr<TimeRanges> buffered() const { return TimeRanges::create(); } virtual unsigned totalBytes() const { return 0; } - virtual unsigned bytesLoaded() const { return 0; } + virtual bool didLoadingProgress() const { return false; } virtual void setSize(const IntSize&) { } @@ -681,9 +681,9 @@ float MediaPlayer::maxTimeSeekable() return m_private->maxTimeSeekable(); } -unsigned MediaPlayer::bytesLoaded() +bool MediaPlayer::didLoadingProgress() { - return m_private->bytesLoaded(); + return m_private->didLoadingProgress(); } void MediaPlayer::setSize(const IntSize& size) diff --git a/Source/WebCore/platform/graphics/MediaPlayer.h b/Source/WebCore/platform/graphics/MediaPlayer.h index a03ade71c..516f2fe98 100644 --- a/Source/WebCore/platform/graphics/MediaPlayer.h +++ b/Source/WebCore/platform/graphics/MediaPlayer.h @@ -278,7 +278,7 @@ public: PassRefPtr<TimeRanges> seekable(); float maxTimeSeekable(); - unsigned bytesLoaded(); + bool didLoadingProgress(); float volume() const; void setVolume(float); diff --git a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h index f76d49e23..085278e3e 100644 --- a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h +++ b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h @@ -96,7 +96,7 @@ public: virtual float maxTimeSeekable() const = 0; virtual PassRefPtr<TimeRanges> buffered() const = 0; - virtual unsigned bytesLoaded() const = 0; + virtual bool didLoadingProgress() const = 0; virtual void setSize(const IntSize&) = 0; diff --git a/Source/WebCore/platform/graphics/OpenGLShims.cpp b/Source/WebCore/platform/graphics/OpenGLShims.cpp index f59f26c60..a23dc6895 100644 --- a/Source/WebCore/platform/graphics/OpenGLShims.cpp +++ b/Source/WebCore/platform/graphics/OpenGLShims.cpp @@ -42,7 +42,7 @@ OpenGLFunctionTable* openGLFunctionTable() #if PLATFORM(QT) static void* getProcAddress(const char* procName) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) return reinterpret_cast<void*>(QOpenGLContext::currentContext()->getProcAddress(procName)); #else return reinterpret_cast<void*>(QGLContext::currentContext()->getProcAddress(QString::fromLatin1(procName))); diff --git a/Source/WebCore/platform/graphics/OpenGLShims.h b/Source/WebCore/platform/graphics/OpenGLShims.h index 1d5f37d9e..706f17d9b 100644 --- a/Source/WebCore/platform/graphics/OpenGLShims.h +++ b/Source/WebCore/platform/graphics/OpenGLShims.h @@ -22,7 +22,7 @@ #if PLATFORM(QT) #include <qglobal.h> -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) #include <qopenglfunctions.h> #include <QOpenGLContext> #include <QSurface> diff --git a/Source/WebCore/platform/graphics/Path.cpp b/Source/WebCore/platform/graphics/Path.cpp index 52153e571..97960f4b6 100644 --- a/Source/WebCore/platform/graphics/Path.cpp +++ b/Source/WebCore/platform/graphics/Path.cpp @@ -105,13 +105,20 @@ void Path::addRoundedRect(const FloatRect& rect, const FloatSize& roundingRadii, FloatSize radius(roundingRadii); FloatSize halfSize(rect.width() / 2, rect.height() / 2); - // If rx is greater than half of the width of the rectangle - // then set rx to half of the width (required in SVG spec) + // Apply the SVG corner radius constraints, per the rect section of the SVG shapes spec: if + // one of rx,ry is negative, then the other corner radius value is used. If both values are + // negative then rx = ry = 0. If rx is greater than half of the width of the rectangle + // then set rx to half of the width; ry is handled similarly. + + if (radius.width() < 0) + radius.setWidth((radius.height() < 0) ? 0 : radius.height()); + + if (radius.height() < 0) + radius.setHeight(radius.width()); + if (radius.width() > halfSize.width()) radius.setWidth(halfSize.width()); - // If ry is greater than half of the height of the rectangle - // then set ry to half of the height (required in SVG spec) if (radius.height() > halfSize.height()) radius.setHeight(halfSize.height()); diff --git a/Source/WebCore/platform/graphics/Path.h b/Source/WebCore/platform/graphics/Path.h index 96c810425..a33ab4c8b 100644 --- a/Source/WebCore/platform/graphics/Path.h +++ b/Source/WebCore/platform/graphics/Path.h @@ -159,6 +159,10 @@ namespace WebCore { void platformAddPathForRoundedRect(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius); #endif +#if PLATFORM(BLACKBERRY) + Path(const SkPath&); +#endif + private: PlatformPathPtr m_path; }; diff --git a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp index 8f3a8dffb..73134ed2a 100644 --- a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp +++ b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp @@ -57,6 +57,7 @@ MediaPlayerPrivateAVFoundation::MediaPlayerPrivateAVFoundation(MediaPlayer* play , m_cachedMaxTimeSeekable(0) , m_cachedDuration(invalidTime()) , m_reportedDuration(invalidTime()) + , m_maxTimeLoadedAtLastDidLoadingProgress(invalidTime()) , m_seekTo(invalidTime()) , m_requestedRate(1) , m_delayCallbacks(0) @@ -366,14 +367,15 @@ float MediaPlayerPrivateAVFoundation::maxTimeLoaded() const return m_cachedMaxTimeLoaded; } -unsigned MediaPlayerPrivateAVFoundation::bytesLoaded() const +bool MediaPlayerPrivateAVFoundation::didLoadingProgress() const { - float dur = duration(); - if (!dur) - return 0; - unsigned loaded = totalBytes() * maxTimeLoaded() / dur; - LOG(Media, "MediaPlayerPrivateAVFoundation::bytesLoaded(%p) - returning %i", this, loaded); - return loaded; + if (!duration() || !totalBytes()) + return false; + float currentMaxTimeLoaded = maxTimeLoaded(); + bool didLoadingProgress = currentMaxTimeLoaded != m_maxTimeLoadedAtLastDidLoadingProgress; + m_maxTimeLoadedAtLastDidLoadingProgress = currentMaxTimeLoaded; + LOG(Media, "MediaPlayerPrivateAVFoundation::didLoadingProgress(%p) - returning %d", this, didLoadingProgress); + return didLoadingProgress; } bool MediaPlayerPrivateAVFoundation::isReadyForVideoSetup() const diff --git a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h index 72302346f..63fe6aa4e 100644 --- a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h +++ b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h @@ -140,7 +140,7 @@ protected: virtual MediaPlayer::ReadyState readyState() const { return m_readyState; } virtual float maxTimeSeekable() const; virtual PassRefPtr<TimeRanges> buffered() const; - virtual unsigned bytesLoaded() const; + virtual bool didLoadingProgress() const; virtual void setSize(const IntSize&); virtual void paint(GraphicsContext*, const IntRect&) = 0; virtual void paintCurrentFrameInContext(GraphicsContext*, const IntRect&) = 0; @@ -263,7 +263,7 @@ private: mutable float m_cachedMaxTimeSeekable; mutable float m_cachedDuration; float m_reportedDuration; - + mutable float m_maxTimeLoadedAtLastDidLoadingProgress; float m_seekTo; float m_requestedRate; mutable int m_delayCallbacks; diff --git a/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp b/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp index 7ef896d1c..4d4a2ca20 100644 --- a/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp +++ b/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp @@ -36,6 +36,7 @@ #include "LayerCompositingThread.h" +#include "LayerCompositingThreadClient.h" #include "LayerMessage.h" #include "LayerRenderer.h" #include "LayerWebKitThread.h" @@ -54,12 +55,22 @@ namespace WebCore { -PassRefPtr<LayerCompositingThread> LayerCompositingThread::create(LayerType type, PassRefPtr<LayerTiler> tiler) +void LayerOverride::removeAnimation(const String& name) { - return adoptRef(new LayerCompositingThread(type, tiler)); + for (size_t i = 0; i < m_animations.size(); ++i) { + if (m_animations[i]->name() == name) { + m_animations.remove(i); + return; + } + } } -LayerCompositingThread::LayerCompositingThread(LayerType type, PassRefPtr<LayerTiler> tiler) +PassRefPtr<LayerCompositingThread> LayerCompositingThread::create(LayerType type, LayerCompositingThreadClient* client) +{ + return adoptRef(new LayerCompositingThread(type, client)); +} + +LayerCompositingThread::LayerCompositingThread(LayerType type, LayerCompositingThreadClient* client) : LayerData(type) , m_layerRenderer(0) , m_superlayer(0) @@ -67,7 +78,7 @@ LayerCompositingThread::LayerCompositingThread(LayerType type, PassRefPtr<LayerT , m_drawOpacity(0) , m_visible(false) , m_commitScheduled(false) - , m_tiler(tiler) + , m_client(client) { } @@ -75,8 +86,6 @@ LayerCompositingThread::~LayerCompositingThread() { ASSERT(isCompositingThread()); - m_tiler->layerCompositingThreadDestroyed(); - ASSERT(!superlayer()); // Remove the superlayer reference from all sublayers. @@ -90,6 +99,9 @@ LayerCompositingThread::~LayerCompositingThread() // layer renderer to track us anymore if (m_layerRenderer) m_layerRenderer->removeLayer(this); + + if (m_client) + m_client->layerCompositingThreadDestroyed(this); } void LayerCompositingThread::setLayerRenderer(LayerRenderer* renderer) @@ -106,15 +118,22 @@ void LayerCompositingThread::deleteTextures() { releaseTextureResources(); - m_tiler->deleteTextures(); + if (m_client) + m_client->deleteTextures(this); } -void LayerCompositingThread::setDrawTransform(const TransformationMatrix& matrix) +void LayerCompositingThread::setDrawTransform(double scale, const TransformationMatrix& matrix) { m_drawTransform = matrix; float bx = m_bounds.width() / 2.0; float by = m_bounds.height() / 2.0; + + if (sizeIsScaleInvariant()) { + bx /= scale; + by /= scale; + } + m_transformedBounds.setP1(matrix.mapPoint(FloatPoint(-bx, -by))); m_transformedBounds.setP2(matrix.mapPoint(FloatPoint(-bx, by))); m_transformedBounds.setP3(matrix.mapPoint(FloatPoint(bx, by))); @@ -185,9 +204,9 @@ FloatQuad LayerCompositingThread::getTransformedHolePunchRect() const return getTransformedRect(m_bounds, drawRect, m_drawTransform); } -void LayerCompositingThread::drawTextures(int positionLocation, int texCoordLocation, const FloatRect& visibleRect) +void LayerCompositingThread::drawTextures(double scale, int positionLocation, int texCoordLocation, const FloatRect& visibleRect) { - float texcoords[4 * 2] = { 0, 0, 0, 1, 1, 1, 1, 0 }; + static float texcoords[4 * 2] = { 0, 0, 0, 1, 1, 1, 1, 0 }; if (m_pluginView) { if (m_isVisible) { @@ -256,7 +275,8 @@ void LayerCompositingThread::drawTextures(int positionLocation, int texCoordLoca return; } - m_tiler->drawTextures(this, positionLocation, texCoordLocation); + if (m_client) + m_client->drawTextures(this, scale, positionLocation, texCoordLocation); } void LayerCompositingThread::drawSurface(const TransformationMatrix& drawTransform, LayerCompositingThread* mask, int positionLocation, int texCoordLocation) @@ -279,23 +299,21 @@ void LayerCompositingThread::drawSurface(const TransformationMatrix& drawTransfo FloatQuad surfaceQuad = getTransformedRect(m_bounds, IntRect(IntPoint::zero(), m_bounds), drawTransform); glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, &surfaceQuad); - float texcoords[4 * 2] = { 0, 0, 0, 1, 1, 1, 1, 0 }; + static float texcoords[4 * 2] = { 0, 0, 0, 1, 1, 1, 1, 0 }; glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } -void LayerCompositingThread::drawMissingTextures(int positionLocation, int texCoordLocation, const FloatRect& visibleRect) +bool LayerCompositingThread::hasMissingTextures() const { - if (m_pluginView || m_texID) - return; - -#if ENABLE(VIDEO) - if (m_mediaPlayer) - return; -#endif + return m_client ? m_client->hasMissingTextures(this) : false; +} - m_tiler->drawMissingTextures(this, positionLocation, texCoordLocation); +void LayerCompositingThread::drawMissingTextures(double scale, int positionLocation, int texCoordLocation, const FloatRect& /*visibleRect*/) +{ + if (m_client) + m_client->drawMissingTextures(this, scale, positionLocation, texCoordLocation); } void LayerCompositingThread::releaseTextureResources() @@ -380,6 +398,13 @@ const LayerCompositingThread* LayerCompositingThread::rootLayer() const return layer; } +void LayerCompositingThread::addSublayer(LayerCompositingThread* layer) +{ + layer->removeFromSuperlayer(); + layer->setSuperlayer(this); + m_sublayers.append(layer); +} + void LayerCompositingThread::removeFromSuperlayer() { if (m_superlayer) @@ -410,15 +435,14 @@ void LayerCompositingThread::setSublayers(const Vector<RefPtr<LayerCompositingTh void LayerCompositingThread::updateTextureContentsIfNeeded() { - if (m_texID || pluginView()) - return; - -#if ENABLE(VIDEO) - if (mediaPlayer()) - return; -#endif + if (m_client) + m_client->uploadTexturesIfNeeded(this); +} - m_tiler->uploadTexturesIfNeeded(); +void LayerCompositingThread::bindContentsTexture() +{ + if (m_client) + m_client->bindContentsTexture(this); } void LayerCompositingThread::setVisible(bool visible) @@ -428,15 +452,8 @@ void LayerCompositingThread::setVisible(bool visible) m_visible = visible; - if (m_texID || pluginView()) - return; - -#if ENABLE(VIDEO) - if (mediaPlayer()) - return; -#endif - - m_tiler->layerVisibilityChanged(visible); + if (m_client) + m_client->layerVisibilityChanged(this, visible); } void LayerCompositingThread::setNeedsCommit() @@ -447,6 +464,9 @@ void LayerCompositingThread::setNeedsCommit() void LayerCompositingThread::scheduleCommit() { + if (!m_client) + return; + if (!isWebKitThread()) { if (m_commitScheduled) return; @@ -459,9 +479,7 @@ void LayerCompositingThread::scheduleCommit() m_commitScheduled = false; - // FIXME: The only way to get at our LayerWebKitThread is to go through the tiler. - if (LayerWebKitThread* layer = m_tiler->layer()) - layer->setNeedsCommit(); + m_client->scheduleCommit(); } bool LayerCompositingThread::updateAnimations(double currentTime) @@ -484,7 +502,30 @@ bool LayerCompositingThread::updateAnimations(double currentTime) animation->apply(this, elapsedTime); } - return !m_runningAnimations.isEmpty(); + bool hasRunningAnimations = !m_runningAnimations.isEmpty(); + + // If there are any overrides, apply them + if (m_override) { + if (m_override->isPositionSet()) + m_position = m_override->position(); + if (m_override->isAnchorPointSet()) + m_anchorPoint = m_override->anchorPoint(); + if (m_override->isBoundsSet()) + m_bounds = m_override->bounds(); + if (m_override->isTransformSet()) + m_transform = m_override->transform(); + if (m_override->isOpacitySet()) + m_opacity = m_override->opacity(); + + for (size_t i = 0; i < m_override->animations().size(); ++i) { + LayerAnimation* animation = m_override->animations()[i].get(); + double elapsedTime = (m_suspendTime ? m_suspendTime : currentTime) - animation->startTime() + animation->timeOffset(); + animation->apply(this, elapsedTime); + hasRunningAnimations |= true; + } + } + + return hasRunningAnimations; } bool LayerCompositingThread::hasVisibleHolePunchRect() const @@ -506,6 +547,28 @@ void LayerCompositingThread::createLayerRendererSurface() m_layerRendererSurface = adoptPtr(new LayerRendererSurface(m_layerRenderer, this)); } +void LayerCompositingThread::removeAnimation(const String& name) +{ + for (size_t i = 0; i < m_runningAnimations.size(); ++i) { + if (m_runningAnimations[i]->name() == name) { + m_runningAnimations.remove(i); + return; + } + } +} + +LayerOverride* LayerCompositingThread::override() +{ + if (!m_override) + m_override = LayerOverride::create(); + return m_override.get(); +} + +void LayerCompositingThread::clearOverride() +{ + m_override.clear(); +} + } #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.h b/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.h index b8470094f..b33560669 100644 --- a/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.h +++ b/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.h @@ -36,6 +36,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "FloatQuad.h" +#include "LayerAnimation.h" #include "LayerData.h" #include "LayerRendererSurface.h" #include "LayerTiler.h" @@ -53,11 +54,65 @@ class Buffer; namespace WebCore { +class LayerCompositingThreadClient; class LayerRenderer; +class LayerOverride { +public: + static PassOwnPtr<LayerOverride> create() { return adoptPtr(new LayerOverride()); } + + bool isPositionSet() const { return m_positionSet; } + FloatPoint position() const { return m_position; } + void setPosition(const FloatPoint& position) { m_position = position; m_positionSet = true; } + + bool isAnchorPointSet() const { return m_anchorPointSet; } + FloatPoint anchorPoint() const { return m_anchorPoint; } + void setAnchorPoint(const FloatPoint& anchorPoint) { m_anchorPoint = anchorPoint; m_anchorPointSet = true; } + + bool isBoundsSet() const { return m_boundsSet; } + IntSize bounds() const { return m_bounds; } + void setBounds(const IntSize&) { m_bounds = bounds; m_boundsSet = true; } + + bool isTransformSet() const { return m_transformSet; } + const TransformationMatrix& transform() const { return m_transform; } + void setTransform(const TransformationMatrix& transform) { m_transform = transform; m_transformSet = true; } + + bool isOpacitySet() const { return m_opacitySet; } + float opacity() const { return m_opacity; } + void setOpacity(float) { m_opacity = opacity; m_opacitySet = true; } + + const Vector<RefPtr<LayerAnimation> >& animations() const { return m_animations; } + void addAnimation(PassRefPtr<LayerAnimation> animation) { m_animations.append(animation); } + void removeAnimation(const String& name); + +private: + LayerOverride() + : m_opacity(1.0) + , m_positionSet(false) + , m_anchorPointSet(false) + , m_boundsSet(false) + , m_transformSet(false) + , m_opacitySet(false) + { + } + + FloatPoint m_position; + FloatPoint m_anchorPoint; + IntSize m_bounds; + TransformationMatrix m_transform; + float m_opacity; + Vector<RefPtr<LayerAnimation> > m_animations; + + unsigned m_positionSet : 1; + unsigned m_anchorPointSet : 1; + unsigned m_boundsSet : 1; + unsigned m_transformSet : 1; + unsigned m_opacitySet : 1; +}; + class LayerCompositingThread : public ThreadSafeRefCounted<LayerCompositingThread>, public LayerData, public BlackBerry::Platform::GuardedPointerBase { public: - static PassRefPtr<LayerCompositingThread> create(LayerType, PassRefPtr<LayerTiler>); + static PassRefPtr<LayerCompositingThread> create(LayerType, LayerCompositingThreadClient*); // Thread safe void setPluginView(PluginView*); @@ -68,14 +123,23 @@ public: // Not thread safe + // These will be overwritten on the next commit if this layer has a LayerWebKitThread counterpart. + // Useful for stand-alone layers that are created and managed on the compositing thread. + // These functions can also be used to update animated properties in LayerAnimation. + void setPosition(const FloatPoint& position) { m_position = position; } + void setAnchorPoint(const FloatPoint& anchorPoint) { m_anchorPoint = anchorPoint; } + void setBounds(const IntSize& bounds) { m_bounds = bounds; } + void setSizeIsScaleInvariant(bool invariant) { m_sizeIsScaleInvariant = invariant; } + void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; } + void setOpacity(float opacity) { m_opacity = opacity; } + void addSublayer(LayerCompositingThread*); + void removeFromSuperlayer(); + void setNeedsTexture(bool needsTexture) { m_needsTexture = needsTexture; } + // Returns true if we have an animation bool updateAnimations(double currentTime); void updateTextureContentsIfNeeded(); - void bindContentsTexture() - { - if (m_tiler) - m_tiler->bindContentsTexture(); - } + void bindContentsTexture(); const LayerCompositingThread* rootLayer() const; void setSublayers(const Vector<RefPtr<LayerCompositingThread> >&); @@ -86,7 +150,7 @@ public: // The layer renderer must be set if the layer has been rendered void setLayerRenderer(LayerRenderer*); - void setDrawTransform(const TransformationMatrix&); + void setDrawTransform(double scale, const TransformationMatrix&); const TransformationMatrix& drawTransform() const { return m_drawTransform; } void setDrawOpacity(float opacity) { m_drawOpacity = opacity; } @@ -108,11 +172,10 @@ public: void deleteTextures(); - void drawTextures(int positionLocation, int texCoordLocation, const FloatRect& visibleRect); - bool hasMissingTextures() const { return m_tiler ? m_tiler->hasMissingTextures() : false; } - void drawMissingTextures(int positionLocation, int texCoordLocation, const FloatRect& visibleRect); + void drawTextures(double scale, int positionLocation, int texCoordLocation, const FloatRect& visibleRect); + bool hasMissingTextures() const; + void drawMissingTextures(double scale, int positionLocation, int texCoordLocation, const FloatRect& visibleRect); void drawSurface(const TransformationMatrix&, LayerCompositingThread* mask, int positionLocation, int texCoordLocation); - bool isDirty() const { return m_tiler ? m_tiler->hasDirtyTiles() : false; } void releaseTextureResources(); @@ -131,26 +194,27 @@ public: // this allows you to do it from the compositing thread. void scheduleCommit(); - // These two functions are used to update animated properties in LayerAnimation. - void setOpacity(float opacity) { m_opacity = opacity; } - void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; } - bool hasRunningAnimations() const { return !m_runningAnimations.isEmpty(); } bool hasVisibleHolePunchRect() const; + void addAnimation(LayerAnimation* animation) { m_runningAnimations.append(animation); } + void removeAnimation(const String& name); + + void setRunningAnimations(const Vector<RefPtr<LayerAnimation> >& animations) { m_runningAnimations = animations; } + void setSuspendedAnimations(const Vector<RefPtr<LayerAnimation> >& animations) { m_suspendedAnimations = animations; } + + LayerOverride* override(); + void clearOverride(); + protected: virtual ~LayerCompositingThread(); private: - LayerCompositingThread(LayerType, PassRefPtr<LayerTiler>); + LayerCompositingThread(LayerType, LayerCompositingThreadClient*); void updateTileContents(const IntRect& tile); - void removeFromSuperlayer(); - - size_t numSublayers() const { return m_sublayers.size(); } - // Returns the index of the sublayer or -1 if not found. int indexOfSublayer(const LayerCompositingThread*); @@ -182,7 +246,11 @@ private: bool m_visible; bool m_commitScheduled; - RefPtr<LayerTiler> m_tiler; + Vector<RefPtr<LayerAnimation> > m_runningAnimations; + Vector<RefPtr<LayerAnimation> > m_suspendedAnimations; + + OwnPtr<LayerOverride> m_override; + LayerCompositingThreadClient* m_client; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/blackberry/LayerCompositingThreadClient.h b/Source/WebCore/platform/graphics/blackberry/LayerCompositingThreadClient.h new file mode 100644 index 000000000..746adea49 --- /dev/null +++ b/Source/WebCore/platform/graphics/blackberry/LayerCompositingThreadClient.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012 Research In Motion Limited. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LayerCompositingThreadClient_h +#define LayerCompositingThreadClient_h + +#if USE(ACCELERATED_COMPOSITING) + +namespace WebCore { + +class LayerCompositingThread; + +class LayerCompositingThreadClient { +public: + virtual ~LayerCompositingThreadClient() { } + + virtual void layerCompositingThreadDestroyed(LayerCompositingThread*) = 0; + + virtual void layerVisibilityChanged(LayerCompositingThread*, bool visible) = 0; + + virtual void uploadTexturesIfNeeded(LayerCompositingThread*) = 0; + virtual void drawTextures(LayerCompositingThread*, double scale, int positionLocation, int texCoordLocation) = 0; + virtual void deleteTextures(LayerCompositingThread*) = 0; + + // Optional. Allows layers to serve as a mask for other layers + virtual void bindContentsTexture(LayerCompositingThread*) { } + + // Optional. Allows layers to have uncached regions, typically drawn as checkerboard + virtual bool hasMissingTextures(const LayerCompositingThread*) const { return false; } + virtual void drawMissingTextures(LayerCompositingThread*, double scale, int positionLocation, int texCoordLocation) { } + + // Unlike the other methods here, this one will be called on the WebKit thread + virtual void scheduleCommit() { } +}; + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif diff --git a/Source/WebCore/platform/graphics/blackberry/LayerData.h b/Source/WebCore/platform/graphics/blackberry/LayerData.h index 2a55bcfe5..d99121551 100644 --- a/Source/WebCore/platform/graphics/blackberry/LayerData.h +++ b/Source/WebCore/platform/graphics/blackberry/LayerData.h @@ -37,7 +37,6 @@ #include "FloatPoint.h" #include "FloatRect.h" #include "IntRect.h" -#include "LayerAnimation.h" #include "PlatformString.h" #include "TransformationMatrix.h" #include <wtf/HashMap.h> @@ -54,7 +53,7 @@ class MediaPlayer; class LayerData { public: - enum LayerType { Layer, TransformLayer, WebGLLayer, CanvasLayer }; + enum LayerType { Layer, TransformLayer, WebGLLayer, CanvasLayer, CustomLayer }; enum FilterType { Linear, Nearest, Trilinear, Lanczos }; enum LayerProgramShader { LayerProgramShaderRGBA = 0, LayerProgramShaderBGRA, @@ -86,6 +85,7 @@ public: , m_hasFixedContainer(false) , m_hasFixedAncestorInDOMTree(false) , m_isVisible(true) + , m_sizeIsScaleInvariant(false) { } @@ -105,6 +105,8 @@ public: IntSize bounds() const { return m_bounds; } + bool sizeIsScaleInvariant() const { return m_sizeIsScaleInvariant; } + bool doubleSided() const { return m_doubleSided; } FloatRect frame() const { return m_frame; } @@ -191,8 +193,6 @@ protected: pthread_mutex_t* m_frontBufferLock; - Vector<RefPtr<LayerAnimation> > m_runningAnimations; - Vector<RefPtr<LayerAnimation> > m_suspendedAnimations; double m_suspendTime; unsigned m_doubleSided : 1; @@ -208,6 +208,7 @@ protected: // The following is only available for media (video) and plugin layers. unsigned m_isVisible : 1; + unsigned m_sizeIsScaleInvariant : 1; // CAUTION: all the data members are copied from one instance to another // i.e. from one thread to another in the replicate method. diff --git a/Source/WebCore/platform/graphics/blackberry/LayerRenderer.cpp b/Source/WebCore/platform/graphics/blackberry/LayerRenderer.cpp index 3235a92b8..f42144ec0 100644 --- a/Source/WebCore/platform/graphics/blackberry/LayerRenderer.cpp +++ b/Source/WebCore/platform/graphics/blackberry/LayerRenderer.cpp @@ -40,16 +40,16 @@ #include "PlatformString.h" #include "TextureCacheCompositingThread.h" +#include <BlackBerryPlatformGraphics.h> #include <BlackBerryPlatformLog.h> -#include <wtf/CurrentTime.h> +#include <limits> #include <wtf/text/CString.h> #define ENABLE_SCISSOR 1 #define DEBUG_SHADER_COMPILATION 0 -#define DEBUG_DIRTY_LAYERS 0 // Show dirty layers as red. #define DEBUG_LAYER_ANIMATIONS 0 // Show running animations as green. -#define DEBUG_VIDEO_CLIPPING 0 +#define DEBUG_CLIPPING 0 using BlackBerry::Platform::Graphics::GLES2Context; using namespace std; @@ -116,7 +116,7 @@ static GLuint loadShaderProgram(const char* vertexShaderSource, const char* frag return programObject; } -static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top, float nearZ, float farZ) +TransformationMatrix LayerRenderer::orthoMatrix(float left, float right, float bottom, float top, float nearZ, float farZ) { float deltaX = right - left; float deltaY = top - bottom; @@ -152,6 +152,8 @@ LayerRenderer::LayerRenderer(GLES2Context* context) , m_checkerProgramObject(0) , m_positionLocation(0) , m_texCoordLocation(1) + , m_scale(1.0) + , m_animationTime(-numeric_limits<double>::infinity()) , m_fbo(0) , m_currentLayerRendererSurface(0) , m_clearSurfaceOnDrawLayers(true) @@ -207,67 +209,54 @@ static inline bool compareLayerZ(const LayerCompositingThread* a, const LayerCom return transformA.m43() < transformB.m43(); } -// Re-composites all sublayers. -void LayerRenderer::drawLayers(const FloatRect& visibleRect, const IntRect& layoutRect, const IntSize& contentsSize, const IntRect& dstRect) +void LayerRenderer::prepareFrame(double animationTime, LayerCompositingThread* rootLayer) { - ASSERT(m_hardwareCompositing); - if (!m_hardwareCompositing) - return; + if (animationTime != m_animationTime) { + m_animationTime = animationTime; - bool wasEmpty = m_lastRenderingResults.isEmpty(); - m_lastRenderingResults = LayerRenderingResults(); - m_lastRenderingResults.wasEmpty = wasEmpty; + // Aha, new frame! Reset rendering results. + bool wasEmpty = m_lastRenderingResults.isEmpty(); + m_lastRenderingResults = LayerRenderingResults(); + m_lastRenderingResults.wasEmpty = wasEmpty; + } - if (!m_rootLayer) + if (!rootLayer) return; + bool isContextCurrent = makeContextCurrent(); + prepareFrameRecursive(rootLayer, animationTime, isContextCurrent); +} + +void LayerRenderer::setViewport(const IntRect& targetRect, const IntRect& clipRect, const FloatRect& visibleRect, const IntRect& layoutRect, const IntSize& contentsSize) +{ // These parameters are used to calculate position of fixed position elements m_visibleRect = visibleRect; m_layoutRect = layoutRect; m_contentsSize = contentsSize; - // WebKit uses row vectors which are multiplied by the matrix on the left (i.e. v*M) - // Transformations are composed on the left so that M1.xform(M2) means M2*M1 - // We therefore start with our (othogonal) projection matrix, which will be applied - // as the last transformation. - TransformationMatrix matrix = orthoMatrix(0, visibleRect.width(), visibleRect.height(), 0, -1000, 1000); - matrix.translate3d(-visibleRect.x(), -visibleRect.y(), 0); - - // OpenGL window coordinates origin is at the lower left corner of the surface while - // WebKit uses upper left as the origin of the window coordinate system. The passed in 'dstRect' - // is in WebKit window coordinate system. Here we setup the viewport to the corresponding value - // in OpenGL window coordinates. - int viewportY = std::max(0, m_context->surfaceSize().height() - dstRect.maxY()); - m_viewport = IntRect(dstRect.x(), viewportY, dstRect.width(), dstRect.height()); - - double animationTime = currentTime(); - -#if DEBUG_VIDEO_CLIPPING - // Invoking updateLayersRecursive() which will call LayerCompositingThread::setDrawTransform(). - BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "LayerRenderer::drawLayers() visible=(x=%.2f,y=%.2f,width=%.2f,height=%.2f), layout=(x=%d,y=%d,width=%d,height=%d), contents=(%dx%d), dst=(x=%d,y=%d,width=%d,height=%d).", - visibleRect.x(), visibleRect.y(), visibleRect.width(), visibleRect.height(), - layoutRect.x(), layoutRect.y(), layoutRect.width(), layoutRect.height(), - contentsSize.width(), contentsSize.height(), - dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height()); + m_viewport = targetRect; + m_scissorRect = clipRect; + + // The clipRect parameter uses render target coordinates, map to normalized device coordinates + m_clipRect = clipRect; + m_clipRect.intersect(targetRect); + m_clipRect = FloatRect(-1 + 2 * (m_clipRect.x() - targetRect.x()) / targetRect.width(), + -1 + 2 * (m_clipRect.y() - targetRect.y()) / targetRect.height(), + 2 * m_clipRect.width() / targetRect.width(), + 2 * m_clipRect.height() / targetRect.height()); + +#if DEBUG_CLIPPING + printf("LayerRenderer::setViewport() m_visibleRect=(%.2f,%.2f %.2fx%.2f), m_layoutRect=(%d,%d %dx%d), m_contentsSize=(%dx%d), m_viewport=(%d,%d %dx%d), m_scissorRect=(%d,%d %dx%d), m_clipRect=(%.2f,%.2f %.2fx%.2f)\n", + m_visibleRect.x(), m_visibleRect.y(), m_visibleRect.width(), m_visibleRect.height(), + m_layoutRect.x(), m_layoutRect.y(), m_layoutRect.width(), m_layoutRect.height(), + m_contentsSize.width(), m_contentsSize.height(), + m_viewport.x(), m_viewport.y(), m_viewport.width(), m_viewport.height(), + m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height(), + m_clipRect.x(), m_clipRect.y(), m_clipRect.width(), m_clipRect.height()); + fflush(stdout); #endif - Vector<RefPtr<LayerCompositingThread> > surfaceLayers; - const Vector<RefPtr<LayerCompositingThread> >& sublayers = m_rootLayer->getSublayers(); - for (size_t i = 0; i < sublayers.size(); i++) { - float opacity = 1; - FloatRect clipRect(-1, -1, 2, 2); - updateLayersRecursive(sublayers[i].get(), matrix, surfaceLayers, opacity, clipRect, animationTime); - } - - // Decompose the dirty rect into a set of non-overlaping rectangles - // (they need to not overlap so that the blending code doesn't draw any region twice). - for (int i = 0; i < LayerRenderingResults::NumberOfDirtyRects; ++i) { - BlackBerry::Platform::IntRectRegion region(BlackBerry::Platform::IntRect(m_lastRenderingResults.dirtyRect(i))); - m_lastRenderingResults.dirtyRegion = BlackBerry::Platform::IntRectRegion::unionRegions(m_lastRenderingResults.dirtyRegion, region); - } - - // If we won't draw anything, don't touch the OpenGL APIs. - if (m_lastRenderingResults.isEmpty() && wasEmpty) + if (!m_hardwareCompositing) return; // Okay, we're going to do some drawing. @@ -293,43 +282,86 @@ void LayerRenderer::drawLayers(const FloatRect& visibleRect, const IntRect& layo // The layer quads are drawn in clock-wise order so the front face is CCW. glFrontFace(GL_CCW); - // The shader used to render layers returns pre-multiplied alpha colors - // so we need to send the blending mode appropriately. - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - // Update the parameters for the checkerboard drawing. glUseProgram(m_checkerProgramObject); float bitmapScale = static_cast<float>(m_layoutRect.width()) / static_cast<float>(m_visibleRect.width()); glUniform1f(m_checkerScaleLocation, bitmapScale); - float scale = static_cast<float>(dstRect.width()) / static_cast<float>(m_visibleRect.width()); + float scale = static_cast<float>(m_viewport.width()) / static_cast<float>(m_visibleRect.width()); glUniform2f(m_checkerOriginLocation, m_visibleRect.x()*scale, m_visibleRect.y()*scale); glUniform1f(m_checkerSurfaceHeightLocation, m_context->surfaceSize().height()); checkGLError(); - // If some layers should be drawed on temporary surfaces, we should do it first. - drawLayersOnSurfaces(surfaceLayers); + glViewport(m_viewport.x(), m_viewport.y(), m_viewport.width(), m_viewport.height()); #if ENABLE_SCISSOR - m_scissorRect = m_viewport; glEnable(GL_SCISSOR_TEST); +#if DEBUG_CLIPPING + printf("LayerRenderer::compositeLayers(): clipping to (%d,%d %dx%d)\n", m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height()); + fflush(stdout); +#endif glScissor(m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height()); #endif glClearStencil(0); glClearColor(0, 0, 0, 0); GLenum buffersToClear = GL_STENCIL_BUFFER_BIT; - if (m_clearSurfaceOnDrawLayers) { + if (m_clearSurfaceOnDrawLayers) buffersToClear |= GL_COLOR_BUFFER_BIT; - } glClear(buffersToClear); +} + +void LayerRenderer::compositeLayers(const TransformationMatrix& matrix, LayerCompositingThread* rootLayer) +{ + ASSERT(m_hardwareCompositing); + if (!m_hardwareCompositing) + return; + + if (!rootLayer) + return; + + // Used to draw scale invariant layers. We assume uniform scale. + // The matrix maps to normalized device coordinates, a system that maps the + // viewport to the interval -1 to 1. + // So it has to scale down by a factor equal to one half the viewport. + m_scale = matrix.m11() * m_viewport.width() / 2; + + Vector<RefPtr<LayerCompositingThread> > surfaceLayers; + const Vector<RefPtr<LayerCompositingThread> >& sublayers = rootLayer->getSublayers(); + for (size_t i = 0; i < sublayers.size(); i++) { + float opacity = 1; + FloatRect clipRect(m_clipRect); + updateLayersRecursive(sublayers[i].get(), matrix, surfaceLayers, opacity, clipRect); + } + + // Decompose the dirty rect into a set of non-overlaping rectangles + // (they need to not overlap so that the blending code doesn't draw any region twice). + for (int i = 0; i < LayerRenderingResults::NumberOfDirtyRects; ++i) { + BlackBerry::Platform::IntRectRegion region(BlackBerry::Platform::IntRect(m_lastRenderingResults.dirtyRect(i))); + m_lastRenderingResults.dirtyRegion = BlackBerry::Platform::IntRectRegion::unionRegions(m_lastRenderingResults.dirtyRegion, region); + } + + // If we won't draw anything, don't touch the OpenGL APIs. + if (m_lastRenderingResults.isEmpty() && m_lastRenderingResults.wasEmpty) + return; + + // Okay, we're going to do some drawing. + if (!makeContextCurrent()) + return; + + // The shader used to render layers returns pre-multiplied alpha colors + // so we need to send the blending mode appropriately. + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + // If some layers should be drawed on temporary surfaces, we should do it first. + drawLayersOnSurfaces(surfaceLayers); // Don't render the root layer, the BlackBerry port uses the BackingStore to draw the // root layer. for (size_t i = 0; i < sublayers.size(); i++) { int currentStencilValue = 0; - FloatRect clipRect(-1, -1, 2, 2); + FloatRect clipRect(m_clipRect); compositeLayersRecursive(sublayers[i].get(), currentStencilValue, clipRect); } @@ -351,6 +383,9 @@ void LayerRenderer::drawLayers(const FloatRect& visibleRect, const IntRect& layo // driver by unbinding early (when the pixmap is hopefully still around). glBindTexture(GL_TEXTURE_2D, 0); + // Turn off blending again + glDisable(GL_BLEND); + LayerSet::iterator iter = m_layersLockingTextureResources.begin(); for (; iter != m_layersLockingTextureResources.end(); ++iter) (*iter)->releaseTextureResources(); @@ -359,12 +394,65 @@ void LayerRenderer::drawLayers(const FloatRect& visibleRect, const IntRect& layo if (m_needsCommit) { m_needsCommit = false; - m_rootLayer->scheduleCommit(); + rootLayer->scheduleCommit(); } textureCacheCompositingThread()->collectGarbage(); } +static float texcoords[4 * 2] = { 0, 0, 0, 1, 1, 1, 1, 0 }; + +void LayerRenderer::compositeBuffer(const TransformationMatrix& transform, const FloatRect& contents, BlackBerry::Platform::Graphics::Buffer* buffer, float opacity) +{ + if (!buffer) + return; + + FloatQuad vertices(transform.mapPoint(contents.minXMinYCorner()), + transform.mapPoint(contents.minXMaxYCorner()), + transform.mapPoint(contents.maxXMaxYCorner()), + transform.mapPoint(contents.maxXMinYCorner())); + + if (!vertices.boundingBox().intersects(m_clipRect)) + return; + + if (opacity < 1.0f) { + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + + glUseProgram(m_layerProgramObject[LayerData::LayerProgramShaderRGBA]); + glUniform1f(m_alphaLocation[LayerData::LayerProgramShaderRGBA], opacity); + + glVertexAttribPointer(m_positionLocation, 2, GL_FLOAT, GL_FALSE, 0, &vertices); + glVertexAttribPointer(m_texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords); + + if (BlackBerry::Platform::Graphics::lockAndBindBufferGLTexture(buffer, GL_TEXTURE_2D)) { + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + BlackBerry::Platform::Graphics::releaseBufferGLTexture(buffer); + } + + if (opacity < 1.0f) + glDisable(GL_BLEND); +} + +void LayerRenderer::drawCheckerboardPattern(const TransformationMatrix& transform, const FloatRect& contents) +{ + FloatQuad vertices(transform.mapPoint(contents.minXMinYCorner()), + transform.mapPoint(contents.minXMaxYCorner()), + transform.mapPoint(contents.maxXMaxYCorner()), + transform.mapPoint(contents.maxXMinYCorner())); + + if (!vertices.boundingBox().intersects(m_clipRect)) + return; + + glUseProgram(m_checkerProgramObject); + + glVertexAttribPointer(m_positionLocation, 2, GL_FLOAT, GL_FALSE, 0, &vertices); + glVertexAttribPointer(m_texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +} + bool LayerRenderer::useSurface(LayerRendererSurface* surface) { if (m_currentLayerRendererSurface == surface) @@ -415,15 +503,13 @@ void LayerRenderer::drawLayersOnSurfaces(const Vector<RefPtr<LayerCompositingThr // If there are layers drawed on surfaces, we need to switch to default framebuffer. // Otherwise, we just need to set viewport. - if (surfaceLayers.size()) + if (surfaceLayers.size()) { useSurface(0); - else - glViewport(m_viewport.x(), m_viewport.y(), m_viewport.width(), m_viewport.height()); -} - -void LayerRenderer::setRootLayer(LayerCompositingThread* layer) -{ - m_rootLayer = layer; +#if ENABLE_SCISSOR + glEnable(GL_SCISSOR_TEST); + glScissor(m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height()); +#endif + } } void LayerRenderer::addLayer(LayerCompositingThread* layer) @@ -488,11 +574,6 @@ void LayerRenderer::drawDebugBorder(LayerCompositingThread* layer) { Color borderColor = layer->borderColor(); -#if DEBUG_DIRTY_LAYERS - if (layer->isDirty()) - borderColor = Color(0xFF, 0x00, 0x00, 0xFF); -#endif - #if DEBUG_LAYER_ANIMATIONS if (layer->hasRunningAnimations()) borderColor = Color(0x00, 0xFF, 0x00, 0xFF); @@ -526,9 +607,34 @@ void LayerRenderer::drawHolePunchRect(LayerCompositingThread* layer) m_lastRenderingResults.addHolePunchRect(holeWC); } -void LayerRenderer::updateLayersRecursive(LayerCompositingThread* layer, const TransformationMatrix& matrix, Vector<RefPtr<LayerCompositingThread> >& surfaceLayers, float opacity, FloatRect clipRect, double currentTime) +void LayerRenderer::prepareFrameRecursive(LayerCompositingThread* layer, double animationTime, bool isContextCurrent) { + // This might cause the layer to recompute some attributes. + m_lastRenderingResults.needsAnimationFrame |= layer->updateAnimations(animationTime); + + if (isContextCurrent) { + // Even non-visible layers need to perform their texture jobs, or they will + // pile up and waste memory. + if (layer->needsTexture()) + layer->updateTextureContentsIfNeeded(); + if (layer->maskLayer() && layer->maskLayer()->needsTexture()) + layer->maskLayer()->updateTextureContentsIfNeeded(); + if (layer->replicaLayer()) { + LayerCompositingThread* replica = layer->replicaLayer(); + if (replica->needsTexture()) + replica->updateTextureContentsIfNeeded(); + if (replica->maskLayer() && replica->maskLayer()->needsTexture()) + replica->maskLayer()->updateTextureContentsIfNeeded(); + } + } + + const Vector<RefPtr<LayerCompositingThread> >& sublayers = layer->getSublayers(); + for (size_t i = 0; i < sublayers.size(); i++) + prepareFrameRecursive(sublayers[i].get(), animationTime, isContextCurrent); +} +void LayerRenderer::updateLayersRecursive(LayerCompositingThread* layer, const TransformationMatrix& matrix, Vector<RefPtr<LayerCompositingThread> >& surfaceLayers, float opacity, FloatRect clipRect) +{ // The contract for LayerCompositingThread::setLayerRenderer is it must be set if the layer has been rendered. // So do it now, before we render it in compositeLayersRecursive. layer->setLayerRenderer(this); @@ -541,9 +647,6 @@ void LayerRenderer::updateLayersRecursive(LayerCompositingThread* layer, const T replica->maskLayer()->setLayerRenderer(this); } - // This might cause the layer to recompute some attributes. - m_lastRenderingResults.needsAnimationFrame |= layer->updateAnimations(currentTime); - // Compute the new matrix transformation that will be applied to this layer and // all its sublayers. It's important to remember that the layer's position // is the position of the layer's anchor point. Also, the coordinate system used @@ -562,7 +665,9 @@ void LayerRenderer::updateLayersRecursive(LayerCompositingThread* layer, const T // Where: P is the projection matrix // M is the layer's matrix computed above // S is the scale adjustment (to scale up to the layer size) - IntSize bounds = layer->bounds(); + FloatSize bounds = layer->bounds(); + if (layer->sizeIsScaleInvariant()) + bounds.scale(1.0 / m_scale); FloatPoint anchorPoint = layer->anchorPoint(); FloatPoint position = layer->position(); @@ -629,7 +734,7 @@ void LayerRenderer::updateLayersRecursive(LayerCompositingThread* layer, const T surface->setReplicaDrawTransform(replicaMatrix); } - IntRect drawRect = IntRect(IntPoint(), bounds); + IntRect drawRect = enclosingIntRect(FloatRect(FloatPoint(), bounds)); surface->setContentRect(drawRect); TransformationMatrix projectionMatrix = orthoMatrix(drawRect.x(), drawRect.maxX(), drawRect.y(), drawRect.maxY(), -1000, 1000); @@ -642,7 +747,7 @@ void LayerRenderer::updateLayersRecursive(LayerCompositingThread* layer, const T surfaceLayers.append(layer); } - layer->setDrawTransform(localMatrix); + layer->setDrawTransform(m_scale, localMatrix); #if ENABLE(VIDEO) bool layerVisible = clipRect.intersects(layer->getDrawRect()) || layer->mediaPlayer(); @@ -681,7 +786,7 @@ void LayerRenderer::updateLayersRecursive(LayerCompositingThread* layer, const T const Vector<RefPtr<LayerCompositingThread> >& sublayers = layer->getSublayers(); for (size_t i = 0; i < sublayers.size(); i++) - updateLayersRecursive(sublayers[i].get(), localMatrix, surfaceLayers, opacity, clipRect, currentTime); + updateLayersRecursive(sublayers[i].get(), localMatrix, surfaceLayers, opacity, clipRect); } static bool hasRotationalComponent(const TransformationMatrix& m) @@ -731,20 +836,6 @@ void LayerRenderer::compositeLayersRecursive(LayerCompositingThread* layer, int // 1. Layers that have their own GraphicsContext and can draw their contents on demand (layer->drawsContent() == true). // 2. Layers that are just containers of images/video/etc that don't own a GraphicsContext (layer->contents() == true). - // Even non-visible layers need to perform their texture jobs, or they will - // pile up and waste memory. - if (layer->needsTexture()) - layer->updateTextureContentsIfNeeded(); - if (layer->maskLayer() && layer->maskLayer()->needsTexture()) - layer->maskLayer()->updateTextureContentsIfNeeded(); - if (layer->replicaLayer()) { - LayerCompositingThread* replica = layer->replicaLayer(); - if (replica->needsTexture()) - replica->updateTextureContentsIfNeeded(); - if (replica->maskLayer() && replica->maskLayer()->needsTexture()) - replica->maskLayer()->updateTextureContentsIfNeeded(); - } - if ((layer->needsTexture() || layer->layerRendererSurface()) && layerVisible) { updateScissorIfNeeded(clipRect); @@ -764,7 +855,7 @@ void LayerRenderer::compositeLayersRecursive(LayerCompositingThread* layer, int if (!drawSurface) { glUseProgram(m_layerProgramObject[shader]); glUniform1f(m_alphaLocation[shader], layer->drawOpacity()); - layer->drawTextures(m_positionLocation, m_texCoordLocation, m_visibleRect); + layer->drawTextures(m_scale, m_positionLocation, m_texCoordLocation, m_visibleRect); } else { // Draw the reflection if it exists. if (layer->replicaLayer()) { @@ -788,7 +879,7 @@ void LayerRenderer::compositeLayersRecursive(LayerCompositingThread* layer, int if (layer->hasMissingTextures()) { glDisable(GL_BLEND); glUseProgram(m_checkerProgramObject); - layer->drawMissingTextures(m_positionLocation, m_texCoordLocation, m_visibleRect); + layer->drawMissingTextures(m_scale, m_positionLocation, m_texCoordLocation, m_visibleRect); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } @@ -870,11 +961,19 @@ void LayerRenderer::compositeLayersRecursive(LayerCompositingThread* layer, int void LayerRenderer::updateScissorIfNeeded(const FloatRect& clipRect) { #if ENABLE_SCISSOR +#if DEBUG_CLIPPING + printf("LayerRenderer::updateScissorIfNeeded(): clipRect=(%.2f,%.2f %.2fx%.2f)\n", clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height()); + fflush(stdout); +#endif IntRect clipRectWC = toOpenGLWindowCoordinates(clipRect); if (m_scissorRect == clipRectWC) return; m_scissorRect = clipRectWC; +#if DEBUG_CLIPPING + printf("LayerRenderer::updateScissorIfNeeded(): clipping to (%d,%d %dx%d)\n", m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height()); + fflush(stdout); +#endif glScissor(m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height()); #endif } @@ -1092,8 +1191,9 @@ IntRect LayerRenderingResults::holePunchRect(unsigned index) const void LayerRenderingResults::addHolePunchRect(const IntRect& rect) { -#if DEBUG_VIDEO_CLIPPING - BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "LayerRenderingResults::addHolePunchRect (x=%d,y=%d,width=%d,height=%d).", rect.x(), rect.y(), rect.width(), rect.height()); +#if DEBUG_CLIPPING + printf("LayerRenderingResults::addHolePunchRect (%d,%d %dx%d)\n", rect.x(), rect.y(), rect.width(), rect.height()); + fflush(stdout); #endif if (!rect.isEmpty()) m_holePunchRects.append(rect); diff --git a/Source/WebCore/platform/graphics/blackberry/LayerRenderer.h b/Source/WebCore/platform/graphics/blackberry/LayerRenderer.h index fe5ea0011..5d21ecbbc 100644 --- a/Source/WebCore/platform/graphics/blackberry/LayerRenderer.h +++ b/Source/WebCore/platform/graphics/blackberry/LayerRenderer.h @@ -79,6 +79,8 @@ private: class LayerRenderer { WTF_MAKE_NONCOPYABLE(LayerRenderer); public: + static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top, float nearZ, float farZ); + static PassOwnPtr<LayerRenderer> create(BlackBerry::Platform::Graphics::GLES2Context*); LayerRenderer(BlackBerry::Platform::Graphics::GLES2Context*); @@ -86,11 +88,26 @@ public: void releaseLayerResources(); - // Recomposites all the layers. Returns true if it needs more draw. - void drawLayers(const FloatRect& visibleRect, const IntRect& layoutRect, const IntSize& contentsSize, const IntRect& dstRect); + // In order to render the layers, you must do the following 3 operations, in order. + + // 1. Upload textures and other operations that should be performed at the beginning of each frame. + // Note, this call also resets the last rendering results. + void prepareFrame(double animationTime, LayerCompositingThread* rootLayer); - void setRootLayer(LayerCompositingThread*); - LayerCompositingThread* rootLayer() { return m_rootLayer.get(); } + // 2. Set the OpenGL viewport and store other viewport-related parameters + // viewport is the GL viewport + // clipRect is an additional clip rect, if clipping is required beyond the clipping effect of the viewport. + // visibleRect is the subrect of the web page that you wish to composite, expressed in content coordinates + // The last two parameters are required to draw fixed position elements in the right place: + // layoutRect is the subrect of the web page that the WebKit thread believes is visible (scroll position, actual visible size). + // contentsSize is the contents size of the web page + void setViewport(const IntRect& viewport, const IntRect& clipRect, const FloatRect& visibleRect, const IntRect& layoutRect, const IntSize& contentsSize); + + // 3. Prepares all the layers for compositing + // transform is the model-view-project matrix that goes all the way from contents to normalized device coordinates. + void compositeLayers(const TransformationMatrix&, LayerCompositingThread* rootLayer); + void compositeBuffer(const TransformationMatrix&, const FloatRect& contents, BlackBerry::Platform::Graphics::Buffer*, float opacity); + void drawCheckerboardPattern(const TransformationMatrix&, const FloatRect& contents); // Keep track of layers that need cleanup when the LayerRenderer is destroyed void addLayer(LayerCompositingThread*); @@ -118,7 +135,8 @@ public: bool layerAlreadyOnSurface(LayerCompositingThread*) const; private: - void updateLayersRecursive(LayerCompositingThread*, const TransformationMatrix& parentMatrix, Vector<RefPtr<LayerCompositingThread> >& surfaceLayers, float opacity, FloatRect clipRect, double currentTime); + void prepareFrameRecursive(LayerCompositingThread*, double animationTime, bool isContextCurrent); + void updateLayersRecursive(LayerCompositingThread*, const TransformationMatrix& parentMatrix, Vector<RefPtr<LayerCompositingThread> >& surfaceLayers, float opacity, FloatRect clipRect); void compositeLayersRecursive(LayerCompositingThread*, int stencilValue, FloatRect clipRect); void updateScissorIfNeeded(const FloatRect& clipRect); @@ -158,14 +176,15 @@ private: int m_checkerSurfaceHeightLocation; // Current draw configuration. + double m_scale; + double m_animationTime; FloatRect m_visibleRect; IntRect m_layoutRect; IntSize m_contentsSize; - IntRect m_viewport; - IntRect m_scissorRect; - - RefPtr<LayerCompositingThread> m_rootLayer; + IntRect m_viewport; // In render target coordinates + IntRect m_scissorRect; // In render target coordinates + FloatRect m_clipRect; // In normalized device coordinates unsigned m_fbo; LayerRendererSurface* m_currentLayerRendererSurface; diff --git a/Source/WebCore/platform/graphics/blackberry/LayerTiler.cpp b/Source/WebCore/platform/graphics/blackberry/LayerTiler.cpp index d517aaa7b..db6e75c2f 100644 --- a/Source/WebCore/platform/graphics/blackberry/LayerTiler.cpp +++ b/Source/WebCore/platform/graphics/blackberry/LayerTiler.cpp @@ -75,6 +75,7 @@ LayerTiler::LayerTiler(LayerWebKitThread* layer) , m_hasMissingTextures(false) , m_contentsScale(0.0) { + ref(); // This ref() is matched by a deref in layerCompositingThreadDestroyed(); } LayerTiler::~LayerTiler() @@ -90,9 +91,10 @@ void LayerTiler::layerWebKitThreadDestroyed() m_layer = 0; } -void LayerTiler::layerCompositingThreadDestroyed() +void LayerTiler::layerCompositingThreadDestroyed(LayerCompositingThread*) { ASSERT(isCompositingThread()); + deref(); // Matched by ref() in constructor; } void LayerTiler::setNeedsDisplay(const FloatRect& dirtyRect) @@ -120,6 +122,11 @@ void LayerTiler::updateTextureContentsIfNeeded(double scale) renderJobs = m_renderJobs; } + // There's no point in drawing contents at a higher resolution for scale + // invariant layers. + if (m_layer->sizeIsScaleInvariant()) + scale = 1.0; + bool isZoomJob = false; if (scale != m_contentsScale) { // The first time around, it does not count as a zoom job. @@ -349,7 +356,7 @@ void LayerTiler::commitPendingTextureUploads() m_pendingTextureJobs.clear(); } -void LayerTiler::layerVisibilityChanged(bool visible) +void LayerTiler::layerVisibilityChanged(LayerCompositingThread*, bool visible) { // For visible layers, we handle the tile-level visibility // in the draw loop, see LayerTiler::drawTextures(). @@ -369,7 +376,7 @@ void LayerTiler::layerVisibilityChanged(bool visible) } } -void LayerTiler::uploadTexturesIfNeeded() +void LayerTiler::uploadTexturesIfNeeded(LayerCompositingThread*) { TileJobsMap tileJobsMap; Deque<TextureJob>::const_iterator textureJobIterEnd = m_textureJobs.end(); @@ -468,20 +475,25 @@ void LayerTiler::performTileJob(LayerTile* tile, const TextureJob& job, const In ASSERT_NOT_REACHED(); } -void LayerTiler::drawTextures(LayerCompositingThread* layer, int pos, int texCoord) +void LayerTiler::drawTextures(LayerCompositingThread* layer, double scale, int pos, int texCoord) { - drawTexturesInternal(layer, pos, texCoord, false /* drawMissing */); + drawTexturesInternal(layer, scale, pos, texCoord, false /* drawMissing */); } -void LayerTiler::drawMissingTextures(LayerCompositingThread* layer, int pos, int texCoord) +void LayerTiler::drawMissingTextures(LayerCompositingThread* layer, double scale, int pos, int texCoord) { - drawTexturesInternal(layer, pos, texCoord, true /* drawMissing */); + drawTexturesInternal(layer, scale, pos, texCoord, true /* drawMissing */); } -void LayerTiler::drawTexturesInternal(LayerCompositingThread* layer, int positionLocation, int texCoordLocation, bool drawMissing) +void LayerTiler::drawTexturesInternal(LayerCompositingThread* layer, double scale, int positionLocation, int texCoordLocation, bool drawMissing) { const TransformationMatrix& drawTransform = layer->drawTransform(); - IntSize bounds = layer->bounds(); + FloatSize bounds = layer->bounds(); + + if (layer->sizeIsScaleInvariant()) { + bounds.setWidth(bounds.width() / scale); + bounds.setHeight(bounds.width() / scale); + } float texcoords[4 * 2] = { 0, 0, 0, 1, 1, 1, 1, 0 }; float vertices[4 * 4]; @@ -611,7 +623,7 @@ void LayerTiler::removeRenderJob(const TileIndex& index) m_renderJobs.remove(index); } -void LayerTiler::deleteTextures() +void LayerTiler::deleteTextures(LayerCompositingThread*) { // Since textures are deleted by a synchronous message // from WebKit thread to compositing thread, we don't need @@ -675,6 +687,14 @@ void LayerTiler::disableTiling(bool disable) updateTileSize(); } +void LayerTiler::scheduleCommit() +{ + ASSERT(isWebKitThread()); + + if (m_layer) + m_layer->setNeedsCommit(); +} + bool LayerTiler::shouldPrefillTile(const TileIndex& index) { // For now, we use the heuristic of prefilling the first screenful of tiles. @@ -716,18 +736,7 @@ IntRect LayerTiler::rectForTile(const TileIndex& index, const IntSize& bounds) return IntRect(origin, size); } -bool LayerTiler::hasDirtyTiles() const -{ - for (TileMap::const_iterator it = m_tilesCompositingThread.begin(); it != m_tilesCompositingThread.end(); ++it) { - const LayerTile* tile = (*it).second; - if (tile->isDirty()) - return true; - } - - return false; -} - -void LayerTiler::bindContentsTexture() +void LayerTiler::bindContentsTexture(LayerCompositingThread*) { ASSERT(m_tilesCompositingThread.size() == 1); if (m_tilesCompositingThread.size() != 1) diff --git a/Source/WebCore/platform/graphics/blackberry/LayerTiler.h b/Source/WebCore/platform/graphics/blackberry/LayerTiler.h index 376662955..7694dec70 100644 --- a/Source/WebCore/platform/graphics/blackberry/LayerTiler.h +++ b/Source/WebCore/platform/graphics/blackberry/LayerTiler.h @@ -24,6 +24,7 @@ #include "Color.h" #include "FloatRect.h" #include "IntRect.h" +#include "LayerCompositingThreadClient.h" #include "LayerTile.h" #include "LayerTileIndex.h" @@ -38,7 +39,7 @@ namespace WebCore { class LayerCompositingThread; class LayerWebKitThread; -class LayerTiler : public ThreadSafeRefCounted<LayerTiler> { +class LayerTiler : public ThreadSafeRefCounted<LayerTiler>, public LayerCompositingThreadClient { public: TileIndex indexOfTile(const IntPoint& origin); IntPoint originOfTile(const TileIndex&); @@ -58,18 +59,18 @@ public: void setNeedsDisplay(); void updateTextureContentsIfNeeded(double scale); void disableTiling(bool); + virtual void scheduleCommit(); // Compositing thread - void layerCompositingThreadDestroyed(); - void uploadTexturesIfNeeded(); - void drawTextures(LayerCompositingThread*, int positionLocation, int texCoordLocation); - bool hasMissingTextures() const { return m_hasMissingTextures; } - void drawMissingTextures(LayerCompositingThread*, int positionLocation, int texCoordLocation); - void deleteTextures(); + virtual void layerCompositingThreadDestroyed(LayerCompositingThread*); + virtual void layerVisibilityChanged(LayerCompositingThread*, bool visible); + virtual void uploadTexturesIfNeeded(LayerCompositingThread*); + virtual void bindContentsTexture(LayerCompositingThread*); + virtual void drawTextures(LayerCompositingThread*, double scale, int positionLocation, int texCoordLocation); + virtual bool hasMissingTextures(const LayerCompositingThread*) const { return m_hasMissingTextures; } + virtual void drawMissingTextures(LayerCompositingThread*, double scale, int positionLocation, int texCoordLocation); + virtual void deleteTextures(LayerCompositingThread*); void commitPendingTextureUploads(); - void layerVisibilityChanged(bool visible); - bool hasDirtyTiles() const; - void bindContentsTexture(); // Thread safe void addRenderJob(const TileIndex&); @@ -156,7 +157,7 @@ private: void addTileJob(const TileIndex&, const TextureJob&, TileJobsMap&); void performTileJob(LayerTile*, const TextureJob&, const IntRect&); void processTextureJob(const TextureJob&, TileJobsMap&); - void drawTexturesInternal(LayerCompositingThread*, int positionLocation, int texCoordLocation, bool missing); + void drawTexturesInternal(LayerCompositingThread*, double scale, int positionLocation, int texCoordLocation, bool missing); void pruneTextures(); void visibilityChanged(bool needsDisplay); diff --git a/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp b/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp index 6c5438267..15bbe0a8f 100644 --- a/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp +++ b/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp @@ -63,9 +63,12 @@ LayerWebKitThread::LayerWebKitThread(LayerType type, GraphicsLayerBlackBerry* ow , m_scale(1.0) , m_isDrawable(false) , m_isMask(false) + , m_animationsChanged(false) + , m_clearOverrideOnCommit(false) { - m_tiler = LayerTiler::create(this); - m_layerCompositingThread = LayerCompositingThread::create(type, m_tiler); + if (type == Layer) + m_tiler = LayerTiler::create(this); + m_layerCompositingThread = LayerCompositingThread::create(type, m_tiler.get()); } LayerWebKitThread::~LayerWebKitThread() @@ -75,7 +78,8 @@ LayerWebKitThread::~LayerWebKitThread() if (m_frontBufferLock) pthread_mutex_destroy(m_frontBufferLock); - m_tiler->layerWebKitThreadDestroyed(); + if (m_tiler) + m_tiler->layerWebKitThreadDestroyed(); // Our superlayer should be holding a reference to us so there should be no // way for us to be destroyed while we still have a superlayer. @@ -167,7 +171,8 @@ void LayerWebKitThread::createFrontBufferLock() void LayerWebKitThread::updateTextureContentsIfNeeded() { - m_tiler->updateTextureContentsIfNeeded(m_isMask ? 1.0 : contentsScale()); + if (m_tiler) + m_tiler->updateTextureContentsIfNeeded(m_isMask ? 1.0 : contentsScale()); } void LayerWebKitThread::setContents(Image* contents) @@ -226,6 +231,7 @@ void LayerWebKitThread::startAnimations(double time) { for (size_t i = 0; i < m_runningAnimations.size(); ++i) { if (!m_runningAnimations[i]->startTime()) { + m_animationsChanged = true; m_runningAnimations[i]->setStartTime(time); notifyAnimationStarted(time); } @@ -278,9 +284,19 @@ void LayerWebKitThread::commitOnCompositingThread() m_position += m_absoluteOffset; // Copy the base variables from this object into m_layerCompositingThread replicate(m_layerCompositingThread.get()); + if (m_animationsChanged) { + m_layerCompositingThread->setRunningAnimations(m_runningAnimations); + m_layerCompositingThread->setSuspendedAnimations(m_suspendedAnimations); + m_animationsChanged = false; + } + if (m_clearOverrideOnCommit) { + m_layerCompositingThread->clearOverride(); + m_clearOverrideOnCommit = false; + } m_position = oldPosition; updateLayerHierarchy(); - m_tiler->commitPendingTextureUploads(); + if (m_tiler) + m_tiler->commitPendingTextureUploads(); size_t listSize = m_sublayers.size(); for (size_t i = 0; i < listSize; i++) @@ -424,13 +440,15 @@ void LayerWebKitThread::setSublayers(const Vector<RefPtr<LayerWebKitThread> >& s void LayerWebKitThread::setNeedsDisplayInRect(const FloatRect& dirtyRect) { - m_tiler->setNeedsDisplay(dirtyRect); + if (m_tiler) + m_tiler->setNeedsDisplay(dirtyRect); setNeedsCommit(); // FIXME: Replace this with a more targeted message for dirty rect handling with plugin content? } void LayerWebKitThread::setNeedsDisplay() { - m_tiler->setNeedsDisplay(); + if (m_tiler) + m_tiler->setNeedsDisplay(); setNeedsCommit(); // FIXME: Replace this with a more targeted message for dirty rect handling with plugin content? } @@ -448,10 +466,24 @@ void LayerWebKitThread::updateLayerHierarchy() void LayerWebKitThread::setIsMask(bool isMask) { m_isMask = isMask; - if (isMask) + if (isMask && m_tiler) m_tiler->disableTiling(true); } +void LayerWebKitThread::setRunningAnimations(const Vector<RefPtr<LayerAnimation> >& animations) +{ + m_runningAnimations = animations; + m_animationsChanged = true; + setNeedsCommit(); +} + +void LayerWebKitThread::setSuspendedAnimations(const Vector<RefPtr<LayerAnimation> >& animations) +{ + m_suspendedAnimations = animations; + m_animationsChanged = true; + setNeedsCommit(); +} + } #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.h b/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.h index 848c184a6..49a49be5f 100644 --- a/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.h +++ b/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.h @@ -36,6 +36,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "GraphicsLayerBlackBerry.h" +#include "LayerAnimation.h" #include "LayerData.h" #include "LayerTiler.h" @@ -73,6 +74,8 @@ public: void setBounds(const IntSize&); + void setSizeIsScaleInvariant(bool invariant) { m_sizeIsScaleInvariant = invariant; setNeedsCommit(); } + void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; setNeedsCommit(); } void setFrame(const FloatRect&); @@ -142,8 +145,11 @@ public: void setNeedsCommit(); void notifyAnimationStarted(double time); - void setRunningAnimations(const Vector<RefPtr<LayerAnimation> >& animations) { m_runningAnimations = animations; setNeedsCommit(); } - void setSuspendedAnimations(const Vector<RefPtr<LayerAnimation> >& animations) { m_suspendedAnimations = animations; setNeedsCommit(); } + void setRunningAnimations(const Vector<RefPtr<LayerAnimation> >&); + void setSuspendedAnimations(const Vector<RefPtr<LayerAnimation> >&); + + // Allows you to clear the LayerCompositingThread::overrides from the WK thread + void clearOverride() { m_clearOverrideOnCommit = true; setNeedsCommit(); } protected: LayerWebKitThread(LayerType, GraphicsLayerBlackBerry* owner); @@ -178,6 +184,9 @@ private: GraphicsLayerBlackBerry* m_owner; + Vector<RefPtr<LayerAnimation> > m_runningAnimations; + Vector<RefPtr<LayerAnimation> > m_suspendedAnimations; + Vector<RefPtr<LayerWebKitThread> > m_sublayers; LayerWebKitThread* m_superlayer; RefPtr<LayerWebKitThread> m_maskLayer; @@ -189,8 +198,10 @@ private: RefPtr<LayerTiler> m_tiler; FloatSize m_absoluteOffset; double m_scale; // Scale applies only to content layers - bool m_isDrawable; - bool m_isMask; + unsigned m_isDrawable : 1; + unsigned m_isMask : 1; + unsigned m_animationsChanged : 1; + unsigned m_clearOverrideOnCommit : 1; }; } diff --git a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp index dc9a534af..3ac93e8b4 100644 --- a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp +++ b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp @@ -22,6 +22,8 @@ #include "MediaPlayerPrivateBlackBerry.h" #include "CookieManager.h" +#include "Credential.h" +#include "CredentialStorage.h" #include "Frame.h" #include "FrameView.h" #include "GraphicsContext.h" @@ -30,6 +32,7 @@ #include "HostWindow.h" #include "NotImplemented.h" #include "PlatformContextSkia.h" +#include "ProtectionSpace.h" #include "RenderBox.h" #include "TimeRanges.h" #include "WebPageClient.h" @@ -285,10 +288,10 @@ PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const return timeRanges.release(); } -unsigned MediaPlayerPrivate::bytesLoaded() const +bool MediaPlayerPrivate::didLoadingProgress() const { notImplemented(); - return 0; + return false; } void MediaPlayerPrivate::setSize(const IntSize&) @@ -657,6 +660,50 @@ void MediaPlayerPrivate::onBuffering(bool flag) } #endif +static ProtectionSpace generateProtectionSpaceFromMMRAuthChallenge(const MMRAuthChallenge& authChallenge) +{ + KURL url(ParsedURLString, String(authChallenge.url().c_str())); + ASSERT(url.isValid()); + + return ProtectionSpace(url.host(), url.port(), + static_cast<ProtectionSpaceServerType>(authChallenge.serverType()), + authChallenge.realm().c_str(), + static_cast<ProtectionSpaceAuthenticationScheme>(authChallenge.authScheme())); +} + +bool MediaPlayerPrivate::onAuthenticationNeeded(MMRAuthChallenge& authChallenge) +{ + KURL url(ParsedURLString, String(authChallenge.url().c_str())); + if (!url.isValid()) + return false; + + ProtectionSpace protectionSpace = generateProtectionSpaceFromMMRAuthChallenge(authChallenge); + Credential credential = CredentialStorage::get(protectionSpace); + bool isConfirmed = false; + if (credential.isEmpty()) { + if (frameView() && frameView()->hostWindow()) + isConfirmed = frameView()->hostWindow()->platformPageClient()->authenticationChallenge(url, protectionSpace, credential); + } else + isConfirmed = true; + + if (isConfirmed) + authChallenge.setCredential(credential.user().utf8().data(), credential.password().utf8().data(), static_cast<MMRAuthChallenge::CredentialPersistence>(credential.persistence())); + + return isConfirmed; +} + +void MediaPlayerPrivate::onAuthenticationAccepted(const MMRAuthChallenge& authChallenge) const +{ + KURL url(ParsedURLString, String(authChallenge.url().c_str())); + if (!url.isValid()) + return; + + ProtectionSpace protectionSpace = generateProtectionSpaceFromMMRAuthChallenge(authChallenge); + Credential savedCredential = CredentialStorage::get(protectionSpace); + if (savedCredential.isEmpty()) + CredentialStorage::set(Credential(authChallenge.username().c_str(), authChallenge.password().c_str(), static_cast<CredentialPersistence>(authChallenge.persistence())), protectionSpace, url); +} + int MediaPlayerPrivate::showErrorDialog(MMRPlayer::Error type) { using namespace BlackBerry::WebKit; diff --git a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h index bcc5473a6..0ac466bec 100644 --- a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h +++ b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h @@ -83,7 +83,7 @@ public: virtual float maxTimeSeekable() const; virtual PassRefPtr<TimeRanges> buffered() const; - virtual unsigned bytesLoaded() const; + virtual bool didLoadingProgress() const; virtual void setSize(const IntSize&); @@ -130,6 +130,8 @@ public: #if USE(ACCELERATED_COMPOSITING) virtual void onBuffering(bool); #endif + virtual bool onAuthenticationNeeded(BlackBerry::Platform::MMRAuthChallenge&); + virtual void onAuthenticationAccepted(const BlackBerry::Platform::MMRAuthChallenge&) const; virtual bool isFullscreen() const; virtual bool isElementPaused() const; diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index 70d590dd6..748946820 100644 --- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -132,18 +132,16 @@ struct SubimageCacheHash { typedef HashSet<SubimageCacheEntry, SubimageCacheHash, SubimageCacheEntryTraits> SubimageCache; -class SubimageCacheTimer : private TimerBase { -public: - SubimageCacheTimer() : m_shouldRestartWhenTimerFires(false) { } - void restart(); -private: - virtual void fired() OVERRIDE; - bool m_shouldRestartWhenTimerFires; -}; - struct SubimageCacheWithTimer { SubimageCache cache; - SubimageCacheTimer timer; + DeferrableOneShotTimer<SubimageCacheWithTimer> timer; + + SubimageCacheWithTimer() + : timer(this, &SubimageCacheWithTimer::invalidateCacheTimerFired, subimageCacheClearDelay) + { + } + + void invalidateCacheTimerFired(DeferrableOneShotTimer<SubimageCacheWithTimer>*); }; static SubimageCacheWithTimer& subimageCache() @@ -152,25 +150,8 @@ static SubimageCacheWithTimer& subimageCache() return cache; } -inline void SubimageCacheTimer::restart() +void SubimageCacheWithTimer::invalidateCacheTimerFired(DeferrableOneShotTimer<SubimageCacheWithTimer>*) { - // Setting this boolean is much more efficient than calling startOneShot - // again, which might result in rescheduling the system timer and that - // can be quite expensive. - if (isActive()) { - m_shouldRestartWhenTimerFires = true; - return; - } - startOneShot(subimageCacheClearDelay); -} - -void SubimageCacheTimer::fired() -{ - if (m_shouldRestartWhenTimerFires) { - m_shouldRestartWhenTimerFires = false; - startOneShot(subimageCacheClearDelay); - return; - } subimageCache().cache.clear(); } diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp index b86ad31da..ae8d3208b 100644 --- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp @@ -49,9 +49,9 @@ namespace WebCore { class ContentLayerPainter : public LayerPainterChromium { WTF_MAKE_NONCOPYABLE(ContentLayerPainter); public: - static PassOwnPtr<ContentLayerPainter> create(ContentLayerDelegate* delegate, TiledLayerChromium* layer) + static PassOwnPtr<ContentLayerPainter> create(ContentLayerDelegate* delegate) { - return adoptPtr(new ContentLayerPainter(delegate, layer)); + return adoptPtr(new ContentLayerPainter(delegate)); } virtual void paint(GraphicsContext& context, const IntRect& contentRect) @@ -59,27 +59,19 @@ public: double paintStart = currentTime(); context.clearRect(contentRect); context.clip(contentRect); - { - GraphicsContextStateSaver stateSaver(context, m_layer->layerTreeHost()->settings().debugShowTileInfo); - - m_delegate->paintContents(context, contentRect); - double paintEnd = currentTime(); - double pixelsPerSec = (contentRect.width() * contentRect.height()) / (paintEnd - paintStart); - WebKit::Platform::current()->histogramCustomCounts("Renderer4.AccelContentPaintDurationMS", (paintEnd - paintStart) * 1000, 0, 120, 30); - WebKit::Platform::current()->histogramCustomCounts("Renderer4.AccelContentPaintMegapixPerSecond", pixelsPerSec / 1000000, 10, 210, 30); - } - if (m_layer->layerTreeHost()->settings().debugShowTileInfo) - m_layer->paintDebugTileInfo(context, contentRect); + m_delegate->paintContents(context, contentRect); + double paintEnd = currentTime(); + double pixelsPerSec = (contentRect.width() * contentRect.height()) / (paintEnd - paintStart); + WebKit::Platform::current()->histogramCustomCounts("Renderer4.AccelContentPaintDurationMS", (paintEnd - paintStart) * 1000, 0, 120, 30); + WebKit::Platform::current()->histogramCustomCounts("Renderer4.AccelContentPaintMegapixPerSecond", pixelsPerSec / 1000000, 10, 210, 30); } private: - explicit ContentLayerPainter(ContentLayerDelegate* delegate, TiledLayerChromium* layer) + explicit ContentLayerPainter(ContentLayerDelegate* delegate) : m_delegate(delegate) - , m_layer(layer) { } ContentLayerDelegate* m_delegate; - TiledLayerChromium* m_layer; }; PassRefPtr<ContentLayerChromium> ContentLayerChromium::create(ContentLayerDelegate* delegate) @@ -134,11 +126,11 @@ void ContentLayerChromium::createTextureUpdaterIfNeeded() if (m_textureUpdater) return; if (layerTreeHost()->settings().acceleratePainting) - m_textureUpdater = FrameBufferSkPictureCanvasLayerTextureUpdater::create(ContentLayerPainter::create(m_delegate, this)); + m_textureUpdater = FrameBufferSkPictureCanvasLayerTextureUpdater::create(ContentLayerPainter::create(m_delegate)); else if (layerTreeHost()->settings().perTilePainting) - m_textureUpdater = BitmapSkPictureCanvasLayerTextureUpdater::create(ContentLayerPainter::create(m_delegate, this), layerTreeHost()->layerRendererCapabilities().usingMapSub); + m_textureUpdater = BitmapSkPictureCanvasLayerTextureUpdater::create(ContentLayerPainter::create(m_delegate), layerTreeHost()->layerRendererCapabilities().usingMapSub); else - m_textureUpdater = BitmapCanvasLayerTextureUpdater::create(ContentLayerPainter::create(m_delegate, this), layerTreeHost()->layerRendererCapabilities().usingMapSub); + m_textureUpdater = BitmapCanvasLayerTextureUpdater::create(ContentLayerPainter::create(m_delegate), layerTreeHost()->layerRendererCapabilities().usingMapSub); m_textureUpdater->setOpaque(opaque()); GC3Denum textureFormat = layerTreeHost()->layerRendererCapabilities().bestTextureFormat; diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp index 74459a851..f61fd35d5 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp @@ -44,9 +44,10 @@ #include "cc/CCLayerTreeHost.h" #include "skia/ext/platform_canvas.h" -namespace WebCore { - using namespace std; +using WebKit::WebTransformationMatrix; + +namespace WebCore { static int s_nextLayerId = 1; @@ -361,7 +362,7 @@ void LayerChromium::setPosition(const FloatPoint& position) setNeedsCommit(); } -void LayerChromium::setSublayerTransform(const TransformationMatrix& sublayerTransform) +void LayerChromium::setSublayerTransform(const WebTransformationMatrix& sublayerTransform) { if (m_sublayerTransform == sublayerTransform) return; @@ -369,7 +370,7 @@ void LayerChromium::setSublayerTransform(const TransformationMatrix& sublayerTra setNeedsCommit(); } -void LayerChromium::setTransform(const TransformationMatrix& transform) +void LayerChromium::setTransform(const WebTransformationMatrix& transform) { if (m_transform == transform) return; @@ -590,7 +591,7 @@ void LayerChromium::setOpacityFromAnimation(float opacity) m_opacity = opacity; } -void LayerChromium::setTransformFromAnimation(const TransformationMatrix& transform) +void LayerChromium::setTransformFromAnimation(const WebTransformationMatrix& transform) { // This is called due to an ongoing accelerated animation. Since this animation is // also being run on the impl thread, there is no need to request a commit to push diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerChromium.h index 9be0279e2..a93d1760f 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.h @@ -41,11 +41,11 @@ #include "Region.h" #include "RenderSurfaceChromium.h" #include "ShaderChromium.h" -#include "TransformationMatrix.h" #include "cc/CCLayerAnimationController.h" #include "cc/CCOcclusionTracker.h" #include <public/WebFilterOperations.h> +#include <public/WebTransformationMatrix.h> #include <wtf/OwnPtr.h> #include <wtf/PassOwnPtr.h> #include <wtf/PassRefPtr.h> @@ -77,8 +77,8 @@ public: virtual int id() const OVERRIDE { return m_layerId; } virtual void setOpacityFromAnimation(float) OVERRIDE; virtual float opacity() const OVERRIDE { return m_opacity; } - virtual void setTransformFromAnimation(const TransformationMatrix&) OVERRIDE; - virtual const TransformationMatrix& transform() const OVERRIDE { return m_transform; } + virtual void setTransformFromAnimation(const WebKit::WebTransformationMatrix&) OVERRIDE; + virtual const WebKit::WebTransformationMatrix& transform() const OVERRIDE { return m_transform; } virtual const IntSize& bounds() const OVERRIDE { return m_bounds; } const LayerChromium* rootLayer() const; @@ -130,10 +130,10 @@ public: void setPosition(const FloatPoint&); FloatPoint position() const { return m_position; } - void setSublayerTransform(const TransformationMatrix&); - const TransformationMatrix& sublayerTransform() const { return m_sublayerTransform; } + void setSublayerTransform(const WebKit::WebTransformationMatrix&); + const WebKit::WebTransformationMatrix& sublayerTransform() const { return m_sublayerTransform; } - void setTransform(const TransformationMatrix&); + void setTransform(const WebKit::WebTransformationMatrix&); bool transformIsAnimating() const; const IntRect& visibleLayerRect() const { return m_visibleLayerRect; } @@ -213,11 +213,11 @@ public: void setScreenSpaceTransformIsAnimating(bool animating) { m_screenSpaceTransformIsAnimating = animating; } // This moves from layer space, with origin in the center to target space with origin in the top left - const TransformationMatrix& drawTransform() const { return m_drawTransform; } - void setDrawTransform(const TransformationMatrix& matrix) { m_drawTransform = matrix; } + const WebKit::WebTransformationMatrix& drawTransform() const { return m_drawTransform; } + void setDrawTransform(const WebKit::WebTransformationMatrix& matrix) { m_drawTransform = matrix; } // This moves from layer space, with origin the top left to screen space with origin in the top left - const TransformationMatrix& screenSpaceTransform() const { return m_screenSpaceTransform; } - void setScreenSpaceTransform(const TransformationMatrix& matrix) { m_screenSpaceTransform = matrix; } + const WebKit::WebTransformationMatrix& screenSpaceTransform() const { return m_screenSpaceTransform; } + void setScreenSpaceTransform(const WebKit::WebTransformationMatrix& matrix) { m_screenSpaceTransform = matrix; } const IntRect& drawableContentRect() const { return m_drawableContentRect; } void setDrawableContentRect(const IntRect& rect) { m_drawableContentRect = rect; } float contentsScale() const { return m_contentsScale; } @@ -334,8 +334,8 @@ private: bool m_drawCheckerboardForMissingTiles; bool m_forceRenderSurface; - TransformationMatrix m_transform; - TransformationMatrix m_sublayerTransform; + WebKit::WebTransformationMatrix m_transform; + WebKit::WebTransformationMatrix m_sublayerTransform; // Replica layer used for reflections. RefPtr<LayerChromium> m_replicaLayer; @@ -346,8 +346,8 @@ private: bool m_drawOpacityIsAnimating; IntRect m_clipRect; RenderSurfaceChromium* m_targetRenderSurface; - TransformationMatrix m_drawTransform; - TransformationMatrix m_screenSpaceTransform; + WebKit::WebTransformationMatrix m_drawTransform; + WebKit::WebTransformationMatrix m_screenSpaceTransform; bool m_drawTransformIsAnimating; bool m_screenSpaceTransformIsAnimating; IntRect m_drawableContentRect; diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp index a9f3d4665..acacc353b 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp @@ -46,6 +46,8 @@ #include "PlatformColor.h" #include "PlatformContextSkia.h" #include "RenderSurfaceChromium.h" +#include "SharedGraphicsContext3D.h" +#include "SkBitmap.h" #include "TextureCopier.h" #include "TextureManager.h" #include "ThrottledTextureUploader.h" @@ -56,11 +58,13 @@ #include "cc/CCDebugBorderDrawQuad.h" #include "cc/CCIOSurfaceDrawQuad.h" #include "cc/CCLayerImpl.h" +#include "cc/CCLayerQuad.h" #include "cc/CCLayerTreeHostCommon.h" #include "cc/CCMathUtil.h" #include "cc/CCProxy.h" #include "cc/CCRenderPass.h" #include "cc/CCRenderSurfaceDrawQuad.h" +#include "cc/CCRenderSurfaceFilters.h" #include "cc/CCSolidColorDrawQuad.h" #include "cc/CCTextureDrawQuad.h" #include "cc/CCTileDrawQuad.h" @@ -70,16 +74,17 @@ #include <wtf/MainThread.h> using namespace std; +using WebKit::WebTransformationMatrix; namespace WebCore { namespace { -static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top) +static WebTransformationMatrix orthoMatrix(float left, float right, float bottom, float top) { float deltaX = right - left; float deltaY = top - bottom; - TransformationMatrix ortho; + WebTransformationMatrix ortho; if (!deltaX || !deltaY) return ortho; ortho.setM11(2.0f / deltaX); @@ -94,9 +99,9 @@ static TransformationMatrix orthoMatrix(float left, float right, float bottom, f return ortho; } -static TransformationMatrix screenMatrix(int x, int y, int width, int height) +static WebTransformationMatrix screenMatrix(int x, int y, int width, int height) { - TransformationMatrix screen; + WebTransformationMatrix screen; // Map to viewport. screen.translate3d(x, y, 0); @@ -522,7 +527,7 @@ void LayerRendererChromium::drawCheckerboardQuad(const CCCheckerboardDrawQuad* q GLC(context(), context()->useProgram(program->program())); IntRect tileRect = quad->quadRect(); - TransformationMatrix tileTransform = quad->quadTransform(); + WebTransformationMatrix tileTransform = quad->quadTransform(); tileTransform.translate(tileRect.x() + tileRect.width() / 2.0, tileRect.y() + tileRect.height() / 2.0); float texOffsetX = tileRect.x(); @@ -551,7 +556,7 @@ void LayerRendererChromium::drawDebugBorderQuad(const CCDebugBorderDrawQuad* qua GLC(context(), context()->useProgram(program->program())); const IntRect& layerRect = quad->quadRect(); - TransformationMatrix renderMatrix = quad->quadTransform(); + WebTransformationMatrix renderMatrix = quad->quadTransform(); renderMatrix.translate(0.5 * layerRect.width() + layerRect.x(), 0.5 * layerRect.height() + layerRect.y()); renderMatrix.scaleNonUniform(layerRect.width(), layerRect.height()); LayerRendererChromium::toGLMatrix(&glMatrix[0], projectionMatrix() * renderMatrix); @@ -568,7 +573,21 @@ void LayerRendererChromium::drawDebugBorderQuad(const CCDebugBorderDrawQuad* qua GLC(context(), context()->drawElements(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short))); } -void LayerRendererChromium::drawBackgroundFilters(const CCRenderSurfaceDrawQuad* quad) +static inline SkBitmap applyFilters(LayerRendererChromium* layerRenderer, const WebKit::WebFilterOperations& filters, ManagedTexture* sourceTexture) +{ + if (filters.isEmpty()) + return SkBitmap(); + + RefPtr<GraphicsContext3D> filterContext = CCProxy::hasImplThread() ? SharedGraphicsContext3D::getForImplThread() : SharedGraphicsContext3D::get(); + if (!filterContext) + return SkBitmap(); + + layerRenderer->context()->flush(); + + return CCRenderSurfaceFilters::apply(filters, sourceTexture->textureId(), sourceTexture->size(), filterContext.get()); +} + +void LayerRendererChromium::drawBackgroundFilters(const CCRenderSurfaceDrawQuad* quad, const WebTransformationMatrix& contentsDeviceTransform) { // This method draws a background filter, which applies a filter to any pixels behind the quad and seen through its background. // The algorithm works as follows: @@ -585,7 +604,7 @@ void LayerRendererChromium::drawBackgroundFilters(const CCRenderSurfaceDrawQuad* // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5. CCRenderSurface* drawingSurface = quad->layer()->renderSurface(); - if (drawingSurface->backgroundFilters().isEmpty()) + if (quad->backgroundFilters().isEmpty()) return; // FIXME: We only allow background filters on the root render surface because other surfaces may contain @@ -593,17 +612,21 @@ void LayerRendererChromium::drawBackgroundFilters(const CCRenderSurfaceDrawQuad* if (!isCurrentRenderSurface(m_defaultRenderSurface)) return; - const TransformationMatrix& surfaceDrawTransform = quad->isReplica() ? drawingSurface->replicaDrawTransform() : drawingSurface->drawTransform(); - // FIXME: Do a single readback for both the surface and replica and cache the filtered results (once filter textures are not reused). - IntRect deviceRect = drawingSurface->readbackDeviceContentRect(this, surfaceDrawTransform); + IntRect deviceRect = enclosingIntRect(CCMathUtil::mapClippedRect(contentsDeviceTransform, sharedGeometryQuad().boundingBox())); + + int top, right, bottom, left; + quad->backgroundFilters().getOutsets(top, right, bottom, left); + deviceRect.move(-left, -top); + deviceRect.expand(left + right, top + bottom); + deviceRect.intersect(m_currentRenderSurface->contentRect()); OwnPtr<ManagedTexture> deviceBackgroundTexture = ManagedTexture::create(m_renderSurfaceTextureManager.get()); if (!getFramebufferTexture(deviceBackgroundTexture.get(), deviceRect)) return; - SkBitmap filteredDeviceBackground = drawingSurface->applyFilters(this, drawingSurface->backgroundFilters(), deviceBackgroundTexture.get()); + SkBitmap filteredDeviceBackground = applyFilters(this, quad->backgroundFilters(), deviceBackgroundTexture.get()); if (!filteredDeviceBackground.getTexture()) return; @@ -613,29 +636,144 @@ void LayerRendererChromium::drawBackgroundFilters(const CCRenderSurfaceDrawQuad* if (!drawingSurface->prepareBackgroundTexture(this)) return; - // This must be computed before switching the target render surface to the background texture. - TransformationMatrix contentsDeviceTransform = drawingSurface->computeDeviceTransform(this, surfaceDrawTransform); - CCRenderSurface* targetRenderSurface = m_currentRenderSurface; - if (useManagedTexture(drawingSurface->backgroundTexture(), drawingSurface->contentRect())) { - drawingSurface->copyDeviceToBackgroundTexture(this, filteredDeviceBackgroundTextureId, deviceRect, contentsDeviceTransform); + if (useManagedTexture(drawingSurface->backgroundTexture(), quad->quadRect())) { + // Copy the readback pixels from device to the background texture for the surface. + WebTransformationMatrix deviceToSurfaceTransform; + deviceToSurfaceTransform.translate(quad->quadRect().width() / 2.0, quad->quadRect().height() / 2.0); + deviceToSurfaceTransform.scale3d(quad->quadRect().width(), quad->quadRect().height(), 1); + deviceToSurfaceTransform.multiply(contentsDeviceTransform.inverse()); + deviceToSurfaceTransform.translate(deviceRect.width() / 2.0, deviceRect.height() / 2.0); + deviceToSurfaceTransform.translate(deviceRect.x(), deviceRect.y()); + + copyTextureToFramebuffer(filteredDeviceBackgroundTextureId, deviceRect.size(), deviceToSurfaceTransform); + useRenderSurface(targetRenderSurface); } } void LayerRendererChromium::drawRenderSurfaceQuad(const CCRenderSurfaceDrawQuad* quad) { - CCLayerImpl* layer = quad->layer(); + // The replica is always drawn first, so free after drawing the contents. + bool shouldReleaseTextures = !quad->isReplica(); - drawBackgroundFilters(quad); + CCRenderSurface* drawingSurface = quad->layer()->renderSurface(); - layer->renderSurface()->setScissorRect(this, quad->surfaceDamageRect()); - if (quad->isReplica()) - layer->renderSurface()->drawReplica(this); - else - layer->renderSurface()->drawContents(this); - layer->renderSurface()->releaseBackgroundTexture(); - layer->renderSurface()->releaseContentsTexture(); + WebTransformationMatrix renderTransform = quad->layerTransform(); + // Apply a scaling factor to size the quad from 1x1 to its intended size. + renderTransform.scale3d(quad->quadRect().width(), quad->quadRect().height(), 1); + WebTransformationMatrix contentsDeviceTransform = WebTransformationMatrix(windowMatrix() * projectionMatrix() * renderTransform).to2dTransform(); + + // Can only draw surface if device matrix is invertible. + if (!contentsDeviceTransform.isInvertible() || !drawingSurface->hasValidContentsTexture()) { + if (shouldReleaseTextures) { + drawingSurface->releaseBackgroundTexture(); + drawingSurface->releaseContentsTexture(); + } + return; + } + + drawBackgroundFilters(quad, contentsDeviceTransform); + + // FIXME: Remove this call when the quad's scissorRect() is set correctly. + drawingSurface->setScissorRect(this, quad->surfaceDamageRect()); + + // FIXME: Cache this value so that we don't have to do it for both the surface and its replica. + // Apply filters to the contents texture. + SkBitmap filterBitmap = applyFilters(this, quad->filters(), drawingSurface->contentsTexture()); + int contentsTextureId = drawingSurface->contentsTexture()->textureId(); + if (filterBitmap.getTexture()) { + GrTexture* texture = reinterpret_cast<GrTexture*>(filterBitmap.getTexture()); + contentsTextureId = texture->getTextureHandle(); + } + + // Draw the background texture if there is one. + if (drawingSurface->hasValidBackgroundTexture()) + copyTextureToFramebuffer(drawingSurface->backgroundTexture()->textureId(), quad->quadRect().size(), quad->layerTransform()); + + FloatQuad deviceQuad = contentsDeviceTransform.mapQuad(sharedGeometryQuad()); + CCLayerQuad deviceLayerBounds = CCLayerQuad(FloatQuad(deviceQuad.boundingBox())); + CCLayerQuad deviceLayerEdges = CCLayerQuad(deviceQuad); + + // Use anti-aliasing programs only when necessary. + bool useAA = (!deviceQuad.isRectilinear() || !deviceQuad.boundingBox().isExpressibleAsIntRect()); + if (useAA) { + deviceLayerBounds.inflateAntiAliasingDistance(); + deviceLayerEdges.inflateAntiAliasingDistance(); + } + + bool useMask = quad->maskTextureId(); + + // FIXME: use the backgroundTexture and blend the background in with this draw instead of having a separate copy of the background texture. + + GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0)); + context()->bindTexture(GraphicsContext3D::TEXTURE_2D, contentsTextureId); + + int shaderQuadLocation = -1; + int shaderEdgeLocation = -1; + int shaderMaskSamplerLocation = -1; + int shaderMatrixLocation = -1; + int shaderAlphaLocation = -1; + if (useAA && useMask) { + const RenderSurfaceMaskProgramAA* program = renderSurfaceMaskProgramAA(); + GLC(context(), context()->useProgram(program->program())); + GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0)); + + shaderQuadLocation = program->vertexShader().pointLocation(); + shaderEdgeLocation = program->fragmentShader().edgeLocation(); + shaderMaskSamplerLocation = program->fragmentShader().maskSamplerLocation(); + shaderMatrixLocation = program->vertexShader().matrixLocation(); + shaderAlphaLocation = program->fragmentShader().alphaLocation(); + } else if (!useAA && useMask) { + const RenderSurfaceMaskProgram* program = renderSurfaceMaskProgram(); + GLC(context(), context()->useProgram(program->program())); + GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0)); + + shaderMaskSamplerLocation = program->fragmentShader().maskSamplerLocation(); + shaderMatrixLocation = program->vertexShader().matrixLocation(); + shaderAlphaLocation = program->fragmentShader().alphaLocation(); + } else if (useAA && !useMask) { + const RenderSurfaceProgramAA* program = renderSurfaceProgramAA(); + GLC(context(), context()->useProgram(program->program())); + GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0)); + + shaderQuadLocation = program->vertexShader().pointLocation(); + shaderEdgeLocation = program->fragmentShader().edgeLocation(); + shaderMatrixLocation = program->vertexShader().matrixLocation(); + shaderAlphaLocation = program->fragmentShader().alphaLocation(); + } else { + const RenderSurfaceProgram* program = renderSurfaceProgram(); + GLC(context(), context()->useProgram(program->program())); + GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0)); + + shaderMatrixLocation = program->vertexShader().matrixLocation(); + shaderAlphaLocation = program->fragmentShader().alphaLocation(); + } + + if (shaderMaskSamplerLocation != -1) { + GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE1)); + GLC(context(), context()->uniform1i(shaderMaskSamplerLocation, 1)); + context()->bindTexture(GraphicsContext3D::TEXTURE_2D, quad->maskTextureId()); + GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0)); + } + + if (shaderEdgeLocation != -1) { + float edge[24]; + deviceLayerEdges.toFloatArray(edge); + deviceLayerBounds.toFloatArray(&edge[12]); + GLC(context(), context()->uniform3fv(shaderEdgeLocation, 8, edge)); + } + + // Map device space quad to surface space. + FloatQuad surfaceQuad = contentsDeviceTransform.inverse().mapQuad(deviceLayerEdges.floatQuad()); + + drawTexturedQuad(quad->layerTransform(), quad->quadRect().width(), quad->quadRect().height(), quad->opacity(), surfaceQuad, + shaderMatrixLocation, shaderAlphaLocation, shaderQuadLocation); + + if (shouldReleaseTextures) { + drawingSurface->releaseBackgroundTexture(); + drawingSurface->releaseContentsTexture(); + } } void LayerRendererChromium::drawSolidColorQuad(const CCSolidColorDrawQuad* quad) @@ -645,7 +783,7 @@ void LayerRendererChromium::drawSolidColorQuad(const CCSolidColorDrawQuad* quad) IntRect tileRect = quad->quadRect(); - TransformationMatrix tileTransform = quad->quadTransform(); + WebTransformationMatrix tileTransform = quad->quadTransform(); tileTransform.translate(tileRect.x() + tileRect.width() / 2.0, tileRect.y() + tileRect.height() / 2.0); const Color& color = quad->color(); @@ -721,7 +859,7 @@ void LayerRendererChromium::drawTileQuad(const CCTileDrawQuad* quad) FloatQuad localQuad; - TransformationMatrix deviceTransform = TransformationMatrix(windowMatrix() * projectionMatrix() * quad->quadTransform()).to2dTransform(); + WebTransformationMatrix deviceTransform = WebTransformationMatrix(windowMatrix() * projectionMatrix() * quad->quadTransform()).to2dTransform(); if (!deviceTransform.isInvertible()) return; @@ -810,7 +948,7 @@ void LayerRendererChromium::drawTileQuad(const CCTileDrawQuad* quad) CCLayerQuad deviceQuad(leftEdge, topEdge, rightEdge, bottomEdge); // Map quad to layer space. - TransformationMatrix inverseDeviceTransform = deviceTransform.inverse(); + WebTransformationMatrix inverseDeviceTransform = deviceTransform.inverse(); localQuad = inverseDeviceTransform.mapQuad(deviceQuad.floatQuad()); } else { // Move fragment shader transform to vertex shader. We can do this while @@ -1083,7 +1221,7 @@ void LayerRendererChromium::drawHeadsUpDisplay(ManagedTexture* hudTexture, const GLC(m_context, m_context->useProgram(program->program())); GLC(m_context, m_context->uniform1i(program->fragmentShader().samplerLocation(), 0)); - TransformationMatrix matrix; + WebTransformationMatrix matrix; matrix.translate3d(hudSize.width() * 0.5, hudSize.height() * 0.5, 0); drawTexturedQuad(matrix, hudSize.width(), hudSize.height(), 1, sharedGeometryQuad(), program->vertexShader().matrixLocation(), @@ -1096,6 +1234,8 @@ void LayerRendererChromium::finishDrawingFrame() GLC(m_context, m_context->disable(GraphicsContext3D::SCISSOR_TEST)); GLC(m_context, m_context->disable(GraphicsContext3D::BLEND)); + m_renderSurfaceTextureManager->unprotectAllTextures(); + size_t contentsMemoryUseBytes = m_contentsTextureAllocator->currentMemoryUseBytes(); size_t reclaimLimit = TextureManager::reclaimLimitBytes(viewportSize()); size_t preferredLimit = reclaimLimit > contentsMemoryUseBytes ? reclaimLimit - contentsMemoryUseBytes : 0; @@ -1104,7 +1244,7 @@ void LayerRendererChromium::finishDrawingFrame() m_renderSurfaceTextureManager->deleteEvictedTextures(m_renderSurfaceTextureAllocator.get()); } -void LayerRendererChromium::toGLMatrix(float* flattened, const TransformationMatrix& m) +void LayerRendererChromium::toGLMatrix(float* flattened, const WebTransformationMatrix& m) { flattened[0] = m.m11(); flattened[1] = m.m12(); @@ -1124,13 +1264,13 @@ void LayerRendererChromium::toGLMatrix(float* flattened, const TransformationMat flattened[15] = m.m44(); } -void LayerRendererChromium::drawTexturedQuad(const TransformationMatrix& drawMatrix, +void LayerRendererChromium::drawTexturedQuad(const WebTransformationMatrix& drawMatrix, float width, float height, float opacity, const FloatQuad& quad, int matrixLocation, int alphaLocation, int quadLocation) { static float glMatrix[16]; - TransformationMatrix renderMatrix = drawMatrix; + WebTransformationMatrix renderMatrix = drawMatrix; // Apply a scaling factor to size the quad from 1x1 to its intended size. renderMatrix.scale3d(width, height, 1); @@ -1159,6 +1299,25 @@ void LayerRendererChromium::drawTexturedQuad(const TransformationMatrix& drawMat GLC(m_context, m_context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0)); } +void LayerRendererChromium::copyTextureToFramebuffer(int textureId, const IntSize& bounds, const WebTransformationMatrix& drawMatrix) +{ + const RenderSurfaceProgram* program = renderSurfaceProgram(); + + GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0)); + GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId)); + GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR)); + GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR)); + GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE)); + GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE)); + + GLC(context(), context()->useProgram(program->program())); + GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0)); + drawTexturedQuad(drawMatrix, bounds.width(), bounds.height(), 1, sharedGeometryQuad(), + program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation(), + -1); +} + void LayerRendererChromium::finish() { TRACE_EVENT("LayerRendererChromium::finish", this, 0); diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h index 1a2ebed0e..0f965a8b4 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h +++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h @@ -107,8 +107,8 @@ public: static void debugGLCall(GraphicsContext3D*, const char* command, const char* file, int line); - const TransformationMatrix& projectionMatrix() const { return m_projectionMatrix; } - const TransformationMatrix& windowMatrix() const { return m_windowMatrix; } + const WebKit::WebTransformationMatrix& projectionMatrix() const { return m_projectionMatrix; } + const WebKit::WebTransformationMatrix& windowMatrix() const { return m_windowMatrix; } const GeometryBinding* sharedGeometry() const { return m_sharedGeometry.get(); } const FloatQuad& sharedGeometryQuad() const { return m_sharedGeometryQuad; } @@ -131,10 +131,11 @@ public: GC3Denum bestTextureFormat(); - static void toGLMatrix(float*, const TransformationMatrix&); - void drawTexturedQuad(const TransformationMatrix& layerMatrix, + static void toGLMatrix(float*, const WebKit::WebTransformationMatrix&); + void drawTexturedQuad(const WebKit::WebTransformationMatrix& layerMatrix, float width, float height, float opacity, const FloatQuad&, int matrixLocation, int alphaLocation, int quadLocation); + void copyTextureToFramebuffer(int textureId, const IntSize& bounds, const WebKit::WebTransformationMatrix& drawMatrix); protected: friend class LayerRendererGpuMemoryAllocationChangedCallbackAdapter; @@ -153,7 +154,7 @@ private: void drawQuad(const CCDrawQuad*, const FloatRect& surfaceDamageRect); void drawCheckerboardQuad(const CCCheckerboardDrawQuad*); void drawDebugBorderQuad(const CCDebugBorderDrawQuad*); - void drawBackgroundFilters(const CCRenderSurfaceDrawQuad*); + void drawBackgroundFilters(const CCRenderSurfaceDrawQuad*, const WebKit::WebTransformationMatrix& deviceTransform); void drawRenderSurfaceQuad(const CCRenderSurfaceDrawQuad*); void drawSolidColorQuad(const CCSolidColorDrawQuad*); void drawTextureQuad(const CCTextureDrawQuad*); @@ -194,8 +195,8 @@ private: LayerRendererCapabilities m_capabilities; - TransformationMatrix m_projectionMatrix; - TransformationMatrix m_windowMatrix; + WebKit::WebTransformationMatrix m_projectionMatrix; + WebKit::WebTransformationMatrix m_windowMatrix; CCRenderSurface* m_currentRenderSurface; ManagedTexture* m_currentManagedTexture; diff --git a/Source/WebCore/platform/graphics/chromium/LinkHighlight.cpp b/Source/WebCore/platform/graphics/chromium/LinkHighlight.cpp index 53536b32c..bcb7b3c36 100644 --- a/Source/WebCore/platform/graphics/chromium/LinkHighlight.cpp +++ b/Source/WebCore/platform/graphics/chromium/LinkHighlight.cpp @@ -34,6 +34,8 @@ #if USE(ACCELERATED_COMPOSITING) +using WebKit::WebTransformationMatrix; + namespace WebCore { PassRefPtr<LinkHighlight> LinkHighlight::create(GraphicsLayerChromium* parent, const Path& path, int animationId, int groupId) @@ -52,7 +54,7 @@ LinkHighlight::LinkHighlight(GraphicsLayerChromium* parent, const Path& path, in m_contentLayer->setBounds(rect.size()); - TransformationMatrix transform; + WebTransformationMatrix transform; transform.translate(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2); m_contentLayer->setTransform(transform); diff --git a/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp b/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp index 267e01957..376434e62 100644 --- a/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp +++ b/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp @@ -29,6 +29,7 @@ #include "ProgramBinding.h" +#include "Extensions3D.h" #include "GeometryBinding.h" #include "GraphicsContext.h" #include "GraphicsContext3D.h" @@ -50,10 +51,16 @@ ProgramBindingBase::~ProgramBindingBase() ASSERT(!m_initialized); } +static bool contextLost(GraphicsContext3D* context) +{ + return (context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR); +} + + void ProgramBindingBase::init(GraphicsContext3D* context, const String& vertexShader, const String& fragmentShader) { m_program = createShaderProgram(context, vertexShader, fragmentShader); - ASSERT(m_program); + ASSERT(m_program || contextLost(context)); } void ProgramBindingBase::cleanup(GraphicsContext3D* context) @@ -91,20 +98,23 @@ unsigned ProgramBindingBase::createShaderProgram(GraphicsContext3D* context, con TRACE_EVENT("ProgramBindingBase::createShaderProgram", this, 0); unsigned vertexShader = loadShader(context, GraphicsContext3D::VERTEX_SHADER, vertexShaderSource); if (!vertexShader) { - LOG_ERROR("Failed to create vertex shader"); + if (!contextLost(context)) + LOG_ERROR("Failed to create vertex shader"); return 0; } unsigned fragmentShader = loadShader(context, GraphicsContext3D::FRAGMENT_SHADER, fragmentShaderSource); if (!fragmentShader) { GLC(context, context->deleteShader(vertexShader)); - LOG_ERROR("Failed to create fragment shader"); + if (!contextLost(context)) + LOG_ERROR("Failed to create fragment shader"); return 0; } unsigned programObject = context->createProgram(); if (!programObject) { - LOG_ERROR("Failed to create shader program"); + if (!contextLost(context)) + LOG_ERROR("Failed to create shader program"); return 0; } @@ -120,7 +130,8 @@ unsigned ProgramBindingBase::createShaderProgram(GraphicsContext3D* context, con int linked = 0; GLC(context, context->getProgramiv(programObject, GraphicsContext3D::LINK_STATUS, &linked)); if (!linked) { - LOG_ERROR("Failed to link shader program"); + if (!contextLost(context)) + LOG_ERROR("Failed to link shader program"); GLC(context, context->deleteProgram(programObject)); return 0; } diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp index f5fe9a7b5..80a8a03eb 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp @@ -64,6 +64,14 @@ FloatRect RenderSurfaceChromium::drawableContentRect() const return drawableContentRect; } +RenderSurfaceChromium* RenderSurfaceChromium::targetRenderSurface() const +{ + LayerChromium* parent = m_owningLayer->parent(); + if (!parent) + return 0; + return parent->targetRenderSurface(); +} + bool RenderSurfaceChromium::hasReplica() const { return m_owningLayer->replicaLayer(); diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h index 8d017a313..e6711ef2a 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h @@ -34,8 +34,8 @@ #include "ProgramBinding.h" #include "ShaderChromium.h" #include "TextureManager.h" -#include "TransformationMatrix.h" #include <public/WebFilterOperations.h> +#include <public/WebTransformationMatrix.h> #include <wtf/Noncopyable.h> namespace WebCore { @@ -65,23 +65,23 @@ public: // This goes from content space with the origin in the center of the rect being transformed to the target space with the origin in the top left of the // rect being transformed. Position the rect so that the origin is in the center of it before applying this transform. - const TransformationMatrix& drawTransform() const { return m_drawTransform; } - void setDrawTransform(const TransformationMatrix& drawTransform) { m_drawTransform = drawTransform; } + const WebKit::WebTransformationMatrix& drawTransform() const { return m_drawTransform; } + void setDrawTransform(const WebKit::WebTransformationMatrix& drawTransform) { m_drawTransform = drawTransform; } - const TransformationMatrix& originTransform() const { return m_originTransform; } - void setOriginTransform(const TransformationMatrix& originTransform) { m_originTransform = originTransform; } + const WebKit::WebTransformationMatrix& originTransform() const { return m_originTransform; } + void setOriginTransform(const WebKit::WebTransformationMatrix& originTransform) { m_originTransform = originTransform; } - const TransformationMatrix& screenSpaceTransform() const { return m_screenSpaceTransform; } - void setScreenSpaceTransform(const TransformationMatrix& screenSpaceTransform) { m_screenSpaceTransform = screenSpaceTransform; } + const WebKit::WebTransformationMatrix& screenSpaceTransform() const { return m_screenSpaceTransform; } + void setScreenSpaceTransform(const WebKit::WebTransformationMatrix& screenSpaceTransform) { m_screenSpaceTransform = screenSpaceTransform; } - const TransformationMatrix& replicaDrawTransform() const { return m_replicaDrawTransform; } - void setReplicaDrawTransform(const TransformationMatrix& replicaDrawTransform) { m_replicaDrawTransform = replicaDrawTransform; } + const WebKit::WebTransformationMatrix& replicaDrawTransform() const { return m_replicaDrawTransform; } + void setReplicaDrawTransform(const WebKit::WebTransformationMatrix& replicaDrawTransform) { m_replicaDrawTransform = replicaDrawTransform; } - const TransformationMatrix& replicaOriginTransform() const { return m_replicaOriginTransform; } - void setReplicaOriginTransform(const TransformationMatrix& replicaOriginTransform) { m_replicaOriginTransform = replicaOriginTransform; } + const WebKit::WebTransformationMatrix& replicaOriginTransform() const { return m_replicaOriginTransform; } + void setReplicaOriginTransform(const WebKit::WebTransformationMatrix& replicaOriginTransform) { m_replicaOriginTransform = replicaOriginTransform; } - const TransformationMatrix& replicaScreenSpaceTransform() const { return m_replicaScreenSpaceTransform; } - void setReplicaScreenSpaceTransform(const TransformationMatrix& replicaScreenSpaceTransform) { m_replicaScreenSpaceTransform = replicaScreenSpaceTransform; } + const WebKit::WebTransformationMatrix& replicaScreenSpaceTransform() const { return m_replicaScreenSpaceTransform; } + void setReplicaScreenSpaceTransform(const WebKit::WebTransformationMatrix& replicaScreenSpaceTransform) { m_replicaScreenSpaceTransform = replicaScreenSpaceTransform; } bool targetSurfaceTransformsAreAnimating() const { return m_targetSurfaceTransformsAreAnimating; } void setTargetSurfaceTransformsAreAnimating(bool animating) { m_targetSurfaceTransformsAreAnimating = animating; } @@ -108,6 +108,8 @@ public: void setNearestAncestorThatMovesPixels(RenderSurfaceChromium* surface) { m_nearestAncestorThatMovesPixels = surface; } const RenderSurfaceChromium* nearestAncestorThatMovesPixels() const { return m_nearestAncestorThatMovesPixels; } + RenderSurfaceChromium* targetRenderSurface() const; + bool hasReplica() const; bool hasMask() const; @@ -122,12 +124,12 @@ private: float m_drawOpacity; bool m_drawOpacityIsAnimating; - TransformationMatrix m_drawTransform; - TransformationMatrix m_originTransform; - TransformationMatrix m_screenSpaceTransform; - TransformationMatrix m_replicaDrawTransform; - TransformationMatrix m_replicaOriginTransform; - TransformationMatrix m_replicaScreenSpaceTransform; + WebKit::WebTransformationMatrix m_drawTransform; + WebKit::WebTransformationMatrix m_originTransform; + WebKit::WebTransformationMatrix m_screenSpaceTransform; + WebKit::WebTransformationMatrix m_replicaDrawTransform; + WebKit::WebTransformationMatrix m_replicaOriginTransform; + WebKit::WebTransformationMatrix m_replicaScreenSpaceTransform; bool m_targetSurfaceTransformsAreAnimating; bool m_screenSpaceTransformsAreAnimating; WebKit::WebFilterOperations m_filters; diff --git a/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp index d029d775f..12e3717ca 100644 --- a/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp @@ -29,13 +29,10 @@ #include "TiledLayerChromium.h" -#include "FontCache.h" -#include "FontDescription.h" #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" #include "ManagedTexture.h" #include "Region.h" -#include "TextRun.h" #include "TextStream.h" #include "TraceEvent.h" @@ -47,6 +44,7 @@ #include <wtf/MathExtras.h> using namespace std; +using WebKit::WebTransformationMatrix; namespace WebCore { @@ -76,15 +74,11 @@ public: bool partialUpdate; bool updated; bool isInUseOnImpl; - int lastUpdateFrame; - int totalPaintCount; private: explicit UpdatableTile(PassOwnPtr<LayerTextureUpdater::Texture> texture) : partialUpdate(false) , updated(false) , isInUseOnImpl(false) - , lastUpdateFrame(0) - , totalPaintCount(0) , m_texture(texture) { } @@ -416,13 +410,6 @@ void TiledLayerChromium::updateTiles(bool idle, int left, int top, int right, in return; } - if (tile->isDirty() && layerTreeHost()->settings().debugShowTileInfo) { - // Invalidate the entire tile so that text updates. - tile->dirtyRect = m_tiler->tileRect(tile); - tile->lastUpdateFrame = layerTreeHost()->frameNumber(); - tile->totalPaintCount++; - } - paintRect.unite(tile->dirtyRect); } } @@ -503,7 +490,7 @@ void TiledLayerChromium::updateTiles(bool idle, int left, int top, int right, in tile->texture()->prepareRect(sourceRect); if (occlusion) - occlusion->overdrawMetrics().didUpload(TransformationMatrix(), sourceRect, tile->opaqueRect()); + occlusion->overdrawMetrics().didUpload(WebTransformationMatrix(), sourceRect, tile->opaqueRect()); const IntPoint anchor = m_tiler->tileRect(tile).location(); @@ -726,71 +713,5 @@ IntRect TiledLayerChromium::idlePaintRect(const IntRect& visibleLayerRect) return prepaintRect; } -void TiledLayerChromium::paintDebugTileInfo(GraphicsContext& context, const IntRect& layerRect) -{ - FontCachePurgePreventer fontCachePurgePreventer; - - // Don't bother writing info onto small tiles. - const int minDimension = 200; - if (m_tiler->tileSize().width() < minDimension || m_tiler->tileSize().height() < minDimension) - return; - - if (!m_debugInfoFont) { - FontDescription fontDesc; - fontDesc.setGenericFamily(FontDescription::MonospaceFamily); - fontDesc.setComputedSize(10); - m_debugInfoFont = adoptPtr(new Font(fontDesc, 0, 0)); - m_debugInfoFont->update(0); - } - - int fontHeight = m_debugInfoFont->fontMetrics().floatHeight() + 2; - - int left, top, right, bottom; - m_tiler->layerRectToTileIndices(layerRect, left, top, right, bottom); - for (int j = top; j <= bottom; ++j) { - for (int i = left; i <= right; ++i) { - UpdatableTile* tile = tileAt(i, j); - if (!tile) - continue; - - IntRect tileRect = m_tiler->tileRect(tile); - String info[] = { - String::format("LayerId(%d)", id()), - String::format("Index(%d, %d)", i, j), - String::format("Tile(%d, %d, %d, %d)", tileRect.x(), tileRect.y(), tileRect.width(), tileRect.height()), - String::format("Frame(%d)", tile->lastUpdateFrame), - String::format("Count(%d)", tile->totalPaintCount), - String::format("Layer(%d, %d)", contentBounds().width(), contentBounds().height()), - }; - const size_t lines = sizeof(info) / sizeof(info[0]); - int width[lines]; - - IntPoint center = m_tiler->tileRect(tile).center(); - int currentY = center.y() - fontHeight * lines / 2; - - int maxWidth = 0; - for (size_t i = 0; i < lines; ++i) { - width[i] = m_debugInfoFont->width(TextRun(info[i])); - maxWidth = max(width[i], maxWidth); - } - - IntRect textRect(IntPoint(center.x() - maxWidth / 2, currentY - fontHeight / 2), IntSize(maxWidth, fontHeight * lines + fontHeight / 2)); - - context.setFillColor(Color(192, 192, 192, 192), ColorSpaceDeviceRGB); - context.fillRect(FloatRect(textRect)); - - context.setFillColor(Color(64, 64, 64), ColorSpaceDeviceRGB); - - for (size_t i = 0; i < lines; ++i) { - TextRun run(info[i]); - int textWidth = m_debugInfoFont->width(run); - IntPoint textStart(center.x() - textWidth / 2, currentY + fontHeight / 2); - context.drawText(*m_debugInfoFont, run, textStart); - currentY += fontHeight; - } - } - } -} - } #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h b/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h index ebc4ee492..ca389f2e4 100644 --- a/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h @@ -28,7 +28,6 @@ #if USE(ACCELERATED_COMPOSITING) -#include "Font.h" #include "LayerChromium.h" #include "cc/CCLayerTilingData.h" #include "cc/CCTiledLayerImpl.h" @@ -66,8 +65,6 @@ public: virtual Region visibleContentOpaqueRegion() const OVERRIDE; - void paintDebugTileInfo(GraphicsContext&, const IntRect&); - protected: TiledLayerChromium(); @@ -130,7 +127,6 @@ private: TilingOption m_tilingOption; OwnPtr<CCLayerTilingData> m_tiler; - OwnPtr<Font> m_debugInfoFont; }; } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCAnimationCurve.h b/Source/WebCore/platform/graphics/chromium/cc/CCAnimationCurve.h index 7f506a706..e21de8964 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCAnimationCurve.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCAnimationCurve.h @@ -25,14 +25,14 @@ #ifndef CCAnimationCurve_h #define CCAnimationCurve_h -#include "TransformationMatrix.h" - +#include <public/WebTransformationMatrix.h> #include <wtf/PassOwnPtr.h> namespace WebCore { class CCFloatAnimationCurve; class CCTransformAnimationCurve; +class IntSize; class TransformOperations; // An animation curve is a function that returns a value given a time. @@ -65,7 +65,7 @@ class CCTransformAnimationCurve : public CCAnimationCurve { public: virtual ~CCTransformAnimationCurve() { } - virtual TransformationMatrix getValue(double t, const IntSize& layerSize) const = 0; + virtual WebKit::WebTransformationMatrix getValue(double t, const IntSize& layerSize) const = 0; // Partial CCAnimation implementation. virtual Type type() const OVERRIDE { return Transform; } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp index 567bd1f1f..8fd3ed124 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp @@ -40,6 +40,8 @@ #include "cc/CCRenderSurface.h" #include <public/WebFilterOperations.h> +using WebKit::WebTransformationMatrix; + namespace WebCore { PassOwnPtr<CCDamageTracker> CCDamageTracker::create() @@ -244,7 +246,7 @@ void CCDamageTracker::extendDamageForLayer(CCLayerImpl* layer, FloatRect& target // Property changes take priority over update rects. // Compute the layer's "originTransform" by translating the drawTransform. - TransformationMatrix originTransform = layer->drawTransform(); + WebTransformationMatrix originTransform = layer->drawTransform(); originTransform.translate(-0.5 * layer->bounds().width(), -0.5 * layer->bounds().height()); bool layerIsNew = false; @@ -304,12 +306,12 @@ void CCDamageTracker::extendDamageForRenderSurface(CCLayerImpl* layer, FloatRect // If there was damage, transform it to target space, and possibly contribute its reflection if needed. if (!damageRectInLocalSpace.isEmpty()) { - const TransformationMatrix& originTransform = renderSurface->originTransform(); + const WebTransformationMatrix& originTransform = renderSurface->originTransform(); FloatRect damageRectInTargetSpace = CCMathUtil::mapClippedRect(originTransform, damageRectInLocalSpace); targetDamageRect.uniteIfNonZero(damageRectInTargetSpace); if (layer->replicaLayer()) { - const TransformationMatrix& replicaOriginTransform = renderSurface->replicaOriginTransform(); + const WebTransformationMatrix& replicaOriginTransform = renderSurface->replicaOriginTransform(); targetDamageRect.uniteIfNonZero(CCMathUtil::mapClippedRect(replicaOriginTransform, damageRectInLocalSpace)); } } @@ -322,7 +324,7 @@ void CCDamageTracker::extendDamageForRenderSurface(CCLayerImpl* layer, FloatRect removeRectFromCurrentFrame(replicaMaskLayer->id(), replicaIsNew); // Compute the replica's "originTransform" that maps from the replica's origin space to the target surface origin space. - const TransformationMatrix& replicaOriginTransform = renderSurface->replicaOriginTransform(); + const WebTransformationMatrix& replicaOriginTransform = renderSurface->replicaOriginTransform(); FloatRect replicaMaskLayerRect = CCMathUtil::mapClippedRect(replicaOriginTransform, FloatRect(FloatPoint::zero(), FloatSize(replicaMaskLayer->bounds().width(), replicaMaskLayer->bounds().height()))); saveRectForNextFrame(replicaMaskLayer->id(), replicaMaskLayerRect); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCDrawQuad.h b/Source/WebCore/platform/graphics/chromium/cc/CCDrawQuad.h index f4ef2d3f2..381cbaeac 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCDrawQuad.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCDrawQuad.h @@ -47,8 +47,8 @@ class CCDrawQuad { WTF_MAKE_NONCOPYABLE(CCDrawQuad); public: const IntRect& quadRect() const { return m_quadRect; } - const TransformationMatrix& quadTransform() const { return m_sharedQuadState->quadTransform(); } - const TransformationMatrix& layerTransform() const { return m_sharedQuadState->layerTransform(); } + const WebKit::WebTransformationMatrix& quadTransform() const { return m_sharedQuadState->quadTransform(); } + const WebKit::WebTransformationMatrix& layerTransform() const { return m_sharedQuadState->layerTransform(); } const IntRect& layerRect() const { return m_sharedQuadState->layerRect(); } const IntRect& clipRect() const { return m_sharedQuadState->clipRect(); } float opacity() const { return m_sharedQuadState->opacity(); } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.cpp index ae41fe069..4db39b69a 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.cpp @@ -37,6 +37,8 @@ #include <wtf/OwnPtr.h> +using WebKit::WebTransformationMatrix; + namespace WebCore { namespace { @@ -176,7 +178,7 @@ PassOwnPtr<CCTransformKeyframe> CCTransformKeyframe::clone() const } case TransformOperation::MATRIX: { MatrixTransformOperation* transform = static_cast<MatrixTransformOperation*>(m_value.operations()[j].get()); - TransformationMatrix m = transform->matrix(); + WebTransformationMatrix m = WebTransformationMatrix(transform->matrix()); operations.operations().append(MatrixTransformOperation::create(m.a(), m.b(), m.c(), m.d(), m.e(), m.f())); break; } @@ -287,18 +289,19 @@ PassOwnPtr<CCAnimationCurve> CCKeyframedTransformAnimationCurve::clone() const return toReturn.release(); } -TransformationMatrix CCKeyframedTransformAnimationCurve::getValue(double t, const IntSize& layerSize) const +WebTransformationMatrix CCKeyframedTransformAnimationCurve::getValue(double t, const IntSize& layerSize) const { + // Note: WebCore data type used here, just for now. TransformationMatrix transformMatrix; if (t <= m_keyframes.first()->time()) { m_keyframes.first()->value().apply(layerSize, transformMatrix); - return transformMatrix; + return WebTransformationMatrix(transformMatrix); } if (t >= m_keyframes.last()->time()) { m_keyframes.last()->value().apply(layerSize, transformMatrix); - return transformMatrix; + return WebTransformationMatrix(transformMatrix); } size_t i = 0; @@ -316,6 +319,7 @@ TransformationMatrix CCKeyframedTransformAnimationCurve::getValue(double t, cons for (size_t j = 0; j < m_keyframes[i+1]->value().size(); ++j) m_keyframes[i+1]->value().operations()[j]->blend(m_keyframes[i]->value().at(j), progress)->apply(transformMatrix, layerSize); } else { + // Note: WebCore data type used here, just for now. TransformationMatrix source; m_keyframes[i]->value().apply(layerSize, source); @@ -324,7 +328,7 @@ TransformationMatrix CCKeyframedTransformAnimationCurve::getValue(double t, cons transformMatrix.blend(source, progress); } - return transformMatrix; + return WebTransformationMatrix(transformMatrix); } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.h b/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.h index 8d1f0e055..e70cdafb7 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCKeyframedAnimationCurve.h @@ -116,7 +116,7 @@ public: virtual PassOwnPtr<CCAnimationCurve> clone() const OVERRIDE; // CCTransformAnimationCurve implementation - virtual TransformationMatrix getValue(double t, const IntSize&) const OVERRIDE; + virtual WebKit::WebTransformationMatrix getValue(double t, const IntSize&) const OVERRIDE; private: CCKeyframedTransformAnimationCurve(); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp index 14fb78a65..096979544 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp @@ -27,12 +27,14 @@ #include "cc/CCLayerAnimationController.h" #include "GraphicsLayer.h" // for KeyframeValueList -#include "TransformationMatrix.h" #include "cc/CCActiveAnimation.h" #include "cc/CCKeyframedAnimationCurve.h" +#include <public/WebTransformationMatrix.h> #include <wtf/CurrentTime.h> #include <wtf/HashMap.h> +using WebKit::WebTransformationMatrix; + namespace WebCore { namespace { @@ -478,7 +480,7 @@ void CCLayerAnimationController::tickAnimations(double monotonicTime) case CCActiveAnimation::Transform: { const CCTransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->curve()->toTransformAnimationCurve(); - const TransformationMatrix matrix = transformAnimationCurve->getValue(trimmed, m_client->bounds()); + const WebTransformationMatrix matrix = transformAnimationCurve->getValue(trimmed, m_client->bounds()); if (m_activeAnimations[i]->isFinishedAt(monotonicTime)) m_activeAnimations[i]->setRunState(CCActiveAnimation::Finished, monotonicTime); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h index ac7287f71..c4c9158b2 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h @@ -34,12 +34,16 @@ #include <wtf/OwnPtr.h> #include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> + +namespace WebKit { +class WebTransformationMatrix; +} + namespace WebCore { class Animation; class IntSize; class KeyframeValueList; -class TransformationMatrix; class CCLayerAnimationControllerClient { public: @@ -48,8 +52,8 @@ public: virtual int id() const = 0; virtual void setOpacityFromAnimation(float) = 0; virtual float opacity() const = 0; - virtual void setTransformFromAnimation(const TransformationMatrix&) = 0; - virtual const TransformationMatrix& transform() const = 0; + virtual void setTransformFromAnimation(const WebKit::WebTransformationMatrix&) = 0; + virtual const WebKit::WebTransformationMatrix& transform() const = 0; virtual const IntSize& bounds() const = 0; }; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp index 6d80684f6..1f08b9b99 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp @@ -38,6 +38,8 @@ #include "cc/CCSolidColorDrawQuad.h" #include <wtf/text/WTFString.h> +using WebKit::WebTransformationMatrix; + namespace WebCore { CCLayerImpl::CCLayerImpl(int id) @@ -169,9 +171,10 @@ void CCLayerImpl::appendDebugBorderQuad(CCQuadCuller& quadList, const CCSharedQu quadList.append(CCDebugBorderDrawQuad::create(sharedQuadState, layerRect, debugBorderColor(), debugBorderWidth())); } -void CCLayerImpl::bindContentsTexture(LayerRendererChromium*) +unsigned CCLayerImpl::contentsTextureId() const { ASSERT_NOT_REACHED(); + return 0; } void CCLayerImpl::scrollBy(const FloatSize& scroll) @@ -193,9 +196,9 @@ const IntRect CCLayerImpl::getDrawRect() const return mappedRect; } -TransformationMatrix CCLayerImpl::quadTransform() const +WebTransformationMatrix CCLayerImpl::quadTransform() const { - TransformationMatrix quadTransformation = drawTransform(); + WebTransformationMatrix quadTransformation = drawTransform(); float offsetX = -0.5 * bounds().width(); float offsetY = -0.5 * bounds().height(); @@ -308,7 +311,7 @@ void CCLayerImpl::setOpacityFromAnimation(float opacity) setOpacity(opacity); } -void CCLayerImpl::setTransformFromAnimation(const TransformationMatrix& transform) +void CCLayerImpl::setTransformFromAnimation(const WebTransformationMatrix& transform) { setTransform(transform); } @@ -454,7 +457,7 @@ void CCLayerImpl::setPreserves3D(bool preserves3D) noteLayerPropertyChangedForSubtree(); } -void CCLayerImpl::setSublayerTransform(const TransformationMatrix& sublayerTransform) +void CCLayerImpl::setSublayerTransform(const WebTransformationMatrix& sublayerTransform) { if (m_sublayerTransform == sublayerTransform) return; @@ -464,7 +467,7 @@ void CCLayerImpl::setSublayerTransform(const TransformationMatrix& sublayerTrans noteLayerPropertyChangedForDescendants(); } -void CCLayerImpl::setTransform(const TransformationMatrix& transform) +void CCLayerImpl::setTransform(const WebTransformationMatrix& transform) { if (m_transform == transform) return; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h index bb75a89eb..2c41d06ea 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h @@ -31,11 +31,11 @@ #include "IntRect.h" #include "Region.h" #include "TextStream.h" -#include "TransformationMatrix.h" #include "cc/CCLayerAnimationController.h" #include "cc/CCRenderSurface.h" #include "cc/CCSharedQuadState.h" #include <public/WebFilterOperations.h> +#include <public/WebTransformationMatrix.h> #include <wtf/OwnPtr.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> @@ -61,8 +61,8 @@ public: virtual int id() const OVERRIDE { return m_layerId; } virtual void setOpacityFromAnimation(float) OVERRIDE; virtual float opacity() const OVERRIDE { return m_opacity; } - virtual void setTransformFromAnimation(const TransformationMatrix&) OVERRIDE; - virtual const TransformationMatrix& transform() const OVERRIDE { return m_transform; } + virtual void setTransformFromAnimation(const WebKit::WebTransformationMatrix&) OVERRIDE; + virtual const WebKit::WebTransformationMatrix& transform() const OVERRIDE { return m_transform; } virtual const IntSize& bounds() const OVERRIDE { return m_bounds; } // Tree structure. @@ -88,7 +88,7 @@ public: virtual void didDraw(); void appendDebugBorderQuad(CCQuadCuller&, const CCSharedQuadState*) const; - virtual void bindContentsTexture(LayerRendererChromium*); + virtual unsigned contentsTextureId() const; // Returns true if this layer has content to draw. void setDrawsContent(bool); @@ -136,8 +136,8 @@ public: void setIsNonCompositedContent(bool isNonCompositedContent) { m_isNonCompositedContent = isNonCompositedContent; } bool isNonCompositedContent() const { return m_isNonCompositedContent; } - void setSublayerTransform(const TransformationMatrix&); - const TransformationMatrix& sublayerTransform() const { return m_sublayerTransform; } + void setSublayerTransform(const WebKit::WebTransformationMatrix&); + const WebKit::WebTransformationMatrix& sublayerTransform() const { return m_sublayerTransform; } // Debug layer border - visual effect only, do not change geometry/clipping/etc. void setDebugBorderColor(Color); @@ -212,13 +212,13 @@ public: // Returns the rect containtaining this layer in the current view's coordinate system. const IntRect getDrawRect() const; - void setTransform(const TransformationMatrix&); + void setTransform(const WebKit::WebTransformationMatrix&); bool transformIsAnimating() const; - const TransformationMatrix& drawTransform() const { return m_drawTransform; } - void setDrawTransform(const TransformationMatrix& matrix) { m_drawTransform = matrix; } - const TransformationMatrix& screenSpaceTransform() const { return m_screenSpaceTransform; } - void setScreenSpaceTransform(const TransformationMatrix& matrix) { m_screenSpaceTransform = matrix; } + const WebKit::WebTransformationMatrix& drawTransform() const { return m_drawTransform; } + void setDrawTransform(const WebKit::WebTransformationMatrix& matrix) { m_drawTransform = matrix; } + const WebKit::WebTransformationMatrix& screenSpaceTransform() const { return m_screenSpaceTransform; } + void setScreenSpaceTransform(const WebKit::WebTransformationMatrix& matrix) { m_screenSpaceTransform = matrix; } bool drawTransformIsAnimating() const { return m_drawTransformIsAnimating; } void setDrawTransformIsAnimating(bool animating) { m_drawTransformIsAnimating = animating; } @@ -253,7 +253,7 @@ protected: static void writeIndent(TextStream&, int indent); // Transformation used to transform quads provided in appendQuads. - virtual TransformationMatrix quadTransform() const; + virtual WebKit::WebTransformationMatrix quadTransform() const; private: void setParent(CCLayerImpl* parent) { m_parent = parent; } @@ -304,8 +304,8 @@ private: FloatPoint m_position; bool m_preserves3D; bool m_drawCheckerboardForMissingTiles; - TransformationMatrix m_sublayerTransform; - TransformationMatrix m_transform; + WebKit::WebTransformationMatrix m_sublayerTransform; + WebKit::WebTransformationMatrix m_transform; bool m_usesLayerClipping; bool m_isNonCompositedContent; @@ -339,8 +339,8 @@ private: WebKit::WebFilterOperations m_filters; WebKit::WebFilterOperations m_backgroundFilters; - TransformationMatrix m_drawTransform; - TransformationMatrix m_screenSpaceTransform; + WebKit::WebTransformationMatrix m_drawTransform; + WebKit::WebTransformationMatrix m_screenSpaceTransform; bool m_drawTransformIsAnimating; bool m_screenSpaceTransformIsAnimating; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.cpp index 1af639c8b..fdf3c7bb2 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.cpp @@ -26,13 +26,14 @@ #include "cc/CCLayerSorter.h" -#include "TransformationMatrix.h" #include "cc/CCMathUtil.h" #include "cc/CCRenderSurface.h" #include <limits.h> +#include <public/WebTransformationMatrix.h> #include <wtf/Deque.h> using namespace std; +using WebKit::WebTransformationMatrix; #define LOG_CHANNEL_PREFIX Log #define SHOW_DEBUG_LOG 0 @@ -151,7 +152,7 @@ CCLayerSorter::ABCompareResult CCLayerSorter::checkOverlap(LayerShape* a, LayerS return BBeforeA; } -CCLayerSorter::LayerShape::LayerShape(float width, float height, const TransformationMatrix& drawTransform) +CCLayerSorter::LayerShape::LayerShape(float width, float height, const WebTransformationMatrix& drawTransform) { FloatQuad layerQuad(FloatPoint(-width * 0.5, height * 0.5), FloatPoint(width * 0.5, height * 0.5), @@ -236,7 +237,7 @@ void CCLayerSorter::createGraphNodes(LayerList::iterator first, LayerList::itera LOG(CCLayerSorter, "Layer %d (%d x %d)\n", node.layer->id(), node.layer->bounds().width(), node.layer->bounds().height()); #endif - TransformationMatrix drawTransform; + WebTransformationMatrix drawTransform; float layerWidth, layerHeight; if (renderSurface) { drawTransform = renderSurface->drawTransform(); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.h index 3e2a88c92..cb88e85db 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerSorter.h @@ -33,6 +33,10 @@ #include <wtf/Noncopyable.h> #include <wtf/Vector.h> +namespace WebKit { +class WebTransformationMatrix; +} + namespace WebCore { class CCLayerSorter { @@ -47,7 +51,7 @@ public: // Holds various useful properties derived from a layer's 3D outline. struct LayerShape { LayerShape() { } - LayerShape(float width, float height, const TransformationMatrix& drawTransform); + LayerShape(float width, float height, const WebKit::WebTransformationMatrix& drawTransform); float layerZFromProjectedPoint(const FloatPoint&) const; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp index 96397ca45..cb610dfd9 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp @@ -43,6 +43,7 @@ #include "cc/CCThreadProxy.h" using namespace std; +using WebKit::WebTransformationMatrix; namespace { static int numLayerTreeInstances; @@ -511,8 +512,8 @@ void CCLayerTreeHost::updateLayers(LayerChromium* rootLayer, CCTextureUpdater& u { TRACE_EVENT("CCLayerTreeHost::updateLayers::calcDrawEtc", this, 0); - TransformationMatrix identityMatrix; - TransformationMatrix deviceScaleTransform; + WebTransformationMatrix identityMatrix; + WebTransformationMatrix deviceScaleTransform; deviceScaleTransform.scale(m_settings.deviceScaleFactor); CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(rootLayer, rootLayer, deviceScaleTransform, identityMatrix, updateList, rootRenderSurface->layerList(), layerRendererCapabilities().maxTextureSize); } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h index 714602356..dc8fb1c93 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h @@ -30,7 +30,6 @@ #include "IntRect.h" #include "LayerChromium.h" #include "RateLimiter.h" -#include "TransformationMatrix.h" #include "cc/CCAnimationEvents.h" #include "cc/CCLayerTreeHostCommon.h" #include "cc/CCProxy.h" @@ -77,7 +76,6 @@ protected: struct CCSettings { CCSettings() : acceleratePainting(false) - , debugShowTileInfo(false) , showFPSCounter(false) , showPlatformLayerTree(false) , showPaintRects(false) @@ -94,7 +92,6 @@ struct CCSettings { { } bool acceleratePainting; - bool debugShowTileInfo; bool showFPSCounter; bool showPlatformLayerTree; bool showPaintRects; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp index 2a0f71803..b5bcabbf0 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp @@ -31,7 +31,6 @@ #include "IntRect.h" #include "LayerChromium.h" #include "RenderSurfaceChromium.h" -#include "TransformationMatrix.h" #include "cc/CCActiveAnimation.h" #include "cc/CCLayerAnimationController.h" #include "cc/CCLayerImpl.h" @@ -39,10 +38,13 @@ #include "cc/CCLayerSorter.h" #include "cc/CCMathUtil.h" #include "cc/CCRenderSurface.h" +#include <public/WebTransformationMatrix.h> + +using WebKit::WebTransformationMatrix; namespace WebCore { -IntRect CCLayerTreeHostCommon::calculateVisibleRect(const IntRect& targetSurfaceRect, const IntRect& layerBoundRect, const TransformationMatrix& transform) +IntRect CCLayerTreeHostCommon::calculateVisibleRect(const IntRect& targetSurfaceRect, const IntRect& layerBoundRect, const WebTransformationMatrix& transform) { // Is this layer fully contained within the target surface? IntRect layerInSurfaceSpace = CCMathUtil::mapClippedRect(transform, layerBoundRect); @@ -59,7 +61,7 @@ IntRect CCLayerTreeHostCommon::calculateVisibleRect(const IntRect& targetSurface // This bounding rectangle may be larger than it needs to be (being // axis-aligned), but is a reasonable filter on the space to consider. // Non-invertible transforms will create an empty rect here. - const TransformationMatrix surfaceToLayer = transform.inverse(); + const WebTransformationMatrix surfaceToLayer = transform.inverse(); IntRect layerRect = enclosingIntRect(CCMathUtil::projectClippedRect(surfaceToLayer, FloatRect(minimalSurfaceRect))); layerRect.intersect(layerBoundRect); return layerRect; @@ -102,7 +104,7 @@ static bool isLayerBackFaceVisible(LayerType* layer) } template<typename LayerType> -static bool isSurfaceBackFaceVisible(LayerType* layer, const TransformationMatrix& drawTransform) +static bool isSurfaceBackFaceVisible(LayerType* layer, const WebTransformationMatrix& drawTransform) { if (layerIsInExisting3DRenderingContext(layer)) return drawTransform.isBackFaceVisible(); @@ -133,7 +135,7 @@ static IntRect calculateVisibleLayerRect(LayerType* layer) const IntSize& contentBounds = layer->contentBounds(); const IntRect layerBoundRect = IntRect(IntPoint(), contentBounds); - TransformationMatrix transform = layer->drawTransform(); + WebTransformationMatrix transform = layer->drawTransform(); transform.scaleNonUniform(bounds.width() / static_cast<double>(contentBounds.width()), bounds.height() / static_cast<double>(contentBounds.height())); @@ -143,7 +145,7 @@ static IntRect calculateVisibleLayerRect(LayerType* layer) return visibleLayerRect; } -static bool isScaleOrTranslation(const TransformationMatrix& m) +static bool isScaleOrTranslation(const WebTransformationMatrix& m) { return !m.m12() && !m.m13() && !m.m14() && !m.m21() && !m.m23() && !m.m24() @@ -282,7 +284,7 @@ static bool subtreeShouldRenderToSeparateSurface(LayerType* layer, bool axisAlig // Recursively walks the layer tree starting at the given node and computes all the // necessary transformations, clipRects, render surfaces, etc. template<typename LayerType, typename LayerList, typename RenderSurfaceType, typename LayerSorter> -static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, LayerType* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, RenderSurfaceType* nearestAncestorThatMovesPixels, LayerList& renderSurfaceLayerList, LayerList& layerList, LayerSorter* layerSorter, int maxTextureSize) +static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, LayerType* rootLayer, const WebTransformationMatrix& parentMatrix, const WebTransformationMatrix& fullHierarchyMatrix, RenderSurfaceType* nearestAncestorThatMovesPixels, LayerList& renderSurfaceLayerList, LayerList& layerList, LayerSorter* layerSorter, int maxTextureSize) { // This function computes the new matrix transformations recursively for this // layer and all its descendants. It also computes the appropriate render surfaces. @@ -296,7 +298,7 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer // projection applied at draw time flips the Y axis appropriately. // // 2. The anchor point, when given as a FloatPoint object, is specified in "unit layer space", - // where the bounds of the layer map to [0, 1]. However, as a TransformationMatrix object, + // where the bounds of the layer map to [0, 1]. However, as a WebTransformationMatrix object, // the transform to the anchor point is specified in "pixel layer space", where the bounds // of the layer map to [bounds.width(), bounds.height()]. // @@ -399,7 +401,7 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer float centerOffsetX = (0.5 - anchorPoint.x()) * bounds.width(); float centerOffsetY = (0.5 - anchorPoint.y()) * bounds.height(); - TransformationMatrix layerLocalTransform; + WebTransformationMatrix layerLocalTransform; // LT = Tr[origin] * S[pageScaleDelta] layerLocalTransform.scale(layer->pageScaleDelta()); // LT = Tr[origin] * S[pageScaleDelta] * Tr[origin2anchor] @@ -409,8 +411,8 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer // LT = Tr[origin] * S[pageScaleDelta] * Tr[origin2anchor] * M[layer] * Tr[anchor2center] layerLocalTransform.translate3d(centerOffsetX, centerOffsetY, -layer->anchorPointZ()); - TransformationMatrix combinedTransform = parentMatrix; - combinedTransform = combinedTransform.multiply(layerLocalTransform); + WebTransformationMatrix combinedTransform = parentMatrix; + combinedTransform.multiply(layerLocalTransform); bool animatingTransformToTarget = layer->transformIsAnimating(); bool animatingTransformToScreen = animatingTransformToTarget; @@ -424,7 +426,7 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer // fullHierarchyMatrix is the matrix that transforms objects between screen space (except projection matrix) and the most recent RenderSurface's space. // nextHierarchyMatrix will only change if this layer uses a new RenderSurface, otherwise remains the same. - TransformationMatrix nextHierarchyMatrix = fullHierarchyMatrix; + WebTransformationMatrix nextHierarchyMatrix = fullHierarchyMatrix; // FIXME: This seems like the wrong place to set this layer->setUsesLayerClipping(false); @@ -441,7 +443,7 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer renderSurface->clearLayerList(); // The origin of the new surface is the upper left corner of the layer. - TransformationMatrix drawTransform; + WebTransformationMatrix drawTransform; drawTransform.translate3d(0.5 * bounds.width(), 0.5 * bounds.height(), 0); layer->setDrawTransform(drawTransform); @@ -453,7 +455,7 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer layer->setDrawOpacity(1); layer->setDrawOpacityIsAnimating(false); - TransformationMatrix surfaceOriginTransform = combinedTransform; + WebTransformationMatrix surfaceOriginTransform = combinedTransform; surfaceOriginTransform.translate3d(-0.5 * bounds.width(), -0.5 * bounds.height(), 0); renderSurface->setOriginTransform(surfaceOriginTransform); @@ -475,11 +477,8 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer layer->setUsesLayerClipping(false); layer->setClipRect(IntRect()); - if (layer->maskLayer()) { - renderSurface->setMaskLayer(layer->maskLayer()); + if (layer->maskLayer()) layer->maskLayer()->setTargetRenderSurface(renderSurface); - } else - renderSurface->setMaskLayer(0); if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) layer->replicaLayer()->maskLayer()->setTargetRenderSurface(renderSurface); @@ -529,7 +528,7 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer // Note that at this point, layer->drawTransform() is not necessarily the same as local variable drawTransform. // layerScreenSpaceTransform represents the transform between root layer's "screen space" and local layer space. - TransformationMatrix layerScreenSpaceTransform = nextHierarchyMatrix; + WebTransformationMatrix layerScreenSpaceTransform = nextHierarchyMatrix; layerScreenSpaceTransform.multiply(layer->drawTransform()); layerScreenSpaceTransform.translate3d(-0.5 * bounds.width(), -0.5 * bounds.height(), 0); layer->setScreenSpaceTransform(layerScreenSpaceTransform); @@ -544,7 +543,7 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer } else layer->setDrawableContentRect(IntRect()); - TransformationMatrix sublayerMatrix = layer->drawTransform(); + WebTransformationMatrix sublayerMatrix = layer->drawTransform(); // Flatten to 2D if the layer doesn't preserve 3D. if (!layer->preserves3D()) { @@ -632,7 +631,7 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer layer->setClipRect(layer->drawableContentRect()); // Adjust the origin of the transform to be the center of the render surface. - TransformationMatrix drawTransform = renderSurface->originTransform(); + WebTransformationMatrix drawTransform = renderSurface->originTransform(); drawTransform.translate3d(surfaceCenter.x() + centerOffsetDueToClipping.width(), surfaceCenter.y() + centerOffsetDueToClipping.height(), 0); renderSurface->setDrawTransform(drawTransform); @@ -641,23 +640,23 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer if (layer->replicaLayer()) { // Compute the transformation matrix used to draw the surface's replica to the target surface. - TransformationMatrix replicaDrawTransform = renderSurface->originTransform(); + WebTransformationMatrix replicaDrawTransform = renderSurface->originTransform(); replicaDrawTransform.translate(layer->replicaLayer()->position().x(), layer->replicaLayer()->position().y()); replicaDrawTransform.multiply(layer->replicaLayer()->transform()); replicaDrawTransform.translate(surfaceCenter.x() - anchorPoint.x() * bounds.width(), surfaceCenter.y() - anchorPoint.y() * bounds.height()); renderSurface->setReplicaDrawTransform(replicaDrawTransform); - TransformationMatrix surfaceOriginToReplicaOriginTransform; + WebTransformationMatrix surfaceOriginToReplicaOriginTransform; surfaceOriginToReplicaOriginTransform.translate(layer->replicaLayer()->position().x(), layer->replicaLayer()->position().y()); surfaceOriginToReplicaOriginTransform.multiply(layer->replicaLayer()->transform()); surfaceOriginToReplicaOriginTransform.translate(-anchorPoint.x() * bounds.width(), -anchorPoint.y() * bounds.height()); // Compute the replica's "originTransform" that maps from the replica's origin space to the target surface origin space. - TransformationMatrix replicaOriginTransform = layer->renderSurface()->originTransform() * surfaceOriginToReplicaOriginTransform; + WebTransformationMatrix replicaOriginTransform = layer->renderSurface()->originTransform() * surfaceOriginToReplicaOriginTransform; renderSurface->setReplicaOriginTransform(replicaOriginTransform); // Compute the replica's "screenSpaceTransform" that maps from the replica's origin space to the screen's origin space. - TransformationMatrix replicaScreenSpaceTransform = layer->renderSurface()->screenSpaceTransform() * surfaceOriginToReplicaOriginTransform; + WebTransformationMatrix replicaScreenSpaceTransform = layer->renderSurface()->screenSpaceTransform() * surfaceOriginToReplicaOriginTransform; renderSurface->setReplicaScreenSpaceTransform(replicaScreenSpaceTransform); } @@ -710,13 +709,13 @@ static void walkLayersAndCalculateVisibleLayerRects(const LayerList& renderSurfa } } -void CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(LayerChromium* layer, LayerChromium* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<LayerChromium> >& renderSurfaceLayerList, Vector<RefPtr<LayerChromium> >& layerList, int maxTextureSize) +void CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(LayerChromium* layer, LayerChromium* rootLayer, const WebTransformationMatrix& parentMatrix, const WebTransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<LayerChromium> >& renderSurfaceLayerList, Vector<RefPtr<LayerChromium> >& layerList, int maxTextureSize) { WebCore::calculateDrawTransformsAndVisibilityInternal<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, void>(layer, rootLayer, parentMatrix, fullHierarchyMatrix, 0, renderSurfaceLayerList, layerList, 0, maxTextureSize); walkLayersAndCalculateVisibleLayerRects<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium>(renderSurfaceLayerList); } -void CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(CCLayerImpl* layer, CCLayerImpl* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList, CCLayerSorter* layerSorter, int maxTextureSize) +void CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(CCLayerImpl* layer, CCLayerImpl* rootLayer, const WebTransformationMatrix& parentMatrix, const WebTransformationMatrix& fullHierarchyMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList, CCLayerSorter* layerSorter, int maxTextureSize) { calculateDrawTransformsAndVisibilityInternal<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, CCLayerSorter>(layer, rootLayer, parentMatrix, fullHierarchyMatrix, 0, renderSurfaceLayerList, layerList, layerSorter, maxTextureSize); walkLayersAndCalculateVisibleLayerRects<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface>(renderSurfaceLayerList); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h index 3762f64b1..0585aff4f 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h @@ -27,7 +27,7 @@ #include "IntRect.h" #include "IntSize.h" -#include "TransformationMatrix.h" +#include <public/WebTransformationMatrix.h> #include <wtf/RefPtr.h> #include <wtf/Vector.h> @@ -39,10 +39,10 @@ class LayerChromium; class CCLayerTreeHostCommon { public: - static IntRect calculateVisibleRect(const IntRect& targetSurfaceRect, const IntRect& layerBoundRect, const TransformationMatrix&); + static IntRect calculateVisibleRect(const IntRect& targetSurfaceRect, const IntRect& layerBoundRect, const WebKit::WebTransformationMatrix&); - static void calculateDrawTransformsAndVisibility(LayerChromium*, LayerChromium* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<LayerChromium> >& renderSurfaceLayerList, Vector<RefPtr<LayerChromium> >& layerList, int maxTextureSize); - static void calculateDrawTransformsAndVisibility(CCLayerImpl*, CCLayerImpl* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList, CCLayerSorter*, int maxTextureSize); + static void calculateDrawTransformsAndVisibility(LayerChromium*, LayerChromium* rootLayer, const WebKit::WebTransformationMatrix& parentMatrix, const WebKit::WebTransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<LayerChromium> >& renderSurfaceLayerList, Vector<RefPtr<LayerChromium> >& layerList, int maxTextureSize); + static void calculateDrawTransformsAndVisibility(CCLayerImpl*, CCLayerImpl* rootLayer, const WebKit::WebTransformationMatrix& parentMatrix, const WebKit::WebTransformationMatrix& fullHierarchyMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList, CCLayerSorter*, int maxTextureSize); template<typename LayerType> static bool renderSurfaceContributesToTarget(LayerType*, int targetSurfaceLayerID); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp index 91336a776..0a49f8e7d 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp @@ -47,6 +47,8 @@ #include "cc/CCThreadTask.h" #include <wtf/CurrentTime.h> +using WebKit::WebTransformationMatrix; + namespace { void didVisibilityChange(WebCore::CCLayerTreeHostImpl* id, bool visible) @@ -234,7 +236,7 @@ static FloatRect damageInSurfaceSpace(CCLayerImpl* renderSurfaceLayer, const Flo FloatRect surfaceDamageRect; // For now, we conservatively use the root damage as the damage for // all surfaces, except perspective transforms. - const TransformationMatrix& screenSpaceTransform = renderSurfaceLayer->renderSurface()->screenSpaceTransform(); + const WebTransformationMatrix& screenSpaceTransform = renderSurfaceLayer->renderSurface()->screenSpaceTransform(); if (screenSpaceTransform.hasPerspective()) { // Perspective projections do not play nice with mapRect of // inverse transforms. In this uncommon case, its simpler to @@ -243,7 +245,7 @@ static FloatRect damageInSurfaceSpace(CCLayerImpl* renderSurfaceLayer, const Flo CCRenderSurface* renderSurface = renderSurfaceLayer->renderSurface(); surfaceDamageRect = renderSurface->contentRect(); } else { - TransformationMatrix inverseScreenSpaceTransform = screenSpaceTransform.inverse(); + WebTransformationMatrix inverseScreenSpaceTransform = screenSpaceTransform.inverse(); surfaceDamageRect = inverseScreenSpaceTransform.mapRect(rootDamageRect); } return surfaceDamageRect; @@ -264,8 +266,8 @@ void CCLayerTreeHostImpl::calculateRenderSurfaceLayerList(CCLayerList& renderSur { TRACE_EVENT("CCLayerTreeHostImpl::calcDrawEtc", this, 0); - TransformationMatrix identityMatrix; - TransformationMatrix deviceScaleTransform; + WebTransformationMatrix identityMatrix; + WebTransformationMatrix deviceScaleTransform; deviceScaleTransform.scale(m_settings.deviceScaleFactor); CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(m_rootLayerImpl.get(), m_rootLayerImpl.get(), deviceScaleTransform, identityMatrix, renderSurfaceLayerList, m_rootLayerImpl->renderSurface()->layerList(), &m_layerSorter, layerRendererCapabilities().maxTextureSize); } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h index f8b763140..7f0c7ff66 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h @@ -50,7 +50,6 @@ class CCLayerTreeHostImplTimeSourceAdapter; class LayerRendererChromium; class TextureAllocator; struct LayerRendererCapabilities; -class TransformationMatrix; // CCLayerTreeHost->CCProxy callback interface. class CCLayerTreeHostImplClient { diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.cpp index 42933688b..867469dde 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.cpp @@ -29,42 +29,13 @@ #include "FloatPoint.h" #include "FloatQuad.h" #include "IntRect.h" -#include "TransformationMatrix.h" +#include <public/WebTransformationMatrix.h> -namespace WebCore { - -struct HomogeneousCoordinate { - HomogeneousCoordinate(double newX, double newY, double newZ, double newW) - : x(newX) - , y(newY) - , z(newZ) - , w(newW) - { - } +using WebKit::WebTransformationMatrix; - bool shouldBeClipped() const - { - return w <= 0; - } - - FloatPoint cartesianPoint2d() const - { - if (w == 1) - return FloatPoint(x, y); - - // For now, because this code is used privately only by CCMathUtil, it should never be called when w == 0, and we do not yet need to handle that case. - ASSERT(w); - double invW = 1.0 / w; - return FloatPoint(x * invW, y * invW); - } - - double x; - double y; - double z; - double w; -}; +namespace WebCore { -static HomogeneousCoordinate projectPoint(const TransformationMatrix& transform, const FloatPoint& p) +static HomogeneousCoordinate projectPoint(const WebTransformationMatrix& transform, const FloatPoint& p) { // In this case, the layer we are trying to project onto is perpendicular to ray // (point p and z-axis direction) that we are trying to project. This happens when the @@ -86,7 +57,7 @@ static HomogeneousCoordinate projectPoint(const TransformationMatrix& transform, return HomogeneousCoordinate(outX, outY, outZ, outW); } -static HomogeneousCoordinate mapPoint(const TransformationMatrix& transform, const FloatPoint& p) +static HomogeneousCoordinate mapPoint(const WebTransformationMatrix& transform, const FloatPoint& p) { double x = p.x(); double y = p.y(); @@ -138,67 +109,18 @@ static inline void expandBoundsToIncludePoint(float& xmin, float& xmax, float& y ymax = std::max(p.y(), ymax); } -static FloatRect computeEnclosingRect(const HomogeneousCoordinate& h1, const HomogeneousCoordinate& h2, const HomogeneousCoordinate& h3, const HomogeneousCoordinate& h4) -{ - // This function performs clipping as necessary and computes the enclosing 2d - // FloatRect of the vertices. Doing these two steps simultaneously allows us to avoid - // the overhead of storing an unknown number of clipped vertices. - - // If no vertices on the quad are clipped, then we can simply return the enclosing rect directly. - bool somethingClipped = h1.shouldBeClipped() || h2.shouldBeClipped() || h3.shouldBeClipped() || h4.shouldBeClipped(); - if (!somethingClipped) { - FloatQuad mappedQuad = FloatQuad(h1.cartesianPoint2d(), h2.cartesianPoint2d(), h3.cartesianPoint2d(), h4.cartesianPoint2d()); - return mappedQuad.boundingBox(); - } - - bool everythingClipped = h1.shouldBeClipped() && h2.shouldBeClipped() && h3.shouldBeClipped() && h4.shouldBeClipped(); - if (everythingClipped) - return FloatRect(); - - float xmin = std::numeric_limits<float>::max(); - float xmax = std::numeric_limits<float>::min(); - float ymin = std::numeric_limits<float>::max(); - float ymax = std::numeric_limits<float>::min(); - - if (!h1.shouldBeClipped()) - expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, h1.cartesianPoint2d()); - - if (h1.shouldBeClipped() ^ h2.shouldBeClipped()) - expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, computeClippedPointForEdge(h1, h2).cartesianPoint2d()); - - if (!h2.shouldBeClipped()) - expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, h2.cartesianPoint2d()); - - if (h2.shouldBeClipped() ^ h3.shouldBeClipped()) - expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, computeClippedPointForEdge(h2, h3).cartesianPoint2d()); - - if (!h3.shouldBeClipped()) - expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, h3.cartesianPoint2d()); - - if (h3.shouldBeClipped() ^ h4.shouldBeClipped()) - expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, computeClippedPointForEdge(h3, h4).cartesianPoint2d()); - - if (!h4.shouldBeClipped()) - expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, h4.cartesianPoint2d()); - - if (h4.shouldBeClipped() ^ h1.shouldBeClipped()) - expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, computeClippedPointForEdge(h4, h1).cartesianPoint2d()); - - return FloatRect(FloatPoint(xmin, ymin), FloatSize(xmax - xmin, ymax - ymin)); -} - static inline void addVertexToClippedQuad(const FloatPoint& newVertex, FloatPoint clippedQuad[8], int& numVerticesInClippedQuad) { clippedQuad[numVerticesInClippedQuad] = newVertex; numVerticesInClippedQuad++; } -IntRect CCMathUtil::mapClippedRect(const TransformationMatrix& transform, const IntRect& srcRect) +IntRect CCMathUtil::mapClippedRect(const WebTransformationMatrix& transform, const IntRect& srcRect) { return enclosingIntRect(mapClippedRect(transform, FloatRect(srcRect))); } -FloatRect CCMathUtil::mapClippedRect(const TransformationMatrix& transform, const FloatRect& srcRect) +FloatRect CCMathUtil::mapClippedRect(const WebTransformationMatrix& transform, const FloatRect& srcRect) { if (transform.isIdentityOrTranslation()) { FloatRect mappedRect(srcRect); @@ -213,10 +135,10 @@ FloatRect CCMathUtil::mapClippedRect(const TransformationMatrix& transform, cons HomogeneousCoordinate h3 = mapPoint(transform, q.p3()); HomogeneousCoordinate h4 = mapPoint(transform, q.p4()); - return computeEnclosingRect(h1, h2, h3, h4); + return computeEnclosingClippedRect(h1, h2, h3, h4); } -FloatRect CCMathUtil::projectClippedRect(const TransformationMatrix& transform, const FloatRect& srcRect) +FloatRect CCMathUtil::projectClippedRect(const WebTransformationMatrix& transform, const FloatRect& srcRect) { // Perform the projection, but retain the result in homogeneous coordinates. FloatQuad q = FloatQuad(FloatRect(srcRect)); @@ -225,10 +147,10 @@ FloatRect CCMathUtil::projectClippedRect(const TransformationMatrix& transform, HomogeneousCoordinate h3 = projectPoint(transform, q.p3()); HomogeneousCoordinate h4 = projectPoint(transform, q.p4()); - return computeEnclosingRect(h1, h2, h3, h4); + return computeEnclosingClippedRect(h1, h2, h3, h4); } -void CCMathUtil::mapClippedQuad(const TransformationMatrix& transform, const FloatQuad& srcQuad, FloatPoint clippedQuad[8], int& numVerticesInClippedQuad) +void CCMathUtil::mapClippedQuad(const WebTransformationMatrix& transform, const FloatQuad& srcQuad, FloatPoint clippedQuad[8], int& numVerticesInClippedQuad) { HomogeneousCoordinate h1 = mapPoint(transform, srcQuad.p1()); HomogeneousCoordinate h2 = mapPoint(transform, srcQuad.p2()); @@ -272,9 +194,9 @@ FloatRect CCMathUtil::computeEnclosingRectOfVertices(FloatPoint vertices[], int return FloatRect(); float xmin = std::numeric_limits<float>::max(); - float xmax = std::numeric_limits<float>::min(); + float xmax = -std::numeric_limits<float>::max(); float ymin = std::numeric_limits<float>::max(); - float ymax = std::numeric_limits<float>::min(); + float ymax = -std::numeric_limits<float>::max(); for (int i = 0; i < numVertices; ++i) expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, vertices[i]); @@ -282,7 +204,57 @@ FloatRect CCMathUtil::computeEnclosingRectOfVertices(FloatPoint vertices[], int return FloatRect(FloatPoint(xmin, ymin), FloatSize(xmax - xmin, ymax - ymin)); } -FloatQuad CCMathUtil::mapQuad(const TransformationMatrix& transform, const FloatQuad& q, bool& clipped) +FloatRect CCMathUtil::computeEnclosingClippedRect(const HomogeneousCoordinate& h1, const HomogeneousCoordinate& h2, const HomogeneousCoordinate& h3, const HomogeneousCoordinate& h4) +{ + // This function performs clipping as necessary and computes the enclosing 2d + // FloatRect of the vertices. Doing these two steps simultaneously allows us to avoid + // the overhead of storing an unknown number of clipped vertices. + + // If no vertices on the quad are clipped, then we can simply return the enclosing rect directly. + bool somethingClipped = h1.shouldBeClipped() || h2.shouldBeClipped() || h3.shouldBeClipped() || h4.shouldBeClipped(); + if (!somethingClipped) { + FloatQuad mappedQuad = FloatQuad(h1.cartesianPoint2d(), h2.cartesianPoint2d(), h3.cartesianPoint2d(), h4.cartesianPoint2d()); + return mappedQuad.boundingBox(); + } + + bool everythingClipped = h1.shouldBeClipped() && h2.shouldBeClipped() && h3.shouldBeClipped() && h4.shouldBeClipped(); + if (everythingClipped) + return FloatRect(); + + + float xmin = std::numeric_limits<float>::max(); + float xmax = -std::numeric_limits<float>::max(); + float ymin = std::numeric_limits<float>::max(); + float ymax = -std::numeric_limits<float>::max(); + + if (!h1.shouldBeClipped()) + expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, h1.cartesianPoint2d()); + + if (h1.shouldBeClipped() ^ h2.shouldBeClipped()) + expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, computeClippedPointForEdge(h1, h2).cartesianPoint2d()); + + if (!h2.shouldBeClipped()) + expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, h2.cartesianPoint2d()); + + if (h2.shouldBeClipped() ^ h3.shouldBeClipped()) + expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, computeClippedPointForEdge(h2, h3).cartesianPoint2d()); + + if (!h3.shouldBeClipped()) + expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, h3.cartesianPoint2d()); + + if (h3.shouldBeClipped() ^ h4.shouldBeClipped()) + expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, computeClippedPointForEdge(h3, h4).cartesianPoint2d()); + + if (!h4.shouldBeClipped()) + expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, h4.cartesianPoint2d()); + + if (h4.shouldBeClipped() ^ h1.shouldBeClipped()) + expandBoundsToIncludePoint(xmin, xmax, ymin, ymax, computeClippedPointForEdge(h4, h1).cartesianPoint2d()); + + return FloatRect(FloatPoint(xmin, ymin), FloatSize(xmax - xmin, ymax - ymin)); +} + +FloatQuad CCMathUtil::mapQuad(const WebTransformationMatrix& transform, const FloatQuad& q, bool& clipped) { if (transform.isIdentityOrTranslation()) { FloatQuad mappedQuad(q); @@ -302,7 +274,7 @@ FloatQuad CCMathUtil::mapQuad(const TransformationMatrix& transform, const Float return FloatQuad(h1.cartesianPoint2d(), h2.cartesianPoint2d(), h3.cartesianPoint2d(), h4.cartesianPoint2d()); } -FloatQuad CCMathUtil::projectQuad(const TransformationMatrix& transform, const FloatQuad& q, bool& clipped) +FloatQuad CCMathUtil::projectQuad(const WebTransformationMatrix& transform, const FloatQuad& q, bool& clipped) { FloatQuad projectedQuad; bool clippedPoint; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.h b/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.h index 398604d9a..63ca00312 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.h @@ -25,20 +25,56 @@ #ifndef CCMathUtil_h #define CCMathUtil_h +#include "FloatPoint.h" + +namespace WebKit { +class WebTransformationMatrix; +} + namespace WebCore { class IntRect; class FloatPoint; class FloatRect; class FloatQuad; -class TransformationMatrix; + +struct HomogeneousCoordinate { + HomogeneousCoordinate(double newX, double newY, double newZ, double newW) + : x(newX) + , y(newY) + , z(newZ) + , w(newW) + { + } + + bool shouldBeClipped() const + { + return w <= 0; + } + + FloatPoint cartesianPoint2d() const + { + if (w == 1) + return FloatPoint(x, y); + + // For now, because this code is used privately only by CCMathUtil, it should never be called when w == 0, and we do not yet need to handle that case. + ASSERT(w); + double invW = 1.0 / w; + return FloatPoint(x * invW, y * invW); + } + + double x; + double y; + double z; + double w; +}; // This class contains math helper functionality that does not belong in WebCore. // It is possible that this functionality should be migrated to WebCore eventually. class CCMathUtil { public: - // Background: TransformationMatrix code in WebCore does not do the right thing in + // Background: WebTransformationMatrix code in WebCore does not do the right thing in // mapRect / mapQuad / projectQuad when there is a perspective projection that causes // one of the transformed vertices to go to w < 0. In those cases, it is necessary to // perform clipping in homogeneous coordinates, after applying the transform, before @@ -46,21 +82,23 @@ public: // // These functions return the axis-aligned rect that encloses the correctly clipped, // transformed polygon. - static IntRect mapClippedRect(const TransformationMatrix&, const IntRect&); - static FloatRect mapClippedRect(const TransformationMatrix&, const FloatRect&); - static FloatRect projectClippedRect(const TransformationMatrix&, const FloatRect&); + static IntRect mapClippedRect(const WebKit::WebTransformationMatrix&, const IntRect&); + static FloatRect mapClippedRect(const WebKit::WebTransformationMatrix&, const FloatRect&); + static FloatRect projectClippedRect(const WebKit::WebTransformationMatrix&, const FloatRect&); // Returns an array of vertices that represent the clipped polygon. After returning, indexes from // 0 to numVerticesInClippedQuad are valid in the clippedQuad array. Note that // numVerticesInClippedQuad may be zero, which means the entire quad was clipped, and // none of the vertices in the array are valid. - static void mapClippedQuad(const TransformationMatrix&, const FloatQuad& srcQuad, FloatPoint clippedQuad[8], int& numVerticesInClippedQuad); + static void mapClippedQuad(const WebKit::WebTransformationMatrix&, const FloatQuad& srcQuad, FloatPoint clippedQuad[8], int& numVerticesInClippedQuad); + static FloatRect computeEnclosingRectOfVertices(FloatPoint vertices[], int numVertices); + static FloatRect computeEnclosingClippedRect(const HomogeneousCoordinate& h1, const HomogeneousCoordinate& h2, const HomogeneousCoordinate& h3, const HomogeneousCoordinate& h4); // NOTE: These functions do not do correct clipping against w = 0 plane, but they // correctly detect the clipped condition via the boolean clipped. - static FloatQuad mapQuad(const TransformationMatrix&, const FloatQuad&, bool& clipped); - static FloatQuad projectQuad(const TransformationMatrix&, const FloatQuad&, bool& clipped); + static FloatQuad mapQuad(const WebKit::WebTransformationMatrix&, const FloatQuad&, bool& clipped); + static FloatQuad projectQuad(const WebKit::WebTransformationMatrix&, const FloatQuad&, bool& clipped); }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp index 792f8629a..68ccdc9c0 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp @@ -36,6 +36,7 @@ #include <algorithm> using namespace std; +using WebKit::WebTransformationMatrix; namespace WebCore { @@ -131,7 +132,7 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::finishedTargetRenderS } template<typename RenderSurfaceType> -static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surface, const Region& region, const TransformationMatrix& transform) +static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surface, const Region& region, const WebTransformationMatrix& transform) { // Verify that rects within the |surface| will remain rects in its target surface after applying |transform|. If this is true, then // apply |transform| to each rect within |region| in order to transform the entire Region. @@ -194,7 +195,7 @@ static inline void reduceOcclusion(const IntRect& affectedArea, const IntRect& e } template<typename RenderSurfaceType> -static void reduceOcclusionBelowSurface(RenderSurfaceType* surface, const IntRect& surfaceRect, const TransformationMatrix& surfaceTransform, RenderSurfaceType* surfaceTarget, Region& occlusionInTarget, Region& occlusionInScreen) +static void reduceOcclusionBelowSurface(RenderSurfaceType* surface, const IntRect& surfaceRect, const WebTransformationMatrix& surfaceTransform, RenderSurfaceType* surfaceTarget, Region& occlusionInTarget, Region& occlusionInScreen) { if (surfaceRect.isEmpty()) return; @@ -260,13 +261,13 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToTargetRenderSu } template<typename LayerType> -static inline TransformationMatrix contentToScreenSpaceTransform(const LayerType* layer) +static inline WebTransformationMatrix contentToScreenSpaceTransform(const LayerType* layer) { ASSERT(layerTransformsToScreenKnown(layer)); IntSize boundsInLayerSpace = layer->bounds(); IntSize boundsInContentSpace = layer->contentBounds(); - TransformationMatrix transform = layer->screenSpaceTransform(); + WebTransformationMatrix transform = layer->screenSpaceTransform(); if (boundsInContentSpace.isEmpty()) return transform; @@ -279,13 +280,13 @@ static inline TransformationMatrix contentToScreenSpaceTransform(const LayerType } template<typename LayerType> -static inline TransformationMatrix contentToTargetSurfaceTransform(const LayerType* layer) +static inline WebTransformationMatrix contentToTargetSurfaceTransform(const LayerType* layer) { ASSERT(layerTransformsToTargetKnown(layer)); IntSize boundsInLayerSpace = layer->bounds(); IntSize boundsInContentSpace = layer->contentBounds(); - TransformationMatrix transform = layer->drawTransform(); + WebTransformationMatrix transform = layer->drawTransform(); if (boundsInContentSpace.isEmpty()) return transform; @@ -302,7 +303,7 @@ static inline TransformationMatrix contentToTargetSurfaceTransform(const LayerTy // FIXME: Remove usePaintTracking when paint tracking is on for paint culling. template<typename LayerType> -static inline void addOcclusionBehindLayer(Region& region, const LayerType* layer, const TransformationMatrix& transform, const Region& opaqueContents, const IntRect& scissorRect, const IntSize& minimumTrackingSize) +static inline void addOcclusionBehindLayer(Region& region, const LayerType* layer, const WebTransformationMatrix& transform, const Region& opaqueContents, const IntRect& scissorRect, const IntSize& minimumTrackingSize) { ASSERT(layer->visibleLayerRect().contains(opaqueContents.bounds())); @@ -345,7 +346,7 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLay // remain rectilinear, then we don't add any occlusion in screen space. if (layerTransformsToScreenKnown(layer)) { - TransformationMatrix targetToScreenTransform = m_stack.last().surface->screenSpaceTransform(); + WebTransformationMatrix targetToScreenTransform = m_stack.last().surface->screenSpaceTransform(); bool clipped; FloatQuad scissorInScreenQuad = CCMathUtil::mapQuad(targetToScreenTransform, FloatQuad(FloatRect(scissorInTarget)), clipped); // FIXME: Find a rect interior to the transformed scissor quad. @@ -356,7 +357,7 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLay } } -static inline bool testContentRectOccluded(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion) +static inline bool testContentRectOccluded(const IntRect& contentRect, const WebTransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion) { FloatRect transformedRect = CCMathUtil::mapClippedRect(contentSpaceTransform, FloatRect(contentRect)); // Take the enclosingIntRect, as we want to include partial pixels in the test. @@ -391,7 +392,7 @@ static inline IntRect rectSubtractRegion(const IntRect& rect, const Region& regi return rectRegion.bounds(); } -static inline IntRect computeUnoccludedContentRect(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion) +static inline IntRect computeUnoccludedContentRect(const IntRect& contentRect, const WebTransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion) { if (!contentSpaceTransform.isInvertible()) return contentRect; @@ -439,34 +440,45 @@ IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContribu // This should be called while the contributing render surface is still considered the current target in the occlusion tracker. ASSERT(surface == m_stack.last().surface); - // A contributing surface doesn't get occluded by things inside its own surface, so only things outside the surface can occlude it. That occlusion is - // found just below the top of the stack (if it exists). - if (m_stack.size() < 2) - return contentRect; if (contentRect.isEmpty()) return contentRect; - const StackObject& secondLast = m_stack[m_stack.size() - 2]; - IntRect surfaceClipRect = surface->clipRect(); if (surfaceClipRect.isEmpty()) { - const RenderSurfaceType* targetSurface = secondLast.surface; - surfaceClipRect = intersection(targetSurface->contentRect(), enclosingIntRect(surface->drawableContentRect())); + const RenderSurfaceType* targetSurface = surface->targetRenderSurface(); + if (targetSurface) + surfaceClipRect = intersection(targetSurface->contentRect(), enclosingIntRect(surface->drawableContentRect())); + else + surfaceClipRect = m_scissorRectInScreenSpace; } - const TransformationMatrix& transformToScreen = forReplica ? surface->replicaScreenSpaceTransform() : surface->screenSpaceTransform(); - const TransformationMatrix& transformToTarget = forReplica ? surface->replicaOriginTransform() : surface->originTransform(); + // A contributing surface doesn't get occluded by things inside its own surface, so only things outside the surface can occlude it. That occlusion is + // found just below the top of the stack (if it exists). + bool hasOcclusion = m_stack.size() > 1; + + const WebTransformationMatrix& transformToScreen = forReplica ? surface->replicaScreenSpaceTransform() : surface->screenSpaceTransform(); + const WebTransformationMatrix& transformToTarget = forReplica ? surface->replicaOriginTransform() : surface->originTransform(); IntRect unoccludedInScreen = contentRect; - if (surfaceTransformsToScreenKnown(surface)) - unoccludedInScreen = computeUnoccludedContentRect(contentRect, transformToScreen, m_scissorRectInScreenSpace, secondLast.occlusionInScreen); + if (surfaceTransformsToScreenKnown(surface)) { + if (hasOcclusion) { + const StackObject& secondLast = m_stack[m_stack.size() - 2]; + unoccludedInScreen = computeUnoccludedContentRect(contentRect, transformToScreen, m_scissorRectInScreenSpace, secondLast.occlusionInScreen); + } else + unoccludedInScreen = computeUnoccludedContentRect(contentRect, transformToScreen, m_scissorRectInScreenSpace, Region()); + } if (unoccludedInScreen.isEmpty()) return unoccludedInScreen; IntRect unoccludedInTarget = contentRect; - if (surfaceTransformsToTargetKnown(surface)) - unoccludedInTarget = computeUnoccludedContentRect(contentRect, transformToTarget, surfaceClipRect, secondLast.occlusionInTarget); + if (surfaceTransformsToTargetKnown(surface)) { + if (hasOcclusion) { + const StackObject& secondLast = m_stack[m_stack.size() - 2]; + unoccludedInTarget = computeUnoccludedContentRect(contentRect, transformToTarget, surfaceClipRect, secondLast.occlusionInTarget); + } else + unoccludedInTarget = computeUnoccludedContentRect(contentRect, transformToTarget, surfaceClipRect, Region()); + } return intersection(unoccludedInScreen, unoccludedInTarget); } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h index 232874523..12801ffbe 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h @@ -28,7 +28,6 @@ #include "FloatQuad.h" #include "Region.h" -#include "TransformationMatrix.h" #include "cc/CCLayerIterator.h" #include "cc/CCOverdrawMetrics.h" diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCOverdrawMetrics.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCOverdrawMetrics.cpp index 3b0193ec4..7b57c89b1 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCOverdrawMetrics.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCOverdrawMetrics.cpp @@ -31,10 +31,12 @@ #include "FloatQuad.h" #include "IntRect.h" #include "TraceEvent.h" -#include "TransformationMatrix.h" #include "cc/CCLayerTreeHost.h" #include "cc/CCLayerTreeHostImpl.h" #include <public/Platform.h> +#include <public/WebTransformationMatrix.h> + +using WebKit::WebTransformationMatrix; namespace WebCore { @@ -78,7 +80,7 @@ void CCOverdrawMetrics::didCullTileForUpload() ++m_tilesCulledForUpload; } -void CCOverdrawMetrics::didUpload(const TransformationMatrix& transformToTarget, const IntRect& uploadRect, const IntRect& opaqueRect) +void CCOverdrawMetrics::didUpload(const WebTransformationMatrix& transformToTarget, const IntRect& uploadRect, const IntRect& opaqueRect) { if (!m_recordMetricsForFrame) return; @@ -90,7 +92,7 @@ void CCOverdrawMetrics::didUpload(const TransformationMatrix& transformToTarget, m_pixelsUploadedTranslucent += uploadArea - uploadOpaqueArea; } -void CCOverdrawMetrics::didCullForDrawing(const TransformationMatrix& transformToTarget, const IntRect& beforeCullRect, const IntRect& afterCullRect) +void CCOverdrawMetrics::didCullForDrawing(const WebTransformationMatrix& transformToTarget, const IntRect& beforeCullRect, const IntRect& afterCullRect) { if (!m_recordMetricsForFrame) return; @@ -101,7 +103,7 @@ void CCOverdrawMetrics::didCullForDrawing(const TransformationMatrix& transformT m_pixelsCulledForDrawing += beforeCullArea - afterCullArea; } -void CCOverdrawMetrics::didDraw(const TransformationMatrix& transformToTarget, const IntRect& afterCullRect, const IntRect& opaqueRect) +void CCOverdrawMetrics::didDraw(const WebTransformationMatrix& transformToTarget, const IntRect& afterCullRect, const IntRect& opaqueRect) { if (!m_recordMetricsForFrame) return; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCOverdrawMetrics.h b/Source/WebCore/platform/graphics/chromium/cc/CCOverdrawMetrics.h index 5156c3c39..715f5e151 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCOverdrawMetrics.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCOverdrawMetrics.h @@ -27,9 +27,12 @@ #include <wtf/PassOwnPtr.h> +namespace WebKit { +class WebTransformationMatrix; +} + namespace WebCore { class IntRect; -class TransformationMatrix; class CCLayerTreeHost; class CCLayerTreeHostImpl; @@ -45,14 +48,14 @@ public: // Records that an invalid tile was culled and did not need to be painted/uploaded, and did not contribute to other tiles needing to be painted. void didCullTileForUpload(); // Records pixels that were uploaded to texture memory. - void didUpload(const TransformationMatrix& transformToTarget, const IntRect& uploadRect, const IntRect& opaqueRect); + void didUpload(const WebKit::WebTransformationMatrix& transformToTarget, const IntRect& uploadRect, const IntRect& opaqueRect); // These methods are used for saving metrics during draw. // Record pixels that were not drawn to screen. - void didCullForDrawing(const TransformationMatrix& transformToTarget, const IntRect& beforeCullRect, const IntRect& afterCullRect); + void didCullForDrawing(const WebKit::WebTransformationMatrix& transformToTarget, const IntRect& beforeCullRect, const IntRect& afterCullRect); // Record pixels that were drawn to screen. - void didDraw(const TransformationMatrix& transformToTarget, const IntRect& afterCullRect, const IntRect& opaqueRect); + void didDraw(const WebKit::WebTransformationMatrix& transformToTarget, const IntRect& afterCullRect, const IntRect& opaqueRect); void recordMetrics(const CCLayerTreeHost*) const; void recordMetrics(const CCLayerTreeHostImpl*) const; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp index 364624866..66eef39fc 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp @@ -30,12 +30,12 @@ #include "cc/CCQuadCuller.h" #include "Region.h" -#include "TransformationMatrix.h" #include "cc/CCDebugBorderDrawQuad.h" #include "cc/CCLayerImpl.h" #include "cc/CCOverdrawMetrics.h" #include "cc/CCRenderPass.h" #include "cc/CCRenderSurfaceDrawQuad.h" +#include <public/WebTransformationMatrix.h> using namespace std; @@ -89,11 +89,5 @@ bool CCQuadCuller::appendSurface(PassOwnPtr<CCDrawQuad> passDrawQuad) return appendQuadInternal(passDrawQuad, culledRect, m_quadList, *m_occlusionTracker, m_showCullingWithDebugBorderQuads); } -bool CCQuadCuller::appendReplica(PassOwnPtr<CCDrawQuad> passDrawQuad) -{ - IntRect culledRect = m_occlusionTracker->unoccludedContributingSurfaceContentRect(m_layer->renderSurface(), true, passDrawQuad->quadRect()); - return appendQuadInternal(passDrawQuad, culledRect, m_quadList, *m_occlusionTracker, m_showCullingWithDebugBorderQuads); -} - } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h index 2d2d80166..2999b6ad5 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h @@ -41,7 +41,6 @@ public: // Returns true if the quad is added to the list, and false if the quad is entirely culled. virtual bool append(PassOwnPtr<CCDrawQuad> passDrawQuad); virtual bool appendSurface(PassOwnPtr<CCDrawQuad> passDrawQuad); - virtual bool appendReplica(PassOwnPtr<CCDrawQuad> passDrawQuad); private: CCQuadList& m_quadList; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp index 848730a2c..fd89990c7 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp @@ -28,24 +28,14 @@ #include "cc/CCRenderPass.h" #include "Color.h" -#include "cc/CCDamageTracker.h" -#include "cc/CCDebugBorderDrawQuad.h" #include "cc/CCLayerImpl.h" #include "cc/CCQuadCuller.h" -#include "cc/CCRenderSurfaceDrawQuad.h" #include "cc/CCSharedQuadState.h" #include "cc/CCSolidColorDrawQuad.h" -namespace WebCore { +using WebKit::WebTransformationMatrix; -static const int debugSurfaceBorderWidth = 2; -static const int debugSurfaceBorderAlpha = 100; -static const int debugSurfaceBorderColorRed = 0; -static const int debugSurfaceBorderColorGreen = 0; -static const int debugSurfaceBorderColorBlue = 255; -static const int debugReplicaBorderColorRed = 160; -static const int debugReplicaBorderColorGreen = 0; -static const int debugReplicaBorderColorBlue = 255; +namespace WebCore { PassOwnPtr<CCRenderPass> CCRenderPass::create(CCRenderSurface* targetSurface) { @@ -75,26 +65,20 @@ void CCRenderPass::appendQuadsForRenderSurfaceLayer(CCLayerImpl* layer, CCOcclus CCQuadCuller quadCuller(m_quadList, layer, occlusionTracker, layer->hasDebugBorders()); CCRenderSurface* surface = layer->renderSurface(); + OwnPtr<CCSharedQuadState> sharedQuadState = surface->createSharedQuadState(); - if (layer->hasDebugBorders()) { - Color color(debugSurfaceBorderColorRed, debugSurfaceBorderColorGreen, debugSurfaceBorderColorBlue, debugSurfaceBorderAlpha); - quadCuller.appendSurface(CCDebugBorderDrawQuad::create(sharedQuadState.get(), surface->contentRect(), color, debugSurfaceBorderWidth)); - } bool isReplica = false; - quadCuller.appendSurface(CCRenderSurfaceDrawQuad::create(sharedQuadState.get(), surface->contentRect(), layer, surfaceDamageRect(), isReplica)); + surface->appendQuads(quadCuller, sharedQuadState.get(), isReplica, surfaceDamageRect()); m_sharedQuadStateList.append(sharedQuadState.release()); + if (!surface->hasReplica()) + return; + // Add replica after the surface so that it appears below the surface. - if (surface->hasReplica()) { - OwnPtr<CCSharedQuadState> sharedQuadState = surface->createReplicaSharedQuadState(); - if (layer->hasDebugBorders()) { - Color color(debugReplicaBorderColorRed, debugReplicaBorderColorGreen, debugReplicaBorderColorBlue, debugSurfaceBorderAlpha); - quadCuller.appendReplica(CCDebugBorderDrawQuad::create(sharedQuadState.get(), surface->contentRect(), color, debugSurfaceBorderWidth)); - } - bool isReplica = true; - quadCuller.appendReplica(CCRenderSurfaceDrawQuad::create(sharedQuadState.get(), surface->contentRect(), layer, surfaceDamageRect(), isReplica)); - m_sharedQuadStateList.append(sharedQuadState.release()); - } + OwnPtr<CCSharedQuadState> replicaSharedQuadState = surface->createReplicaSharedQuadState(); + isReplica = true; + surface->appendQuads(quadCuller, replicaSharedQuadState.get(), isReplica, surfaceDamageRect()); + m_sharedQuadStateList.append(replicaSharedQuadState.release()); } void CCRenderPass::appendQuadsToFillScreen(CCLayerImpl* rootLayer, const Color& screenBackgroundColor, const CCOcclusionTrackerImpl& occlusionTracker) @@ -107,7 +91,7 @@ void CCRenderPass::appendQuadsToFillScreen(CCLayerImpl* rootLayer, const Color& return; OwnPtr<CCSharedQuadState> sharedQuadState = rootLayer->createSharedQuadState(); - TransformationMatrix transformToLayerSpace = rootLayer->screenSpaceTransform().inverse(); + WebTransformationMatrix transformToLayerSpace = rootLayer->screenSpaceTransform().inverse(); Vector<IntRect> fillRects = fillRegion.rects(); for (size_t i = 0; i < fillRects.size(); ++i) { IntRect layerRect = transformToLayerSpace.mapRect(fillRects[i]); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp index 6ab50998d..943c53fbf 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp @@ -29,27 +29,32 @@ #include "cc/CCRenderSurface.h" -#include "GeometryBinding.h" -#include "GrTexture.h" #include "GraphicsContext3D.h" #include "LayerChromium.h" #include "LayerRendererChromium.h" #include "ManagedTexture.h" -#include "SharedGraphicsContext3D.h" #include "TextStream.h" #include "cc/CCDamageTracker.h" +#include "cc/CCDebugBorderDrawQuad.h" #include "cc/CCLayerImpl.h" -#include "cc/CCProxy.h" -#include "cc/CCRenderSurfaceFilters.h" +#include "cc/CCQuadCuller.h" +#include "cc/CCRenderSurfaceDrawQuad.h" #include "cc/CCSharedQuadState.h" #include <wtf/text/CString.h> namespace WebCore { +static const int debugSurfaceBorderWidth = 2; +static const int debugSurfaceBorderAlpha = 100; +static const int debugSurfaceBorderColorRed = 0; +static const int debugSurfaceBorderColorGreen = 0; +static const int debugSurfaceBorderColorBlue = 255; +static const int debugReplicaBorderColorRed = 160; +static const int debugReplicaBorderColorGreen = 0; +static const int debugReplicaBorderColorBlue = 255; + CCRenderSurface::CCRenderSurface(CCLayerImpl* owningLayer) : m_owningLayer(owningLayer) - , m_maskLayer(0) - , m_skipsDraw(false) , m_surfacePropertyChanged(false) , m_drawOpacity(1) , m_drawOpacityIsAnimating(false) @@ -79,7 +84,6 @@ FloatRect CCRenderSurface::drawableContentRect() const bool CCRenderSurface::prepareContentsTexture(LayerRendererChromium* layerRenderer) { - IntSize requiredSize(m_contentRect.size()); TextureManager* textureManager = layerRenderer->renderSurfaceTextureManager(); if (!m_contentsTexture) @@ -88,25 +92,26 @@ bool CCRenderSurface::prepareContentsTexture(LayerRendererChromium* layerRendere if (m_contentsTexture->isReserved()) return true; - if (!m_contentsTexture->reserve(requiredSize, GraphicsContext3D::RGBA)) { - m_skipsDraw = true; + if (!m_contentsTexture->reserve(m_contentRect.size(), GraphicsContext3D::RGBA)) return false; - } - m_skipsDraw = false; return true; } void CCRenderSurface::releaseContentsTexture() { - if (m_skipsDraw || !m_contentsTexture) + if (!m_contentsTexture || !m_contentsTexture->isReserved()) return; m_contentsTexture->unreserve(); } +bool CCRenderSurface::hasValidContentsTexture() const +{ + return m_contentsTexture && m_contentsTexture->isReserved() && m_contentsTexture->isValid(m_contentRect.size(), GraphicsContext3D::RGBA); +} + bool CCRenderSurface::prepareBackgroundTexture(LayerRendererChromium* layerRenderer) { - IntSize requiredSize(m_contentRect.size()); TextureManager* textureManager = layerRenderer->renderSurfaceTextureManager(); if (!m_backgroundTexture) @@ -115,7 +120,7 @@ bool CCRenderSurface::prepareBackgroundTexture(LayerRendererChromium* layerRende if (m_backgroundTexture->isReserved()) return true; - if (!m_backgroundTexture->reserve(requiredSize, GraphicsContext3D::RGBA)) + if (!m_backgroundTexture->reserve(m_contentRect.size(), GraphicsContext3D::RGBA)) return false; return true; @@ -123,89 +128,14 @@ bool CCRenderSurface::prepareBackgroundTexture(LayerRendererChromium* layerRende void CCRenderSurface::releaseBackgroundTexture() { - if (!m_backgroundTexture) + if (!m_backgroundTexture || !m_backgroundTexture->isReserved()) return; m_backgroundTexture->unreserve(); } -TransformationMatrix CCRenderSurface::computeDeviceTransform(LayerRendererChromium* layerRenderer, const TransformationMatrix& drawTransform) const +bool CCRenderSurface::hasValidBackgroundTexture() const { - TransformationMatrix renderTransform = drawTransform; - // Apply a scaling factor to size the quad from 1x1 to its intended size. - renderTransform.scale3d(m_contentRect.width(), m_contentRect.height(), 1); - TransformationMatrix deviceTransform = TransformationMatrix(layerRenderer->windowMatrix() * layerRenderer->projectionMatrix() * renderTransform).to2dTransform(); - return deviceTransform; -} - -IntRect CCRenderSurface::computeDeviceBoundingBox(LayerRendererChromium* layerRenderer, const TransformationMatrix& drawTransform) const -{ - TransformationMatrix contentsDeviceTransform = computeDeviceTransform(layerRenderer, drawTransform); - - // Can only draw surface if device matrix is invertible. - if (!contentsDeviceTransform.isInvertible()) - return IntRect(); - - FloatQuad deviceQuad = contentsDeviceTransform.mapQuad(layerRenderer->sharedGeometryQuad()); - return enclosingIntRect(deviceQuad.boundingBox()); -} - -IntRect CCRenderSurface::computeReadbackDeviceBoundingBox(LayerRendererChromium* layerRenderer, const TransformationMatrix& drawTransform) const -{ - IntRect deviceRect = computeDeviceBoundingBox(layerRenderer, drawTransform); - - if (m_backgroundFilters.isEmpty()) - return deviceRect; - - int top, right, bottom, left; - m_backgroundFilters.getOutsets(top, right, bottom, left); - deviceRect.move(-left, -top); - deviceRect.expand(left + right, top + bottom); - - return deviceRect; -} - -IntRect CCRenderSurface::readbackDeviceContentRect(LayerRendererChromium* layerRenderer, const TransformationMatrix& drawTransform) const -{ - return computeReadbackDeviceBoundingBox(layerRenderer, drawTransform); -} - -void CCRenderSurface::copyTextureToFramebuffer(LayerRendererChromium* layerRenderer, int textureId, const IntSize& bounds, const TransformationMatrix& drawMatrix) -{ - const LayerRendererChromium::RenderSurfaceProgram* program = layerRenderer->renderSurfaceProgram(); - - GLC(layerRenderer->context(), layerRenderer->context()->activeTexture(GraphicsContext3D::TEXTURE0)); - GLC(layerRenderer->context(), layerRenderer->context()->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId)); - GLC(layerRenderer->context(), layerRenderer->context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR)); - GLC(layerRenderer->context(), layerRenderer->context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR)); - - GLC(layerRenderer->context(), layerRenderer->context()->useProgram(program->program())); - GLC(layerRenderer->context(), layerRenderer->context()->uniform1i(program->fragmentShader().samplerLocation(), 0)); - layerRenderer->drawTexturedQuad(drawMatrix, bounds.width(), bounds.height(), 1, layerRenderer->sharedGeometryQuad(), - program->vertexShader().matrixLocation(), - program->fragmentShader().alphaLocation(), - -1); -} - -void CCRenderSurface::copyDeviceToBackgroundTexture(LayerRendererChromium* layerRenderer, int deviceBackgroundTextureId, const IntRect& deviceTextureRect, const TransformationMatrix& deviceTransform) const -{ - ASSERT(!m_backgroundFilters.isEmpty()); - - TransformationMatrix deviceToSurfaceTransform; - deviceToSurfaceTransform.translate(m_contentRect.width() / 2.0, m_contentRect.height() / 2.0); - deviceToSurfaceTransform.scale3d(m_contentRect.width(), m_contentRect.height(), 1); - deviceToSurfaceTransform *= deviceTransform.inverse(); - deviceToSurfaceTransform.translate(deviceTextureRect.width() / 2.0, deviceTextureRect.height() / 2.0); - deviceToSurfaceTransform.translate(deviceTextureRect.x(), deviceTextureRect.y()); - - copyTextureToFramebuffer(layerRenderer, deviceBackgroundTextureId, deviceTextureRect.size(), deviceToSurfaceTransform); -} - -inline static int getSkBitmapTextureId(const SkBitmap& bitmap, int fallback) -{ - if (!bitmap.getTexture()) - return fallback; - GrTexture* texture = reinterpret_cast<GrTexture*>(bitmap.getTexture()); - return texture->getTextureHandle(); + return m_backgroundTexture && m_backgroundTexture->isReserved() && m_backgroundTexture->isValid(m_contentRect.size(), GraphicsContext3D::RGBA); } void CCRenderSurface::setScissorRect(LayerRendererChromium* layerRenderer, const FloatRect& surfaceDamageRect) const @@ -222,139 +152,6 @@ void CCRenderSurface::setScissorRect(LayerRendererChromium* layerRenderer, const GLC(layerRenderer->context(), layerRenderer->context()->disable(GraphicsContext3D::SCISSOR_TEST)); } -void CCRenderSurface::drawContents(LayerRendererChromium* layerRenderer) -{ - if (m_skipsDraw || !m_contentsTexture) - return; - - // FIXME: Cache this value so that we don't have to do it for both the surface and its replica. - // Apply filters to the contents texture. - SkBitmap filterBitmap = applyFilters(layerRenderer, m_filters, m_contentsTexture.get()); - - int contentsTextureId = getSkBitmapTextureId(filterBitmap, m_contentsTexture->textureId()); - drawLayer(layerRenderer, m_maskLayer, m_drawTransform, contentsTextureId); -} - -void CCRenderSurface::drawReplica(LayerRendererChromium* layerRenderer) -{ - ASSERT(hasReplica()); - if (!hasReplica() || m_skipsDraw || !m_contentsTexture) - return; - - // Apply filters to the contents texture. - SkBitmap filterBitmap = applyFilters(layerRenderer, m_filters, m_contentsTexture.get()); - - // FIXME: By using the same RenderSurface for both the content and its reflection, - // it's currently not possible to apply a separate mask to the reflection layer - // or correctly handle opacity in reflections (opacity must be applied after drawing - // both the layer and its reflection). The solution is to introduce yet another RenderSurface - // to draw the layer and its reflection in. For now we only apply a separate reflection - // mask if the contents don't have a mask of their own. - CCLayerImpl* replicaMaskLayer = m_maskLayer; - if (!m_maskLayer && m_owningLayer->replicaLayer()) - replicaMaskLayer = m_owningLayer->replicaLayer()->maskLayer(); - - int contentsTextureId = getSkBitmapTextureId(filterBitmap, m_contentsTexture->textureId()); - drawLayer(layerRenderer, replicaMaskLayer, m_replicaDrawTransform, contentsTextureId); -} - -void CCRenderSurface::drawLayer(LayerRendererChromium* layerRenderer, CCLayerImpl* maskLayer, const TransformationMatrix& drawTransform, int contentsTextureId) -{ - TransformationMatrix deviceMatrix = computeDeviceTransform(layerRenderer, drawTransform); - - // Can only draw surface if device matrix is invertible. - if (!deviceMatrix.isInvertible()) - return; - - // Draw the background texture if there is one. - if (m_backgroundTexture && m_backgroundTexture->isReserved()) - copyTextureToFramebuffer(layerRenderer, m_backgroundTexture->textureId(), m_contentRect.size(), drawTransform); - - FloatQuad quad = deviceMatrix.mapQuad(layerRenderer->sharedGeometryQuad()); - CCLayerQuad deviceRect = CCLayerQuad(FloatQuad(quad.boundingBox())); - CCLayerQuad layerQuad = CCLayerQuad(quad); - - // Use anti-aliasing programs only when necessary. - bool useAA = (!quad.isRectilinear() || !quad.boundingBox().isExpressibleAsIntRect()); - - if (useAA) { - deviceRect.inflateAntiAliasingDistance(); - layerQuad.inflateAntiAliasingDistance(); - } - - bool useMask = false; - if (maskLayer && maskLayer->drawsContent()) - if (!maskLayer->bounds().isEmpty()) - useMask = true; - - // FIXME: pass in backgroundTextureId and blend the background in with this draw instead of having a separate drawBackground() pass. - - if (useMask) { - if (useAA) { - const LayerRendererChromium::RenderSurfaceMaskProgramAA* program = layerRenderer->renderSurfaceMaskProgramAA(); - drawSurface(layerRenderer, maskLayer, drawTransform, deviceMatrix, deviceRect, layerQuad, contentsTextureId, program, program->fragmentShader().maskSamplerLocation(), program->vertexShader().pointLocation(), program->fragmentShader().edgeLocation()); - } else { - const LayerRendererChromium::RenderSurfaceMaskProgram* program = layerRenderer->renderSurfaceMaskProgram(); - drawSurface(layerRenderer, maskLayer, drawTransform, deviceMatrix, deviceRect, layerQuad, contentsTextureId, program, program->fragmentShader().maskSamplerLocation(), -1, -1); - } - } else { - if (useAA) { - const LayerRendererChromium::RenderSurfaceProgramAA* program = layerRenderer->renderSurfaceProgramAA(); - drawSurface(layerRenderer, maskLayer, drawTransform, deviceMatrix, deviceRect, layerQuad, contentsTextureId, program, -1, program->vertexShader().pointLocation(), program->fragmentShader().edgeLocation()); - } else { - const LayerRendererChromium::RenderSurfaceProgram* program = layerRenderer->renderSurfaceProgram(); - drawSurface(layerRenderer, maskLayer, drawTransform, deviceMatrix, deviceRect, layerQuad, contentsTextureId, program, -1, -1, -1); - } - } -} - -template <class T> -void CCRenderSurface::drawSurface(LayerRendererChromium* layerRenderer, CCLayerImpl* maskLayer, const TransformationMatrix& drawTransform, const TransformationMatrix& deviceTransform, const CCLayerQuad& deviceRect, const CCLayerQuad& layerQuad, int contentsTextureId, const T* program, int shaderMaskSamplerLocation, int shaderQuadLocation, int shaderEdgeLocation) -{ - GraphicsContext3D* context3D = layerRenderer->context(); - - context3D->makeContextCurrent(); - GLC(context3D, context3D->useProgram(program->program())); - - GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0)); - GLC(context3D, context3D->uniform1i(program->fragmentShader().samplerLocation(), 0)); - context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, contentsTextureId); - - if (shaderMaskSamplerLocation != -1) { - GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE1)); - GLC(context3D, context3D->uniform1i(shaderMaskSamplerLocation, 1)); - maskLayer->bindContentsTexture(layerRenderer); - GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0)); - } - - if (shaderEdgeLocation != -1) { - float edge[24]; - layerQuad.toFloatArray(edge); - deviceRect.toFloatArray(&edge[12]); - GLC(context3D, context3D->uniform3fv(shaderEdgeLocation, 8, edge)); - } - - // Map device space quad to layer space. - FloatQuad quad = deviceTransform.inverse().mapQuad(layerQuad.floatQuad()); - - layerRenderer->drawTexturedQuad(drawTransform, m_contentRect.width(), m_contentRect.height(), m_drawOpacity, quad, - program->vertexShader().matrixLocation(), program->fragmentShader().alphaLocation(), shaderQuadLocation); -} - -SkBitmap CCRenderSurface::applyFilters(LayerRendererChromium* layerRenderer, const WebKit::WebFilterOperations& filters, ManagedTexture* sourceTexture) -{ - if (filters.isEmpty()) - return SkBitmap(); - - RefPtr<GraphicsContext3D> filterContext = CCProxy::hasImplThread() ? SharedGraphicsContext3D::getForImplThread() : SharedGraphicsContext3D::get(); - if (!filterContext) - return SkBitmap(); - - layerRenderer->context()->flush(); - - return CCRenderSurfaceFilters::apply(filters, sourceTexture->textureId(), sourceTexture->size(), filterContext.get()); -} - String CCRenderSurface::name() const { return String::format("RenderSurface(id=%i,owner=%s)", m_owningLayer->id(), m_owningLayer->debugName().utf8().data()); @@ -391,6 +188,14 @@ int CCRenderSurface::owningLayerId() const return m_owningLayer ? m_owningLayer->id() : 0; } +CCRenderSurface* CCRenderSurface::targetRenderSurface() const +{ + CCLayerImpl* parent = m_owningLayer->parent(); + if (!parent) + return 0; + return parent->targetRenderSurface(); +} + bool CCRenderSurface::hasReplica() const { return m_owningLayer->replicaLayer(); @@ -398,12 +203,12 @@ bool CCRenderSurface::hasReplica() const bool CCRenderSurface::hasMask() const { - return m_maskLayer; + return m_owningLayer->maskLayer(); } bool CCRenderSurface::replicaHasMask() const { - return hasReplica() && (m_maskLayer || m_owningLayer->replicaLayer()->maskLayer()); + return hasReplica() && (m_owningLayer->maskLayer() || m_owningLayer->replicaLayer()->maskLayer()); } void CCRenderSurface::setClipRect(const IntRect& clipRect) @@ -455,5 +260,38 @@ PassOwnPtr<CCSharedQuadState> CCRenderSurface::createReplicaSharedQuadState() co return CCSharedQuadState::create(replicaOriginTransform(), replicaDrawTransform(), contentRect(), clipRect(), drawOpacity(), isOpaque); } +void CCRenderSurface::appendQuads(CCQuadCuller& quadList, CCSharedQuadState* sharedQuadState, bool forReplica, const FloatRect& surfaceDamageRect) +{ + ASSERT(!forReplica || hasReplica()); + + if (m_owningLayer->hasDebugBorders()) { + int red = forReplica ? debugReplicaBorderColorRed : debugSurfaceBorderColorRed; + int green = forReplica ? debugReplicaBorderColorGreen : debugSurfaceBorderColorGreen; + int blue = forReplica ? debugReplicaBorderColorBlue : debugSurfaceBorderColorBlue; + Color color(red, green, blue, debugSurfaceBorderAlpha); + quadList.appendSurface(CCDebugBorderDrawQuad::create(sharedQuadState, contentRect(), color, debugSurfaceBorderWidth)); + } + + // FIXME: By using the same RenderSurface for both the content and its reflection, + // it's currently not possible to apply a separate mask to the reflection layer + // or correctly handle opacity in reflections (opacity must be applied after drawing + // both the layer and its reflection). The solution is to introduce yet another RenderSurface + // to draw the layer and its reflection in. For now we only apply a separate reflection + // mask if the contents don't have a mask of their own. + CCLayerImpl* maskLayer = m_owningLayer->maskLayer(); + if (maskLayer && (!maskLayer->drawsContent() || maskLayer->bounds().isEmpty())) + maskLayer = 0; + + if (!maskLayer && forReplica) { + maskLayer = m_owningLayer->replicaLayer()->maskLayer(); + if (maskLayer && (!maskLayer->drawsContent() || maskLayer->bounds().isEmpty())) + maskLayer = 0; + } + + int maskTextureId = maskLayer ? maskLayer->contentsTextureId() : 0; + + quadList.appendSurface(CCRenderSurfaceDrawQuad::create(sharedQuadState, contentRect(), m_owningLayer, surfaceDamageRect, forReplica, filters(), backgroundFilters(), maskTextureId)); +} + } #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h index a6dee10ec..855fcce7e 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h @@ -31,16 +31,16 @@ #include "FloatRect.h" #include "IntRect.h" -#include "SkBitmap.h" #include "TextureManager.h" -#include "TransformationMatrix.h" #include "cc/CCLayerQuad.h" #include <public/WebFilterOperations.h> +#include <public/WebTransformationMatrix.h> #include <wtf/Noncopyable.h> namespace WebCore { class CCDamageTracker; +class CCQuadCuller; class CCSharedQuadState; class CCLayerImpl; class LayerRendererChromium; @@ -54,19 +54,14 @@ public: bool prepareContentsTexture(LayerRendererChromium*); void releaseContentsTexture(); + bool hasValidContentsTexture() const; bool prepareBackgroundTexture(LayerRendererChromium*); void releaseBackgroundTexture(); + bool hasValidBackgroundTexture() const; void setScissorRect(LayerRendererChromium*, const FloatRect& surfaceDamageRect) const; - void drawContents(LayerRendererChromium*); - void drawReplica(LayerRendererChromium*); - - // Takes a texture with pixels in device space, and a transform from content space to the device. Copies the device-space texture back into - // content space for the surface, storing the result in the backgroundTexture(). The surface's backgroundTexture() must be the active drawing target. - void copyDeviceToBackgroundTexture(LayerRendererChromium*, int deviceBackgroundTextureId, const IntRect& deviceTextureRect, const TransformationMatrix& deviceTransform) const; - String name() const; void dumpSurface(TextStream&, int indent) const; @@ -74,18 +69,12 @@ public: // Returns the rect that encloses the RenderSurface including any reflection. FloatRect drawableContentRect() const; - // Returns the rect that encloses the pixels that may affect the pixel values in this surface through background filters. - IntRect readbackDeviceContentRect(LayerRendererChromium*, const TransformationMatrix& drawTransform) const; - - // Gives the transform from the surface content space, with origin in the top left, to the current target device space, with origin in the top left. - TransformationMatrix computeDeviceTransform(LayerRendererChromium*, const TransformationMatrix& drawTransform) const; float drawOpacity() const { return m_drawOpacity; } void setDrawOpacity(float opacity) { m_drawOpacity = opacity; } void setFilters(const WebKit::WebFilterOperations& filters) { m_filters = filters; } const WebKit::WebFilterOperations& filters() const { return m_filters; } - SkBitmap applyFilters(LayerRendererChromium*, const WebKit::WebFilterOperations&, ManagedTexture* sourceTexture); void setBackgroundFilters(const WebKit::WebFilterOperations& filters) { m_backgroundFilters = filters; } const WebKit::WebFilterOperations& backgroundFilters() const { return m_backgroundFilters; } @@ -96,23 +85,23 @@ public: bool drawOpacityIsAnimating() const { return m_drawOpacityIsAnimating; } void setDrawOpacityIsAnimating(bool drawOpacityIsAnimating) { m_drawOpacityIsAnimating = drawOpacityIsAnimating; } - void setDrawTransform(const TransformationMatrix& drawTransform) { m_drawTransform = drawTransform; } - const TransformationMatrix& drawTransform() const { return m_drawTransform; } + void setDrawTransform(const WebKit::WebTransformationMatrix& drawTransform) { m_drawTransform = drawTransform; } + const WebKit::WebTransformationMatrix& drawTransform() const { return m_drawTransform; } - void setOriginTransform(const TransformationMatrix& originTransform) { m_originTransform = originTransform; } - const TransformationMatrix& originTransform() const { return m_originTransform; } + void setOriginTransform(const WebKit::WebTransformationMatrix& originTransform) { m_originTransform = originTransform; } + const WebKit::WebTransformationMatrix& originTransform() const { return m_originTransform; } - void setScreenSpaceTransform(const TransformationMatrix& screenSpaceTransform) { m_screenSpaceTransform = screenSpaceTransform; } - const TransformationMatrix& screenSpaceTransform() const { return m_screenSpaceTransform; } + void setScreenSpaceTransform(const WebKit::WebTransformationMatrix& screenSpaceTransform) { m_screenSpaceTransform = screenSpaceTransform; } + const WebKit::WebTransformationMatrix& screenSpaceTransform() const { return m_screenSpaceTransform; } - void setReplicaDrawTransform(const TransformationMatrix& replicaDrawTransform) { m_replicaDrawTransform = replicaDrawTransform; } - const TransformationMatrix& replicaDrawTransform() const { return m_replicaDrawTransform; } + void setReplicaDrawTransform(const WebKit::WebTransformationMatrix& replicaDrawTransform) { m_replicaDrawTransform = replicaDrawTransform; } + const WebKit::WebTransformationMatrix& replicaDrawTransform() const { return m_replicaDrawTransform; } - void setReplicaOriginTransform(const TransformationMatrix& replicaOriginTransform) { m_replicaOriginTransform = replicaOriginTransform; } - const TransformationMatrix& replicaOriginTransform() const { return m_replicaOriginTransform; } + void setReplicaOriginTransform(const WebKit::WebTransformationMatrix& replicaOriginTransform) { m_replicaOriginTransform = replicaOriginTransform; } + const WebKit::WebTransformationMatrix& replicaOriginTransform() const { return m_replicaOriginTransform; } - void setReplicaScreenSpaceTransform(const TransformationMatrix& replicaScreenSpaceTransform) { m_replicaScreenSpaceTransform = replicaScreenSpaceTransform; } - const TransformationMatrix& replicaScreenSpaceTransform() const { return m_replicaScreenSpaceTransform; } + void setReplicaScreenSpaceTransform(const WebKit::WebTransformationMatrix& replicaScreenSpaceTransform) { m_replicaScreenSpaceTransform = replicaScreenSpaceTransform; } + const WebKit::WebTransformationMatrix& replicaScreenSpaceTransform() const { return m_replicaScreenSpaceTransform; } bool targetSurfaceTransformsAreAnimating() const { return m_targetSurfaceTransformsAreAnimating; } void setTargetSurfaceTransformsAreAnimating(bool animating) { m_targetSurfaceTransformsAreAnimating = animating; } @@ -126,18 +115,14 @@ public: void setContentRect(const IntRect&); const IntRect& contentRect() const { return m_contentRect; } - void setSkipsDraw(bool skipsDraw) { m_skipsDraw = skipsDraw; } - bool skipsDraw() const { return m_skipsDraw; } - void clearLayerList() { m_layerList.clear(); } Vector<CCLayerImpl*>& layerList() { return m_layerList; } - void setMaskLayer(CCLayerImpl* maskLayer) { m_maskLayer = maskLayer; } - ManagedTexture* contentsTexture() const { return m_contentsTexture.get(); } ManagedTexture* backgroundTexture() const { return m_backgroundTexture.get(); } int owningLayerId() const; + CCRenderSurface* targetRenderSurface() const; bool hasReplica() const; @@ -153,21 +138,13 @@ public: PassOwnPtr<CCSharedQuadState> createSharedQuadState() const; PassOwnPtr<CCSharedQuadState> createReplicaSharedQuadState() const; -private: - IntRect computeDeviceBoundingBox(LayerRendererChromium*, const TransformationMatrix& drawTransform) const; - IntRect computeReadbackDeviceBoundingBox(LayerRendererChromium*, const TransformationMatrix& drawTransform) const; - - void drawLayer(LayerRendererChromium*, CCLayerImpl*, const TransformationMatrix&, int contentsTextureId); - template <class T> - void drawSurface(LayerRendererChromium*, CCLayerImpl*, const TransformationMatrix& drawTransform, const TransformationMatrix& deviceTransform, const CCLayerQuad& deviceRect, const CCLayerQuad&, int contentsTextureId, const T* program, int shaderMaskSamplerLocation, int shaderQuadLocation, int shaderEdgeLocation); - - static void copyTextureToFramebuffer(LayerRendererChromium*, int textureId, const IntSize& bounds, const TransformationMatrix& drawMatrix); + // FIXME: Remove the surfaceDamageRect parameter when the value is removed from CCRenderSurfaceDrawQuad. + void appendQuads(CCQuadCuller&, CCSharedQuadState*, bool forReplica, const FloatRect& surfaceDamageRect); +private: CCLayerImpl* m_owningLayer; - CCLayerImpl* m_maskLayer; IntRect m_contentRect; - bool m_skipsDraw; bool m_surfacePropertyChanged; OwnPtr<ManagedTexture> m_contentsTexture; @@ -175,12 +152,12 @@ private: float m_drawOpacity; bool m_drawOpacityIsAnimating; - TransformationMatrix m_drawTransform; - TransformationMatrix m_originTransform; - TransformationMatrix m_screenSpaceTransform; - TransformationMatrix m_replicaDrawTransform; - TransformationMatrix m_replicaOriginTransform; - TransformationMatrix m_replicaScreenSpaceTransform; + WebKit::WebTransformationMatrix m_drawTransform; + WebKit::WebTransformationMatrix m_originTransform; + WebKit::WebTransformationMatrix m_screenSpaceTransform; + WebKit::WebTransformationMatrix m_replicaDrawTransform; + WebKit::WebTransformationMatrix m_replicaOriginTransform; + WebKit::WebTransformationMatrix m_replicaScreenSpaceTransform; bool m_targetSurfaceTransformsAreAnimating; bool m_screenSpaceTransformsAreAnimating; WebKit::WebFilterOperations m_filters; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurfaceDrawQuad.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurfaceDrawQuad.cpp index c6e021ece..df00c0e0f 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurfaceDrawQuad.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurfaceDrawQuad.cpp @@ -29,16 +29,19 @@ namespace WebCore { -PassOwnPtr<CCRenderSurfaceDrawQuad> CCRenderSurfaceDrawQuad::create(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, CCLayerImpl* layer, const FloatRect& surfaceDamageRect, bool isReplica) +PassOwnPtr<CCRenderSurfaceDrawQuad> CCRenderSurfaceDrawQuad::create(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, CCLayerImpl* layer, const FloatRect& surfaceDamageRect, bool isReplica, const WebKit::WebFilterOperations& filters, const WebKit::WebFilterOperations& backgroundFilters, unsigned maskTextureId) { - return adoptPtr(new CCRenderSurfaceDrawQuad(sharedQuadState, quadRect, layer, surfaceDamageRect, isReplica)); + return adoptPtr(new CCRenderSurfaceDrawQuad(sharedQuadState, quadRect, layer, surfaceDamageRect, isReplica, filters, backgroundFilters, maskTextureId)); } -CCRenderSurfaceDrawQuad::CCRenderSurfaceDrawQuad(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, CCLayerImpl* layer, const FloatRect& surfaceDamageRect, bool isReplica) +CCRenderSurfaceDrawQuad::CCRenderSurfaceDrawQuad(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, CCLayerImpl* layer, const FloatRect& surfaceDamageRect, bool isReplica, const WebKit::WebFilterOperations& filters, const WebKit::WebFilterOperations& backgroundFilters, unsigned maskTextureId) : CCDrawQuad(sharedQuadState, CCDrawQuad::RenderSurface, quadRect) , m_layer(layer) , m_surfaceDamageRect(surfaceDamageRect) , m_isReplica(isReplica) + , m_filters(filters) + , m_backgroundFilters(backgroundFilters) + , m_maskTextureId(maskTextureId) { ASSERT(m_layer); } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurfaceDrawQuad.h b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurfaceDrawQuad.h index 8f6da5eee..0a01281fa 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurfaceDrawQuad.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurfaceDrawQuad.h @@ -27,6 +27,7 @@ #define CCRenderSurfaceDrawQuad_h #include "cc/CCDrawQuad.h" +#include <public/WebFilterOperations.h> #include <wtf/PassOwnPtr.h> namespace WebCore { @@ -36,21 +37,28 @@ class CCLayerImpl; class CCRenderSurfaceDrawQuad : public CCDrawQuad { WTF_MAKE_NONCOPYABLE(CCRenderSurfaceDrawQuad); public: - static PassOwnPtr<CCRenderSurfaceDrawQuad> create(const CCSharedQuadState*, const IntRect&, CCLayerImpl*, const FloatRect& surfaceDamageRect, bool isReplica); + static PassOwnPtr<CCRenderSurfaceDrawQuad> create(const CCSharedQuadState*, const IntRect&, CCLayerImpl*, const FloatRect& surfaceDamageRect, bool isReplica, const WebKit::WebFilterOperations& filters, const WebKit::WebFilterOperations& backgroundFilters, unsigned maskTextureId); CCLayerImpl* layer() const { return m_layer; } bool isReplica() const { return m_isReplica; } + unsigned maskTextureId() const { return m_maskTextureId; } // The surface damage rect for the target surface this quad draws into. // FIXME: This can be removed once render surfaces get their own layer type. const FloatRect& surfaceDamageRect() const { return m_surfaceDamageRect; } + const WebKit::WebFilterOperations& filters() const { return m_filters; } + const WebKit::WebFilterOperations& backgroundFilters() const { return m_backgroundFilters; } + private: - CCRenderSurfaceDrawQuad(const CCSharedQuadState*, const IntRect&, CCLayerImpl*, const FloatRect& surfaceDamageRect, bool isReplica); + CCRenderSurfaceDrawQuad(const CCSharedQuadState*, const IntRect&, CCLayerImpl*, const FloatRect& surfaceDamageRect, bool isReplica, const WebKit::WebFilterOperations& filters, const WebKit::WebFilterOperations& backgroundFilters, unsigned maskTextureId); CCLayerImpl* m_layer; FloatRect m_surfaceDamageRect; bool m_isReplica; + WebKit::WebFilterOperations m_filters; + WebKit::WebFilterOperations m_backgroundFilters; + unsigned m_maskTextureId; }; } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSharedQuadState.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCSharedQuadState.cpp index 9bf76925b..3f2837e05 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCSharedQuadState.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCSharedQuadState.cpp @@ -27,14 +27,16 @@ #include "cc/CCSharedQuadState.h" +using WebKit::WebTransformationMatrix; + namespace WebCore { -PassOwnPtr<CCSharedQuadState> CCSharedQuadState::create(const TransformationMatrix& quadTransform, const TransformationMatrix& layerTransform, const IntRect& layerRect, const IntRect& clipRect, float opacity, bool opaque) +PassOwnPtr<CCSharedQuadState> CCSharedQuadState::create(const WebTransformationMatrix& quadTransform, const WebTransformationMatrix& layerTransform, const IntRect& layerRect, const IntRect& clipRect, float opacity, bool opaque) { return adoptPtr(new CCSharedQuadState(quadTransform, layerTransform, layerRect, clipRect, opacity, opaque)); } -CCSharedQuadState::CCSharedQuadState(const TransformationMatrix& quadTransform, const TransformationMatrix& layerTransform, const IntRect& layerRect, const IntRect& clipRect, float opacity, bool opaque) +CCSharedQuadState::CCSharedQuadState(const WebTransformationMatrix& quadTransform, const WebTransformationMatrix& layerTransform, const IntRect& layerRect, const IntRect& clipRect, float opacity, bool opaque) : m_quadTransform(quadTransform) , m_layerTransform(layerTransform) , m_layerRect(layerRect) diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSharedQuadState.h b/Source/WebCore/platform/graphics/chromium/cc/CCSharedQuadState.h index 4206aa5c2..a14b17daa 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCSharedQuadState.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCSharedQuadState.h @@ -28,7 +28,7 @@ #include "FloatQuad.h" #include "IntRect.h" -#include "TransformationMatrix.h" +#include <public/WebTransformationMatrix.h> #include <wtf/PassOwnPtr.h> namespace WebCore { @@ -36,12 +36,12 @@ namespace WebCore { class CCSharedQuadState { WTF_MAKE_NONCOPYABLE(CCSharedQuadState); public: - static PassOwnPtr<CCSharedQuadState> create(const TransformationMatrix& quadTransform, const TransformationMatrix& layerTransform, const IntRect& layerRect, const IntRect& clipRect, float opacity, bool opaque); + static PassOwnPtr<CCSharedQuadState> create(const WebKit::WebTransformationMatrix& quadTransform, const WebKit::WebTransformationMatrix& layerTransform, const IntRect& layerRect, const IntRect& clipRect, float opacity, bool opaque); // The transform that quads in a CCDrawQuad should be transformed with. - const TransformationMatrix& quadTransform() const { return m_quadTransform; } + const WebKit::WebTransformationMatrix& quadTransform() const { return m_quadTransform; } // The transform that layerRect() should be transformed with. - const TransformationMatrix& layerTransform() const { return m_layerTransform; } + const WebKit::WebTransformationMatrix& layerTransform() const { return m_layerTransform; } const IntRect& layerRect() const { return m_layerRect; } // Usage: if clipRect is empty, this clipRect should not be used. const IntRect& clipRect() const { return m_clipRect; } @@ -51,10 +51,10 @@ public: bool isLayerAxisAlignedIntRect() const; private: - CCSharedQuadState(const TransformationMatrix& quadTransform, const TransformationMatrix& layerTransform, const IntRect& layerRect, const IntRect& clipRect, float opacity, bool opaque); + CCSharedQuadState(const WebKit::WebTransformationMatrix& quadTransform, const WebKit::WebTransformationMatrix& layerTransform, const IntRect& layerRect, const IntRect& clipRect, float opacity, bool opaque); - TransformationMatrix m_quadTransform; - TransformationMatrix m_layerTransform; + WebKit::WebTransformationMatrix m_quadTransform; + WebKit::WebTransformationMatrix m_layerTransform; IntRect m_layerRect; IntRect m_clipRect; float m_opacity; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp index 0113c079a..17cdc59e4 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp @@ -58,9 +58,6 @@ private: CCSingleThreadProxy* m_proxy; }; -// Measured in seconds. -static const double animationTimerDelay = 1 / 60.0; - PassOwnPtr<CCProxy> CCSingleThreadProxy::create(CCLayerTreeHost* layerTreeHost) { return adoptPtr(new CCSingleThreadProxy(layerTreeHost)); @@ -165,7 +162,10 @@ bool CCSingleThreadProxy::initializeLayerRenderer() if (ok) { m_layerRendererInitialized = true; m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities(); - } + } else + // If we couldn't initialize the layer renderer, we shouldn't process any future animation events. + m_animationTimer->stop(); + return ok; } } @@ -278,7 +278,7 @@ bool CCSingleThreadProxy::commitRequested() const void CCSingleThreadProxy::didAddAnimation() { - m_animationTimer->startOneShot(animationTimerDelay); + m_animationTimer->startOneShot(animationTimerDelay()); } void CCSingleThreadProxy::stop() @@ -326,6 +326,11 @@ void CCSingleThreadProxy::compositeImmediately() } } +double CCSingleThreadProxy::animationTimerDelay() +{ + return 1 / 60.0; +} + void CCSingleThreadProxy::forceSerializeOnSwapBuffers() { { diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h b/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h index 8fc8984bf..441466afc 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h @@ -79,6 +79,9 @@ public: // Called by the legacy path where RenderWidget does the scheduling. void compositeImmediately(); + // Measured in seconds. + static double animationTimerDelay(); + private: explicit CCSingleThreadProxy(CCLayerTreeHost*); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp index 6ae3a1729..d1a4f7626 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp @@ -36,6 +36,7 @@ #include <wtf/text/WTFString.h> using namespace std; +using WebKit::WebTransformationMatrix; namespace WebCore { @@ -49,9 +50,9 @@ CCSolidColorLayerImpl::~CCSolidColorLayerImpl() { } -TransformationMatrix CCSolidColorLayerImpl::quadTransform() const +WebTransformationMatrix CCSolidColorLayerImpl::quadTransform() const { - TransformationMatrix solidColorTransform = drawTransform(); + WebTransformationMatrix solidColorTransform = drawTransform(); solidColorTransform.translate(-bounds().width() / 2.0, -bounds().height() / 2.0); return solidColorTransform; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h index d8fce3761..64291255f 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h @@ -26,8 +26,8 @@ #ifndef CCSolidColorLayerImpl_h #define CCSolidColorLayerImpl_h -#include "TransformationMatrix.h" #include "cc/CCLayerImpl.h" +#include <public/WebTransformationMatrix.h> namespace WebCore { @@ -41,7 +41,7 @@ public: } virtual ~CCSolidColorLayerImpl(); - virtual TransformationMatrix quadTransform() const OVERRIDE; + virtual WebKit::WebTransformationMatrix quadTransform() const OVERRIDE; virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*, bool& hadMissingTiles) OVERRIDE; protected: diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp index ec22a9fd6..efecabd1d 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp @@ -38,6 +38,7 @@ #include <wtf/text/WTFString.h> using namespace std; +using WebKit::WebTransformationMatrix; namespace WebCore { @@ -77,7 +78,7 @@ CCTiledLayerImpl::~CCTiledLayerImpl() { } -void CCTiledLayerImpl::bindContentsTexture(LayerRendererChromium* layerRenderer) +unsigned CCTiledLayerImpl::contentsTextureId() const { // This function is only valid for single texture layers, e.g. masks. ASSERT(m_tiler); @@ -88,7 +89,7 @@ void CCTiledLayerImpl::bindContentsTexture(LayerRendererChromium* layerRenderer) Platform3DObject textureId = tile ? tile->textureId() : 0; ASSERT(textureId); - layerRenderer->context()->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId); + return textureId; } void CCTiledLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const @@ -121,9 +122,9 @@ DrawableTile* CCTiledLayerImpl::createTile(int i, int j) return addedTile; } -TransformationMatrix CCTiledLayerImpl::quadTransform() const +WebTransformationMatrix CCTiledLayerImpl::quadTransform() const { - TransformationMatrix transform = drawTransform(); + WebTransformationMatrix transform = drawTransform(); if (contentBounds().isEmpty()) return transform; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h index bd146650b..f588c9cf5 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h @@ -27,9 +27,9 @@ #define CCTiledLayerImpl_h #include "LayerTextureUpdater.h" -#include "TransformationMatrix.h" #include "cc/CCLayerImpl.h" #include "cc/CCLayerTilingData.h" +#include <public/WebTransformationMatrix.h> namespace WebCore { @@ -45,7 +45,7 @@ public: virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*, bool& hadMissingTiles) OVERRIDE; - virtual void bindContentsTexture(LayerRendererChromium*) OVERRIDE; + virtual unsigned contentsTextureId() const OVERRIDE; virtual void dumpLayerProperties(TextStream&, int indent) const OVERRIDE; @@ -65,7 +65,7 @@ protected: bool hasTileAt(int, int) const; bool hasTextureIdForTileAt(int, int) const; - virtual TransformationMatrix quadTransform() const OVERRIDE; + virtual WebKit::WebTransformationMatrix quadTransform() const OVERRIDE; private: diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp index fd84c0972..839708ee9 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp @@ -227,6 +227,7 @@ MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer(MediaPlayer* player) , m_preload(MediaPlayer::Auto) , m_delayingLoad(false) , m_mediaDurationKnown(true) + , m_maxTimeLoadedAtLastDidLoadingProgress(0) , m_volumeTimerHandler(0) , m_muteTimerHandler(0) , m_hasVideo(false) @@ -920,17 +921,15 @@ float MediaPlayerPrivateGStreamer::maxTimeLoaded() const return loaded; } -unsigned MediaPlayerPrivateGStreamer::bytesLoaded() const +bool MediaPlayerPrivateGStreamer::didLoadingProgress() const { - if (!m_playBin) - return 0; - - if (!m_mediaDuration) - return 0; - - unsigned loaded = totalBytes() * maxTimeLoaded() / m_mediaDuration; - LOG_VERBOSE(Media, "bytesLoaded: %d", loaded); - return loaded; + if (!m_playBin || !m_mediaDuration || !totalBytes()) + return false; + float currentMaxTimeLoaded = maxTimeLoaded(); + bool didLoadingProgress = currentMaxTimeLoaded != m_maxTimeLoadedAtLastDidLoadingProgress; + m_maxTimeLoadedAtLastDidLoadingProgress = currentMaxTimeLoaded; + LOG_VERBOSE(Media, "didLoadingProgress: %d", didLoadingProgress); + return didLoadingProgress; } unsigned MediaPlayerPrivateGStreamer::totalBytes() const @@ -1674,7 +1673,7 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin() g_signal_connect(m_playBin, "video-changed", G_CALLBACK(mediaPlayerPrivateVideoChangedCallback), this); g_signal_connect(m_playBin, "audio-changed", G_CALLBACK(mediaPlayerPrivateAudioChangedCallback), this); - m_webkitVideoSink = webkit_video_sink_new(m_gstGWorld.get()); + m_webkitVideoSink = webkitVideoSinkNew(m_gstGWorld.get()); g_signal_connect(m_webkitVideoSink, "repaint-requested", G_CALLBACK(mediaPlayerPrivateRepaintCallback), this); diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h index 1b0ff26e6..39ee9ce4b 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h @@ -90,7 +90,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface { PassRefPtr<TimeRanges> buffered() const; float maxTimeSeekable() const; - unsigned bytesLoaded() const; + bool didLoadingProgress() const; unsigned totalBytes() const; void setVisible(bool); @@ -181,6 +181,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface { MediaPlayer::Preload m_preload; bool m_delayingLoad; bool m_mediaDurationKnown; + mutable float m_maxTimeLoadedAtLastDidLoadingProgress; #ifndef GST_API_VERSION_1 RefPtr<GStreamerGWorld> m_gstGWorld; #endif diff --git a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowPrivate.h b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowPrivate.h index 33600f696..b929e90e4 100644 --- a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowPrivate.h +++ b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowPrivate.h @@ -23,7 +23,7 @@ #include <QEvent> #include <QTimer> -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if defined(HAVE_QT5) && HAVE_QT5 #include <QWindow> #else #include <QWidget> @@ -33,7 +33,7 @@ namespace WebCore { class HTMLVideoElement; -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if defined(HAVE_QT5) && HAVE_QT5 typedef QWindow Base; #else typedef QWidget Base; diff --git a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowQt.cpp b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowQt.cpp index 506a59d1f..3e431f241 100644 --- a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowQt.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowQt.cpp @@ -38,7 +38,7 @@ static const int gHideMouseCursorDelay = 3000; FullScreenVideoWindow::FullScreenVideoWindow() : m_mediaElement(0) { -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +#if !HAVE(QT5) setAttribute(Qt::WA_NativeWindow); setAttribute(Qt::WA_NoSystemBackground, true); setAttribute(Qt::WA_PaintOnScreen, true); @@ -83,7 +83,7 @@ bool FullScreenVideoWindow::event(QEvent* ev) #ifndef QT_NO_CURSOR m_cursorTimer.stop(); #endif -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +#if !HAVE(QT5) setMouseTracking(false); releaseMouse(); #endif @@ -100,11 +100,11 @@ bool FullScreenVideoWindow::event(QEvent* ev) void FullScreenVideoWindow::showFullScreen() { Base::showFullScreen(); -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +#if !HAVE(QT5) setMouseTracking(true); #endif raise(); -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +#if !HAVE(QT5) setFocus(); #endif hideCursor(); @@ -132,7 +132,7 @@ PlatformVideoWindow::PlatformVideoWindow() m_window = win; win->setWindowFlags(win->windowFlags() | Qt::FramelessWindowHint); // FIXME: Port to Qt 5. -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +#if !HAVE(QT5) QPalette p; p.setColor(QPalette::Base, Qt::black); p.setColor(QPalette::Window, Qt::black); diff --git a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp index 436303662..1389b695f 100644 --- a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2007 OpenedHand * Copyright (C) 2007 Alp Toker <alp@atoker.com> + * Copyright (C) 2009, 2010, 2011, 2012 Igalia S.L * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,36 +18,32 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/** - * SECTION:webkit-video-sink - * @short_description: GStreamer video sink +/* * - * #WebKitVideoSink is a GStreamer sink element that triggers + * WebKitVideoSink is a GStreamer sink element that triggers * repaints in the WebKit GStreamer media player for the * current video buffer. */ #include "config.h" +#if USE(GSTREAMER) #include "VideoSinkGStreamer.h" -#if ENABLE(VIDEO) && USE(GSTREAMER) #include <glib.h> #include <gst/gst.h> -#include <gst/video/video.h> #include <wtf/FastAllocBase.h> -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE("sink", - GST_PAD_SINK, GST_PAD_ALWAYS, // CAIRO_FORMAT_RGB24 used to render the video buffers is little/big endian dependant. #if G_BYTE_ORDER == G_LITTLE_ENDIAN - GST_STATIC_CAPS(GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_BGRA) +#define WEBKIT_VIDEO_SINK_PAD_CAPS GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_BGRA #else - GST_STATIC_CAPS(GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_ARGB) +#define WEBKIT_VIDEO_SINK_PAD_CAPS GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_ARGB #endif -); +static GstStaticPadTemplate s_sinkTemplate = GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS(WEBKIT_VIDEO_SINK_PAD_CAPS)); + -GST_DEBUG_CATEGORY_STATIC(webkit_video_sink_debug); -#define GST_CAT_DEFAULT webkit_video_sink_debug +GST_DEBUG_CATEGORY_STATIC(webkitVideoSinkDebug); +#define GST_CAT_DEFAULT webkitVideoSinkDebug enum { REPAINT_REQUESTED, @@ -57,13 +54,14 @@ enum { PROP_0 }; -static guint webkit_video_sink_signals[LAST_SIGNAL] = { 0, }; +static guint webkitVideoSinkSignals[LAST_SIGNAL] = { 0, }; struct _WebKitVideoSinkPrivate { GstBuffer* buffer; - guint timeout_id; - GMutex* buffer_mutex; - GCond* data_cond; + guint timeoutId; + GMutex* bufferMutex; + GCond* dataCondition; + WebCore::GStreamerGWorld* gstGWorld; // If this is TRUE all processing should finish ASAP @@ -74,92 +72,67 @@ struct _WebKitVideoSinkPrivate { // to deadlocks because render() holds the stream lock. // // Protected by the buffer mutex - gboolean unlocked; + bool unlocked; }; -#define _do_init(bla) \ - GST_DEBUG_CATEGORY_INIT(webkit_video_sink_debug, \ - "webkitsink", \ - 0, \ - "webkit video sink") +#define webkit_video_sink_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE(WebKitVideoSink, webkit_video_sink, GST_TYPE_VIDEO_SINK, GST_DEBUG_CATEGORY_INIT(webkitVideoSinkDebug, "webkitsink", 0, "webkit video sink")); -GST_BOILERPLATE_FULL(WebKitVideoSink, - webkit_video_sink, - GstVideoSink, - GST_TYPE_VIDEO_SINK, - _do_init); -static void -webkit_video_sink_base_init(gpointer g_class) +static void webkit_video_sink_init(WebKitVideoSink* sink) { - GstElementClass* element_class = GST_ELEMENT_CLASS(g_class); - - gst_element_class_add_pad_template(element_class, gst_static_pad_template_get(&sinktemplate)); - gst_element_class_set_details_simple(element_class, "WebKit video sink", - "Sink/Video", "Sends video data from a GStreamer pipeline to a Cairo surface", - "Alp Toker <alp@atoker.com>"); -} - -static void -webkit_video_sink_init(WebKitVideoSink* sink, WebKitVideoSinkClass* klass) -{ - WebKitVideoSinkPrivate* priv; - - sink->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE(sink, WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkPrivate); + sink->priv = G_TYPE_INSTANCE_GET_PRIVATE(sink, WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkPrivate); #if GLIB_CHECK_VERSION(2, 31, 0) - priv->data_cond = WTF::fastNew<GCond>(); - g_cond_init(priv->data_cond); - priv->buffer_mutex = WTF::fastNew<GMutex>(); - g_mutex_init(priv->buffer_mutex); + sink->priv->dataCondition = WTF::fastNew<GCond>(); + g_cond_init(sink->priv->dataCondition); + sink->priv->bufferMutex = WTF::fastNew<GMutex>(); + g_mutex_init(sink->priv->bufferMutex); #else - priv->data_cond = g_cond_new(); - priv->buffer_mutex = g_mutex_new(); + sink->priv->dataCondition = g_cond_new(); + sink->priv->bufferMutex = g_mutex_new(); #endif } -static gboolean -webkit_video_sink_timeout_func(gpointer data) +static gboolean webkitVideoSinkTimeoutCallback(gpointer data) { WebKitVideoSink* sink = reinterpret_cast<WebKitVideoSink*>(data); WebKitVideoSinkPrivate* priv = sink->priv; - GstBuffer* buffer; - g_mutex_lock(priv->buffer_mutex); - buffer = priv->buffer; + g_mutex_lock(priv->bufferMutex); + GstBuffer* buffer = priv->buffer; priv->buffer = 0; - priv->timeout_id = 0; + priv->timeoutId = 0; - if (!buffer || priv->unlocked || G_UNLIKELY(!GST_IS_BUFFER(buffer))) { - g_cond_signal(priv->data_cond); - g_mutex_unlock(priv->buffer_mutex); + if (!buffer || priv->unlocked || UNLIKELY(!GST_IS_BUFFER(buffer))) { + g_cond_signal(priv->dataCondition); + g_mutex_unlock(priv->bufferMutex); return FALSE; } - g_signal_emit(sink, webkit_video_sink_signals[REPAINT_REQUESTED], 0, buffer); + g_signal_emit(sink, webkitVideoSinkSignals[REPAINT_REQUESTED], 0, buffer); gst_buffer_unref(buffer); - g_cond_signal(priv->data_cond); - g_mutex_unlock(priv->buffer_mutex); + g_cond_signal(priv->dataCondition); + g_mutex_unlock(priv->bufferMutex); return FALSE; } -static GstFlowReturn -webkit_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer) +static GstFlowReturn webkitVideoSinkRender(GstBaseSink* baseSink, GstBuffer* buffer) { - WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(bsink); + WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(baseSink); WebKitVideoSinkPrivate* priv = sink->priv; - g_mutex_lock(priv->buffer_mutex); + g_mutex_lock(priv->bufferMutex); if (priv->unlocked) { - g_mutex_unlock(priv->buffer_mutex); + g_mutex_unlock(priv->bufferMutex); return GST_FLOW_OK; } // Ignore buffers if the video is already in fullscreen using // another sink. if (priv->gstGWorld->isFullscreen()) { - g_mutex_unlock(priv->buffer_mutex); + g_mutex_unlock(priv->bufferMutex); return GST_FLOW_OK; } @@ -167,17 +140,17 @@ webkit_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer) // For the unlikely case where the buffer has no caps, the caps // are implicitely the caps of the pad. This shouldn't happen. - if (G_UNLIKELY(!GST_BUFFER_CAPS(buffer))) { + if (UNLIKELY(!GST_BUFFER_CAPS(buffer))) { buffer = priv->buffer = gst_buffer_make_metadata_writable(priv->buffer); - gst_buffer_set_caps(priv->buffer, GST_PAD_CAPS(GST_BASE_SINK_PAD(bsink))); + gst_buffer_set_caps(priv->buffer, GST_PAD_CAPS(GST_BASE_SINK_PAD(baseSink))); } - GstCaps *caps = GST_BUFFER_CAPS(buffer); + GstCaps* caps = GST_BUFFER_CAPS(buffer); GstVideoFormat format; int width, height; - if (G_UNLIKELY(!gst_video_format_parse_caps(caps, &format, &width, &height))) { + if (UNLIKELY(!gst_video_format_parse_caps(caps, &format, &width, &height))) { gst_buffer_unref(buffer); - g_mutex_unlock(priv->buffer_mutex); + g_mutex_unlock(priv->bufferMutex); return GST_FLOW_ERROR; } @@ -187,36 +160,35 @@ webkit_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer) // Because GstBaseSink::render() only owns the buffer reference in the // method scope we can't use gst_buffer_make_writable() here. Also // The buffer content should not be changed here because the same buffer - // could be passed multiple times to this method (in theory) - GstBuffer *newBuffer = gst_buffer_try_new_and_alloc(GST_BUFFER_SIZE(buffer)); + // could be passed multiple times to this method (in theory). + + GstBuffer* newBuffer = gst_buffer_try_new_and_alloc(GST_BUFFER_SIZE(buffer)); - // Check if allocation failed - if (G_UNLIKELY(!newBuffer)) { - gst_buffer_unref(buffer); - g_mutex_unlock(priv->buffer_mutex); + // Check if allocation failed. + if (UNLIKELY(!newBuffer)) { + g_mutex_unlock(priv->bufferMutex); return GST_FLOW_ERROR; } - gst_buffer_copy_metadata(newBuffer, buffer, (GstBufferCopyFlags) GST_BUFFER_COPY_ALL); + gst_buffer_copy_metadata(newBuffer, buffer, static_cast<GstBufferCopyFlags>(GST_BUFFER_COPY_ALL)); // We don't use Color::premultipliedARGBFromColor() here because // one function call per video pixel is just too expensive: // For 720p/PAL for example this means 1280*720*25=23040000 // function calls per second! - unsigned short alpha; - const guint8 *source = GST_BUFFER_DATA(buffer); - guint8 *destination = GST_BUFFER_DATA(newBuffer); + const guint8* source = GST_BUFFER_DATA(buffer); + guint8* destination = GST_BUFFER_DATA(newBuffer); for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN - alpha = source[3]; + unsigned short alpha = source[3]; destination[0] = (source[0] * alpha + 128) / 255; destination[1] = (source[1] * alpha + 128) / 255; destination[2] = (source[2] * alpha + 128) / 255; destination[3] = alpha; #else - alpha = source[0]; + unsigned short alpha = source[0]; destination[0] = alpha; destination[1] = (source[1] * alpha + 128) / 255; destination[2] = (source[2] * alpha + 128) / 255; @@ -226,6 +198,7 @@ webkit_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer) destination += 4; } } + gst_buffer_unref(buffer); buffer = priv->buffer = newBuffer; } @@ -233,165 +206,151 @@ webkit_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer) // This should likely use a lower priority, but glib currently starves // lower priority sources. // See: https://bugzilla.gnome.org/show_bug.cgi?id=610830. - priv->timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT, 0, - webkit_video_sink_timeout_func, - gst_object_ref(sink), - (GDestroyNotify)gst_object_unref); + priv->timeoutId = g_timeout_add_full(G_PRIORITY_DEFAULT, 0, webkitVideoSinkTimeoutCallback, + gst_object_ref(sink), reinterpret_cast<GDestroyNotify>(gst_object_unref)); - g_cond_wait(priv->data_cond, priv->buffer_mutex); - g_mutex_unlock(priv->buffer_mutex); + g_cond_wait(priv->dataCondition, priv->bufferMutex); + g_mutex_unlock(priv->bufferMutex); return GST_FLOW_OK; } -static void -webkit_video_sink_dispose(GObject* object) +static void webkitVideoSinkDispose(GObject* object) { WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(object); WebKitVideoSinkPrivate* priv = sink->priv; - if (priv->data_cond) { + if (priv->dataCondition) { #if GLIB_CHECK_VERSION(2, 31, 0) - g_cond_clear(priv->data_cond); - WTF::fastDelete(priv->data_cond); + g_cond_clear(priv->dataCondition); + WTF::fastDelete(priv->dataCondition); #else - g_cond_free(priv->data_cond); + g_cond_free(priv->dataCondition); #endif - priv->data_cond = 0; + priv->dataCondition = 0; } - if (priv->buffer_mutex) { + if (priv->bufferMutex) { #if GLIB_CHECK_VERSION(2, 31, 0) - g_mutex_clear(priv->buffer_mutex); - WTF::fastDelete(priv->buffer_mutex); + g_mutex_clear(priv->bufferMutex); + WTF::fastDelete(priv->bufferMutex); #else - g_mutex_free(priv->buffer_mutex); + g_mutex_free(priv->bufferMutex); #endif - priv->buffer_mutex = 0; + priv->bufferMutex = 0; } G_OBJECT_CLASS(parent_class)->dispose(object); } -static void -unlock_buffer_mutex(WebKitVideoSinkPrivate* priv) +static void unlockBufferMutex(WebKitVideoSinkPrivate* priv) { - g_mutex_lock(priv->buffer_mutex); + g_mutex_lock(priv->bufferMutex); if (priv->buffer) { gst_buffer_unref(priv->buffer); priv->buffer = 0; } - priv->unlocked = TRUE; + priv->unlocked = true; - g_cond_signal(priv->data_cond); - g_mutex_unlock(priv->buffer_mutex); + g_cond_signal(priv->dataCondition); + g_mutex_unlock(priv->bufferMutex); } -static gboolean -webkit_video_sink_unlock(GstBaseSink* object) +static gboolean webkitVideoSinkUnlock(GstBaseSink* baseSink) { - WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(object); + WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(baseSink); - unlock_buffer_mutex(sink->priv); + unlockBufferMutex(sink->priv); - return GST_CALL_PARENT_WITH_DEFAULT(GST_BASE_SINK_CLASS, unlock, - (object), TRUE); + return GST_CALL_PARENT_WITH_DEFAULT(GST_BASE_SINK_CLASS, unlock, (baseSink), TRUE); } -static gboolean -webkit_video_sink_unlock_stop(GstBaseSink* object) +static gboolean webkitVideoSinkUnlockStop(GstBaseSink* baseSink) { - WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(object); - WebKitVideoSinkPrivate* priv = sink->priv; + WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(baseSink)->priv; - g_mutex_lock(priv->buffer_mutex); - priv->unlocked = FALSE; - g_mutex_unlock(priv->buffer_mutex); + g_mutex_lock(priv->bufferMutex); + priv->unlocked = false; + g_mutex_unlock(priv->bufferMutex); - return GST_CALL_PARENT_WITH_DEFAULT(GST_BASE_SINK_CLASS, unlock_stop, - (object), TRUE); + return GST_CALL_PARENT_WITH_DEFAULT(GST_BASE_SINK_CLASS, unlock_stop, (baseSink), TRUE); } -static gboolean -webkit_video_sink_stop(GstBaseSink* base_sink) +static gboolean webkitVideoSinkStop(GstBaseSink* baseSink) { - WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(base_sink)->priv; - - unlock_buffer_mutex(priv); + unlockBufferMutex(WEBKIT_VIDEO_SINK(baseSink)->priv); return TRUE; } -static gboolean -webkit_video_sink_start(GstBaseSink* base_sink) +static gboolean webkitVideoSinkStart(GstBaseSink* baseSink) { - WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(base_sink)->priv; + WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(baseSink)->priv; - g_mutex_lock(priv->buffer_mutex); - priv->unlocked = FALSE; - g_mutex_unlock(priv->buffer_mutex); + g_mutex_lock(priv->bufferMutex); + priv->unlocked = false; + g_mutex_unlock(priv->bufferMutex); return TRUE; } -static void -marshal_VOID__MINIOBJECT(GClosure * closure, GValue * return_value, - guint n_param_values, const GValue * param_values, - gpointer invocation_hint, gpointer marshal_data) +static void webkitVideoSinkMarshalVoidAndMiniObject(GClosure* closure, GValue* returnValue, guint parametersNumber, const GValue* parameterValues, gpointer invocationHint, gpointer marshalData) { - typedef void (*marshalfunc_VOID__MINIOBJECT) (gpointer obj, gpointer arg1, gpointer data2); - marshalfunc_VOID__MINIOBJECT callback; - GCClosure *cc = (GCClosure *) closure; - gpointer data1, data2; - - g_return_if_fail(n_param_values == 2); - - if (G_CCLOSURE_SWAP_DATA(closure)) { - data1 = closure->data; - data2 = g_value_peek_pointer(param_values + 0); - } else { - data1 = g_value_peek_pointer(param_values + 0); - data2 = closure->data; - } - callback = (marshalfunc_VOID__MINIOBJECT) (marshal_data ? marshal_data : cc->callback); - - callback(data1, gst_value_get_mini_object(param_values + 1), data2); + typedef void (*marshalfunc_VOID__MINIOBJECT) (gpointer obj, gpointer arg1, gpointer data2); + marshalfunc_VOID__MINIOBJECT callback; + GCClosure* cclosure = reinterpret_cast<GCClosure*>(closure); + gpointer data1, data2; + + g_return_if_fail(parametersNumber == 2); + + if (G_CCLOSURE_SWAP_DATA(closure)) { + data1 = closure->data; + data2 = g_value_peek_pointer(parameterValues + 0); + } else { + data1 = g_value_peek_pointer(parameterValues + 0); + data2 = closure->data; + } + + callback = (marshalfunc_VOID__MINIOBJECT) (marshalData ? marshalData : cclosure->callback); + callback(data1, gst_value_get_mini_object(parameterValues + 1), data2); } -static void -webkit_video_sink_class_init(WebKitVideoSinkClass* klass) +static void webkit_video_sink_class_init(WebKitVideoSinkClass* klass) { - GObjectClass* gobject_class = G_OBJECT_CLASS(klass); - GstBaseSinkClass* gstbase_sink_class = GST_BASE_SINK_CLASS(klass); + GObjectClass* gobjectClass = G_OBJECT_CLASS(klass); + GstBaseSinkClass* baseSinkClass = GST_BASE_SINK_CLASS(klass); + GstElementClass* elementClass = GST_ELEMENT_CLASS(klass); + + gst_element_class_add_pad_template(elementClass, gst_static_pad_template_get(&s_sinkTemplate)); + gst_element_class_set_details_simple(elementClass, + "WebKit video sink", + "Sink/Video", "Sends video data from a GStreamer pipeline to a Cairo surface", + "Alp Toker <alp@atoker.com>"); g_type_class_add_private(klass, sizeof(WebKitVideoSinkPrivate)); - gobject_class->dispose = webkit_video_sink_dispose; + gobjectClass->dispose = webkitVideoSinkDispose; - gstbase_sink_class->unlock = webkit_video_sink_unlock; - gstbase_sink_class->unlock_stop = webkit_video_sink_unlock_stop; - gstbase_sink_class->render = webkit_video_sink_render; - gstbase_sink_class->preroll = webkit_video_sink_render; - gstbase_sink_class->stop = webkit_video_sink_stop; - gstbase_sink_class->start = webkit_video_sink_start; + baseSinkClass->unlock = webkitVideoSinkUnlock; + baseSinkClass->unlock_stop = webkitVideoSinkUnlockStop; + baseSinkClass->render = webkitVideoSinkRender; + baseSinkClass->preroll = webkitVideoSinkRender; + baseSinkClass->stop = webkitVideoSinkStop; + baseSinkClass->start = webkitVideoSinkStart; - webkit_video_sink_signals[REPAINT_REQUESTED] = g_signal_new("repaint-requested", + webkitVideoSinkSignals[REPAINT_REQUESTED] = g_signal_new("repaint-requested", G_TYPE_FROM_CLASS(klass), - (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), - 0, - 0, - 0, - marshal_VOID__MINIOBJECT, - G_TYPE_NONE, 1, GST_TYPE_BUFFER); + static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + 0, // Class offset + 0, // Accumulator + 0, // Accumulator data + webkitVideoSinkMarshalVoidAndMiniObject, + G_TYPE_NONE, // Return type + 1, // Only one parameter + GST_TYPE_BUFFER); } -/** - * webkit_video_sink_new: - * - * Creates a new GStreamer video sink. - * - * Return value: a #GstElement for the newly created video sink - */ -GstElement* webkit_video_sink_new(WebCore::GStreamerGWorld* gstGWorld) + +GstElement* webkitVideoSinkNew(WebCore::GStreamerGWorld* gstGWorld) { GstElement* element = GST_ELEMENT(g_object_new(WEBKIT_TYPE_VIDEO_SINK, 0)); WEBKIT_VIDEO_SINK(element)->priv->gstGWorld = gstGWorld; diff --git a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h index 501850fde..34057aa46 100644 --- a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h +++ b/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h @@ -25,46 +25,29 @@ #include "GStreamerGWorld.h" #include <glib-object.h> #include <gst/video/gstvideosink.h> - -G_BEGIN_DECLS +#include <gst/video/video.h> #define WEBKIT_TYPE_VIDEO_SINK webkit_video_sink_get_type() -#define WEBKIT_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSink)) - -#define WEBKIT_VIDEO_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkClass)) - -#define WEBKIT_IS_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ - WEBKIT_TYPE_VIDEO_SINK)) +#define WEBKIT_VIDEO_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSink)) +#define WEBKIT_VIDEO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkClass)) +#define WEBKIT_IS_VIDEO_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_VIDEO_SINK)) +#define WEBKIT_IS_VIDEO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_VIDEO_SINK)) +#define WEBKIT_VIDEO_SINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkClass)) -#define WEBKIT_IS_VIDEO_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), \ - WEBKIT_TYPE_VIDEO_SINK)) - -#define WEBKIT_VIDEO_SINK_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkClass)) - -typedef struct _WebKitVideoSink WebKitVideoSink; -typedef struct _WebKitVideoSinkClass WebKitVideoSinkClass; +typedef struct _WebKitVideoSink WebKitVideoSink; +typedef struct _WebKitVideoSinkClass WebKitVideoSinkClass; typedef struct _WebKitVideoSinkPrivate WebKitVideoSinkPrivate; struct _WebKitVideoSink { - /*< private >*/ GstVideoSink parent; - WebKitVideoSinkPrivate *priv; + WebKitVideoSinkPrivate* priv; }; struct _WebKitVideoSinkClass { - /*< private >*/ GstVideoSinkClass parent_class; - /* Future padding */ + // Future padding void (* _webkit_reserved1)(void); void (* _webkit_reserved2)(void); void (* _webkit_reserved3)(void); @@ -73,11 +56,9 @@ struct _WebKitVideoSinkClass { void (* _webkit_reserved6)(void); }; +GType webkit_video_sink_get_type() G_GNUC_CONST; -GType webkit_video_sink_get_type(void) G_GNUC_CONST; -GstElement *webkit_video_sink_new(WebCore::GStreamerGWorld*); - -G_END_DECLS +GstElement* webkitVideoSinkNew(WebCore::GStreamerGWorld*); #endif // USE(GSTREAMER) #endif diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h index 3089ae2d4..011ec36a2 100644 --- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h +++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h @@ -121,7 +121,7 @@ private: PassRefPtr<TimeRanges> buffered() const; float maxTimeSeekable() const; - unsigned bytesLoaded() const; + bool didLoadingProgress() const; unsigned totalBytes() const; void setVisible(bool); @@ -212,6 +212,7 @@ private: bool m_videoFrameHasDrawn; bool m_isAllowedToRender; bool m_privateBrowsing; + mutable float m_maxTimeLoadedAtLastDidLoadingProgress; #if DRAW_FRAME_RATE int m_frameCountWhilePlaying; double m_timeStartedPlaying; diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm index 98599e96b..29249aa78 100644 --- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm +++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm @@ -214,6 +214,7 @@ MediaPlayerPrivateQTKit::MediaPlayerPrivateQTKit(MediaPlayer* player) , m_videoFrameHasDrawn(false) , m_isAllowedToRender(false) , m_privateBrowsing(false) + , m_maxTimeLoadedAtLastDidLoadingProgress(0) #if DRAW_FRAME_RATE , m_frameCountWhilePlaying(0) , m_timeStartedPlaying(0) @@ -945,12 +946,14 @@ float MediaPlayerPrivateQTKit::maxTimeLoaded() const return wkQTMovieMaxTimeLoaded(m_qtMovie.get()); } -unsigned MediaPlayerPrivateQTKit::bytesLoaded() const +bool MediaPlayerPrivateQTKit::didLoadingProgress() const { - float dur = duration(); - if (!dur) - return 0; - return totalBytes() * maxTimeLoaded() / dur; + if (!duration() || !totalBytes()) + return false; + float currentMaxTimeLoaded = maxTimeLoaded(); + bool didLoadingProgress = currentMaxTimeLoaded != m_maxTimeLoadedAtLastDidLoadingProgress; + m_maxTimeLoadedAtLastDidLoadingProgress = currentMaxTimeLoaded; + return didLoadingProgress; } unsigned MediaPlayerPrivateQTKit::totalBytes() const diff --git a/Source/WebCore/platform/graphics/openvg/ImageOpenVG.cpp b/Source/WebCore/platform/graphics/openvg/ImageOpenVG.cpp index 98a730c06..9510882cc 100644 --- a/Source/WebCore/platform/graphics/openvg/ImageOpenVG.cpp +++ b/Source/WebCore/platform/graphics/openvg/ImageOpenVG.cpp @@ -105,24 +105,6 @@ void BitmapImage::invalidatePlatformData() { } -#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) -static void adjustSourceRectForDownSampling(FloatRect& srcRect, const IntSize& origSize, const IntSize& scaledSize) -{ - // We assume down-sampling zoom rates in X direction and in Y direction are same. - if (origSize.width() == scaledSize.width()) - return; - - // Image has been down sampled. - double rate = static_cast<double>(scaledSize.width()) / origSize.width(); - double temp = srcRect.right() * rate; - srcRect.setX(srcRect.x() * rate); - srcRect.setWidth(temp - srcRect.x()); - temp = srcRect.bottom() * rate; - srcRect.setY(srcRect.y() * rate); - srcRect.setHeight(temp - srcRect.y()); -} -#endif - void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op) { if (dst.isEmpty() || src.isEmpty()) @@ -147,9 +129,10 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo else context->setCompositeOperation(op); - FloatRect srcRectLocal(src); #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) - adjustSourceRectForDownSampling(srcRectLocal, size(), image->size()); + FloatRect srcRectLocal = adjustSourceRectForDownSampling(src, image->size()); +#else + FloatRect srcRectLocal(src); #endif context->platformContext()->activePainter()->drawImage(image, dst, srcRectLocal); diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp index af95e4f74..f3a7ea8ab 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp @@ -194,7 +194,7 @@ void GraphicsContext3DPrivate::blitMultisampleFramebufferAndRestoreContext() con if (!m_context->m_attrs.antialias) return; -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) const QOpenGLContext* currentContext = QOpenGLContext::currentContext(); QSurface* currentSurface = 0; if (currentContext != m_platformContext) { @@ -220,7 +220,7 @@ void GraphicsContext3DPrivate::blitMultisampleFramebufferAndRestoreContext() con bool GraphicsContext3DPrivate::makeCurrentIfNeeded() const { -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) const QOpenGLContext* currentContext = QOpenGLContext::currentContext(); if (currentContext == m_platformContext) return true; @@ -322,7 +322,6 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi #endif } -#if !defined(QT_OPENGL_ES_2) // ANGLE initialization. ShBuiltInResources ANGLEResources; ShInitBuiltInResources(&ANGLEResources); @@ -339,6 +338,7 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi ANGLEResources.MaxDrawBuffers = 1; m_compiler.setResources(ANGLEResources); +#if !defined(QT_OPENGL_ES_2) glEnable(GL_POINT_SPRITE); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); #endif diff --git a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp index 1f93aa3cd..e03636f20 100644 --- a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp +++ b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp @@ -31,21 +31,10 @@ #include <QtCore/QByteArray> #include <QtCore/QBuffer> - #include <QtGui/QImageReader> -#include <qdebug.h> namespace WebCore { -ImageDecoder* ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption) -{ - // We need at least 4 bytes to figure out what kind of image we're dealing with. - if (data.size() < 4) - return 0; - - return new ImageDecoderQt(alphaOption, gammaAndColorProfileOption); -} - ImageDecoderQt::ImageDecoderQt(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption) : ImageDecoder(alphaOption, gammaAndColorProfileOption) , m_repetitionCount(cAnimationNone) @@ -129,7 +118,7 @@ int ImageDecoderQt::repetitionCount() const String ImageDecoderQt::filenameExtension() const { return String(m_format.constData(), m_format.length()); -}; +} ImageFrame* ImageDecoderQt::frameBufferAtIndex(size_t index) { @@ -167,6 +156,12 @@ void ImageDecoderQt::internalDecodeSize() } setSize(size.width(), size.height()); + + // We don't need the tables set by prepareScaleDataIfNecessary, + // but their dimensions are used by ImageDecoder::scaledSize(). + prepareScaleDataIfNecessary(); + if (m_scaled) + m_reader->setScaledSize(scaledSize()); } void ImageDecoderQt::internalReadImage(size_t frameIndex) @@ -194,21 +189,44 @@ void ImageDecoderQt::internalReadImage(size_t frameIndex) bool ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex) { - QPixmap pixmap = QPixmap::fromImageReader(m_reader.get()); + ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; + QSize imageSize = m_reader->scaledSize(); + if (imageSize.isEmpty()) + imageSize = m_reader->size(); + + if (!buffer->setSize(imageSize.width(), imageSize.height())) + return false; + + QImage image(reinterpret_cast<uchar*>(buffer->getAddr(0, 0)), imageSize.width(), imageSize.height(), sizeof(ImageFrame::PixelData) * imageSize.width(), m_reader->imageFormat()); + + buffer->setDuration(m_reader->nextImageDelay()); + m_reader->read(&image); + + // ImageFrame expects ARGB32. + if (buffer->premultiplyAlpha()) { + if (image.format() != QImage::Format_ARGB32_Premultiplied) + image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + } else { + if (image.format() != QImage::Format_ARGB32) + image = image.convertToFormat(QImage::Format_ARGB32); + } + + if (reinterpret_cast<const uchar*>(image.constBits()) != reinterpret_cast<const uchar*>(buffer->getAddr(0, 0))) { + // The in-buffer was replaced during decoding with another, so copy into it manually. + memcpy(buffer->getAddr(0, 0), image.constBits(), image.byteCount()); + } - if (pixmap.isNull()) { + if (image.isNull()) { frameCount(); repetitionCount(); clearPointers(); return false; } - // now into the ImageFrame - even if the image is not - ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; - buffer->setOriginalFrameRect(m_reader->currentImageRect()); + buffer->setOriginalFrameRect(image.rect()); + buffer->setHasAlpha(image.hasAlphaChannel()); buffer->setStatus(ImageFrame::FrameComplete); - buffer->setDuration(m_reader->nextImageDelay()); - buffer->setPixmap(pixmap); + return true; } @@ -245,6 +263,20 @@ void ImageDecoderQt::clearPointers() m_reader.clear(); m_buffer.clear(); } + +NativeImagePtr ImageFrame::asNewNativeImage() const +{ + QImage::Format format; + if (m_hasAlpha) + format = m_premultiplyAlpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_ARGB32; + else + format = QImage::Format_RGB32; + + QImage img(reinterpret_cast<uchar*>(m_bytes), m_size.width(), m_size.height(), sizeof(PixelData) * m_size.width(), format); + + return new QPixmap(QPixmap::fromImage(img)); +} + } // vim: ts=4 sw=4 et diff --git a/Source/WebCore/platform/graphics/qt/ImageQt.cpp b/Source/WebCore/platform/graphics/qt/ImageQt.cpp index 182b36684..849435f63 100644 --- a/Source/WebCore/platform/graphics/qt/ImageQt.cpp +++ b/Source/WebCore/platform/graphics/qt/ImageQt.cpp @@ -132,9 +132,15 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const if (!framePixmap) // If it's too early we won't have an image yet. return; +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + FloatRect tileRectAdjusted = adjustSourceRectForDownSampling(tileRect, framePixmap->size()); +#else + FloatRect tileRectAdjusted = tileRect; +#endif + // Qt interprets 0 width/height as full width/height so just short circuit. QRectF dr = QRectF(destRect).normalized(); - QRect tr = QRectF(tileRect).toRect().normalized(); + QRect tr = QRectF(tileRectAdjusted).toRect().normalized(); if (!dr.width() || !dr.height() || !tr.width() || !tr.height()) return; @@ -239,6 +245,10 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, return; } +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + normalizedSrc = adjustSourceRectForDownSampling(normalizedSrc, image->size()); +#endif + CompositeOperator previousOperator = ctxt->compositeOperation(); ctxt->setCompositeOperation(!image->hasAlpha() && op == CompositeSourceOver ? CompositeCopy : op); diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp index 9529cd47a..3a307cb27 100644 --- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp +++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp @@ -116,6 +116,7 @@ MediaPlayerPrivateQt::MediaPlayerPrivateQt(MediaPlayer* player) , m_isSeeking(false) , m_composited(false) , m_preload(MediaPlayer::Auto) + , m_bytesLoadedAtLastDidLoadingProgress(0) , m_suppressNextPlaybackChanged(false) { m_mediaPlayer->setVideoOutput(m_videoItem); @@ -361,13 +362,17 @@ float MediaPlayerPrivateQt::maxTimeSeekable() const return static_cast<float>(m_mediaPlayerControl->availablePlaybackRanges().latestTime()) / 1000.0f; } -unsigned MediaPlayerPrivateQt::bytesLoaded() const +bool MediaPlayerPrivateQt::didLoadingProgress() const { + unsigned bytesLoaded = 0; QLatin1String bytesLoadedKey("bytes-loaded"); if (m_mediaPlayer->availableExtendedMetaData().contains(bytesLoadedKey)) - return m_mediaPlayer->extendedMetaData(bytesLoadedKey).toInt(); - - return m_mediaPlayer->bufferStatus(); + bytesLoaded = m_mediaPlayer->extendedMetaData(bytesLoadedKey).toInt(); + else + bytesLoaded = m_mediaPlayer->bufferStatus(); + bool didLoadingProgress = bytesLoaded != m_bytesLoadedAtLastDidLoadingProgress; + m_bytesLoadedAtLastDidLoadingProgress = bytesLoaded; + return didLoadingProgress; } unsigned MediaPlayerPrivateQt::totalBytes() const diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h index 67f64c74b..c6fcbd838 100644 --- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h +++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h @@ -86,7 +86,7 @@ public: PassRefPtr<TimeRanges> buffered() const; float maxTimeSeekable() const; - unsigned bytesLoaded() const; + bool didLoadingProgress() const; unsigned totalBytes() const; void setVisible(bool); @@ -156,6 +156,7 @@ private: bool m_isSeeking; bool m_composited; MediaPlayer::Preload m_preload; + mutable unsigned m_bytesLoadedAtLastDidLoadingProgress; bool m_delayingLoad; String m_mediaUrl; bool m_suppressNextPlaybackChanged; diff --git a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp index 1bcd6c05b..4c01f1dac 100644 --- a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp +++ b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp @@ -148,7 +148,7 @@ void SimpleFontData::platformInit() float spaceWidth = fm.width(QLatin1Char(' ')); #endif -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +#if !HAVE(QT5) // Qt subtracts 1 from the descent to account for the baseline, // we add it back here to get correct metrics for WebKit. descent += 1; diff --git a/Source/WebCore/platform/graphics/skia/PathSkia.cpp b/Source/WebCore/platform/graphics/skia/PathSkia.cpp index 0ba6d070e..8795b4c3c 100644 --- a/Source/WebCore/platform/graphics/skia/PathSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/PathSkia.cpp @@ -53,6 +53,13 @@ Path::Path(const Path& other) m_path = new SkPath(*other.m_path); } +#if PLATFORM(BLACKBERRY) +Path::Path(const SkPath& path) +{ + m_path = new SkPath(path); +} +#endif + Path::~Path() { delete m_path; diff --git a/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp b/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp index b43a1012e..018a89c9b 100644 --- a/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp +++ b/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp @@ -46,6 +46,11 @@ uint32_t GraphicsSurface::exportToken() return platformExport(); } +uint32_t GraphicsSurface::getTextureID() +{ + return platformGetTextureID(); +} + PassOwnPtr<GraphicsContext> GraphicsSurface::beginPaint(const IntRect& rect, LockOptions lockOptions) { int stride = 0; @@ -59,6 +64,11 @@ void GraphicsSurface::copyToGLTexture(uint32_t target, uint32_t texture, const I platformCopyToGLTexture(target, texture, targetRect, offset); } +void GraphicsSurface::copyFromFramebuffer(uint32_t fbo, const IntRect& sourceRect) +{ + platformCopyFromFramebuffer(fbo, sourceRect); +} + GraphicsSurface::GraphicsSurface(const IntSize& size, Flags flags) : m_size(size) , m_flags(flags) diff --git a/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h b/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h index da941d497..96b1c15a1 100644 --- a/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h +++ b/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h @@ -64,7 +64,9 @@ public: static PassRefPtr<GraphicsSurface> create(const IntSize&, Flags); static PassRefPtr<GraphicsSurface> create(const IntSize&, Flags, uint32_t token); void copyToGLTexture(uint32_t target, uint32_t texture, const IntRect& targetRect, const IntPoint& sourceOffset); + void copyFromFramebuffer(uint32_t fbo, const IntRect& sourceRect); uint32_t exportToken(); + uint32_t getTextureID(); PassOwnPtr<GraphicsContext> beginPaint(const IntRect&, LockOptions); PassRefPtr<Image> createReadOnlyImage(const IntRect&); @@ -74,9 +76,11 @@ protected: uint32_t platformExport(); void platformDestroy(); + uint32_t platformGetTextureID(); char* platformLock(const IntRect&, int* stride, LockOptions); void platformUnlock(); void platformCopyToGLTexture(uint32_t target, uint32_t texture, const IntRect&, const IntPoint&); + void platformCopyFromFramebuffer(uint32_t fbo, const IntRect& sourceRect); PassOwnPtr<GraphicsContext> platformBeginPaint(const IntSize&, char* bits, int stride); diff --git a/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp b/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp index b6a1a0202..a8fe4ddc2 100644 --- a/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp +++ b/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp @@ -64,6 +64,13 @@ static uint32_t createTexture(IOSurfaceRef handle) return texture; } +uint32_t GraphicsSurface::platformGetTextureID() +{ + if (!m_texture) + m_texture = createTexture(m_platformSurface); + return m_texture; +} + void GraphicsSurface::platformCopyToGLTexture(uint32_t target, uint32_t id, const IntRect& targetRect, const IntPoint& offset) { glPushAttrib(GL_ALL_ATTRIB_BITS); @@ -83,6 +90,28 @@ void GraphicsSurface::platformCopyToGLTexture(uint32_t target, uint32_t id, cons glPopAttrib(); } +void GraphicsSurface::platformCopyFromFramebuffer(uint32_t originFbo, const IntRect& sourceRect) +{ + glPushAttrib(GL_ALL_ATTRIB_BITS); + if (!m_texture) + m_texture = createTexture(m_platformSurface); + if (!m_fbo) + glGenFramebuffers(1, &m_fbo); + GLint oldFBO; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO); + glEnable(GL_TEXTURE_RECTANGLE_ARB); + glBindFramebuffer(GL_READ_FRAMEBUFFER, originFbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, m_texture, 0); + glBlitFramebuffer(0, 0, sourceRect.width(), sourceRect.height(), 0, sourceRect.height(), sourceRect.width(), 0, GL_COLOR_BUFFER_BIT, GL_LINEAR); // Flip the texture upside down. + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, 0, 0); + glBindFramebuffer(GL_FRAMEBUFFER, oldFBO); + glPopAttrib(); + + // Flushing the gl command buffer is necessary to ensure the texture has correctly been bound to the IOSurface. + glFlush(); +} + bool GraphicsSurface::platformCreate(const IntSize& size, Flags flags) { unsigned pixelFormat = 'BGRA'; diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.h b/Source/WebCore/platform/graphics/texmap/TextureMapper.h index 2907d1ac8..12498ecc3 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapper.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.h @@ -25,7 +25,7 @@ #if PLATFORM(QT) #include <qglobal.h> -#if defined(QT_OPENGL_LIB) || (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) +#if defined(QT_OPENGL_LIB) || HAVE(QT5) #if defined(QT_OPENGL_ES_2) && !defined(TEXMAP_OPENGL_ES_2) #define TEXMAP_OPENGL_ES_2 #endif diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp index 0f7652cd4..660334a67 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp @@ -505,7 +505,7 @@ void BitmapTextureGL::updateContents(Image* image, const IntRect& targetRect, co #if PLATFORM(QT) QImage qtImage; -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) // With QPA, we can avoid a deep copy. qtImage = *frameImage->handle()->buffer(); #else diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp index 1cc0a220e..8e6c14e5f 100644 --- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp +++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp @@ -727,15 +727,13 @@ TransformationMatrix& TransformationMatrix::scale3d(double sx, double sy, double TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double z, double angle) { - // angles are in degrees. Switch to radians + // Angles are in degrees. Switch to radians. angle = deg2rad(angle); + + double sinTheta = sin(angle); + double cosTheta = cos(angle); - angle /= 2.0f; - double sinA = sin(angle); - double cosA = cos(angle); - double sinA2 = sinA * sinA; - - // normalize + // Normalize the axis of rotation double length = sqrt(x * x + y * y + z * z); if (length == 0) { // bad vector, just use something reasonable @@ -750,39 +748,39 @@ TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double TransformationMatrix mat; - // optimize case where axis is along major axis + // Optimize cases where the axis is along a major axis if (x == 1.0f && y == 0.0f && z == 0.0f) { mat.m_matrix[0][0] = 1.0f; mat.m_matrix[0][1] = 0.0f; mat.m_matrix[0][2] = 0.0f; mat.m_matrix[1][0] = 0.0f; - mat.m_matrix[1][1] = 1.0f - 2.0f * sinA2; - mat.m_matrix[1][2] = 2.0f * sinA * cosA; + mat.m_matrix[1][1] = cosTheta; + mat.m_matrix[1][2] = sinTheta; mat.m_matrix[2][0] = 0.0f; - mat.m_matrix[2][1] = -2.0f * sinA * cosA; - mat.m_matrix[2][2] = 1.0f - 2.0f * sinA2; + mat.m_matrix[2][1] = -sinTheta; + mat.m_matrix[2][2] = cosTheta; mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f; mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f; mat.m_matrix[3][3] = 1.0f; } else if (x == 0.0f && y == 1.0f && z == 0.0f) { - mat.m_matrix[0][0] = 1.0f - 2.0f * sinA2; + mat.m_matrix[0][0] = cosTheta; mat.m_matrix[0][1] = 0.0f; - mat.m_matrix[0][2] = -2.0f * sinA * cosA; + mat.m_matrix[0][2] = -sinTheta; mat.m_matrix[1][0] = 0.0f; mat.m_matrix[1][1] = 1.0f; mat.m_matrix[1][2] = 0.0f; - mat.m_matrix[2][0] = 2.0f * sinA * cosA; + mat.m_matrix[2][0] = sinTheta; mat.m_matrix[2][1] = 0.0f; - mat.m_matrix[2][2] = 1.0f - 2.0f * sinA2; + mat.m_matrix[2][2] = cosTheta; mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f; mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f; mat.m_matrix[3][3] = 1.0f; } else if (x == 0.0f && y == 0.0f && z == 1.0f) { - mat.m_matrix[0][0] = 1.0f - 2.0f * sinA2; - mat.m_matrix[0][1] = 2.0f * sinA * cosA; + mat.m_matrix[0][0] = cosTheta; + mat.m_matrix[0][1] = sinTheta; mat.m_matrix[0][2] = 0.0f; - mat.m_matrix[1][0] = -2.0f * sinA * cosA; - mat.m_matrix[1][1] = 1.0f - 2.0f * sinA2; + mat.m_matrix[1][0] = -sinTheta; + mat.m_matrix[1][1] = cosTheta; mat.m_matrix[1][2] = 0.0f; mat.m_matrix[2][0] = 0.0f; mat.m_matrix[2][1] = 0.0f; @@ -791,19 +789,23 @@ TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f; mat.m_matrix[3][3] = 1.0f; } else { - double x2 = x*x; - double y2 = y*y; - double z2 = z*z; - - mat.m_matrix[0][0] = 1.0f - 2.0f * (y2 + z2) * sinA2; - mat.m_matrix[0][1] = 2.0f * (x * y * sinA2 + z * sinA * cosA); - mat.m_matrix[0][2] = 2.0f * (x * z * sinA2 - y * sinA * cosA); - mat.m_matrix[1][0] = 2.0f * (y * x * sinA2 - z * sinA * cosA); - mat.m_matrix[1][1] = 1.0f - 2.0f * (z2 + x2) * sinA2; - mat.m_matrix[1][2] = 2.0f * (y * z * sinA2 + x * sinA * cosA); - mat.m_matrix[2][0] = 2.0f * (z * x * sinA2 + y * sinA * cosA); - mat.m_matrix[2][1] = 2.0f * (z * y * sinA2 - x * sinA * cosA); - mat.m_matrix[2][2] = 1.0f - 2.0f * (x2 + y2) * sinA2; + // This case is the rotation about an arbitrary unit vector. + // + // Formula is adapted from Wikipedia article on Rotation matrix, + // http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle + // + // An alternate resource with the same matrix: http://www.fastgraph.com/makegames/3drotation/ + // + double oneMinusCosTheta = 1 - cosTheta; + mat.m_matrix[0][0] = cosTheta + x * x * oneMinusCosTheta; + mat.m_matrix[0][1] = y * x * oneMinusCosTheta + z * sinTheta; + mat.m_matrix[0][2] = z * x * oneMinusCosTheta - y * sinTheta; + mat.m_matrix[1][0] = x * y * oneMinusCosTheta - z * sinTheta; + mat.m_matrix[1][1] = cosTheta + y * y * oneMinusCosTheta; + mat.m_matrix[1][2] = z * y * oneMinusCosTheta + x * sinTheta; + mat.m_matrix[2][0] = x * z * oneMinusCosTheta + y * sinTheta; + mat.m_matrix[2][1] = y * z * oneMinusCosTheta - x * sinTheta; + mat.m_matrix[2][2] = cosTheta + z * z * oneMinusCosTheta; mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f; mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f; mat.m_matrix[3][3] = 1.0f; @@ -814,23 +816,21 @@ TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, double rz) { - // angles are in degrees. Switch to radians + // Angles are in degrees. Switch to radians. rx = deg2rad(rx); ry = deg2rad(ry); rz = deg2rad(rz); TransformationMatrix mat; - rz /= 2.0f; - double sinA = sin(rz); - double cosA = cos(rz); - double sinA2 = sinA * sinA; + double sinTheta = sin(rz); + double cosTheta = cos(rz); - mat.m_matrix[0][0] = 1.0f - 2.0f * sinA2; - mat.m_matrix[0][1] = 2.0f * sinA * cosA; + mat.m_matrix[0][0] = cosTheta; + mat.m_matrix[0][1] = sinTheta; mat.m_matrix[0][2] = 0.0f; - mat.m_matrix[1][0] = -2.0f * sinA * cosA; - mat.m_matrix[1][1] = 1.0f - 2.0f * sinA2; + mat.m_matrix[1][0] = -sinTheta; + mat.m_matrix[1][1] = cosTheta; mat.m_matrix[1][2] = 0.0f; mat.m_matrix[2][0] = 0.0f; mat.m_matrix[2][1] = 0.0f; @@ -841,44 +841,40 @@ TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, doubl TransformationMatrix rmat(mat); - ry /= 2.0f; - sinA = sin(ry); - cosA = cos(ry); - sinA2 = sinA * sinA; + sinTheta = sin(ry); + cosTheta = cos(ry); - mat.m_matrix[0][0] = 1.0f - 2.0f * sinA2; + mat.m_matrix[0][0] = cosTheta; mat.m_matrix[0][1] = 0.0f; - mat.m_matrix[0][2] = -2.0f * sinA * cosA; + mat.m_matrix[0][2] = -sinTheta; mat.m_matrix[1][0] = 0.0f; mat.m_matrix[1][1] = 1.0f; mat.m_matrix[1][2] = 0.0f; - mat.m_matrix[2][0] = 2.0f * sinA * cosA; + mat.m_matrix[2][0] = sinTheta; mat.m_matrix[2][1] = 0.0f; - mat.m_matrix[2][2] = 1.0f - 2.0f * sinA2; + mat.m_matrix[2][2] = cosTheta; mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f; mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f; mat.m_matrix[3][3] = 1.0f; - + rmat.multiply(mat); - rx /= 2.0f; - sinA = sin(rx); - cosA = cos(rx); - sinA2 = sinA * sinA; + sinTheta = sin(rx); + cosTheta = cos(rx); mat.m_matrix[0][0] = 1.0f; mat.m_matrix[0][1] = 0.0f; mat.m_matrix[0][2] = 0.0f; mat.m_matrix[1][0] = 0.0f; - mat.m_matrix[1][1] = 1.0f - 2.0f * sinA2; - mat.m_matrix[1][2] = 2.0f * sinA * cosA; + mat.m_matrix[1][1] = cosTheta; + mat.m_matrix[1][2] = sinTheta; mat.m_matrix[2][0] = 0.0f; - mat.m_matrix[2][1] = -2.0f * sinA * cosA; - mat.m_matrix[2][2] = 1.0f - 2.0f * sinA2; + mat.m_matrix[2][1] = -sinTheta; + mat.m_matrix[2][2] = cosTheta; mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f; mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f; mat.m_matrix[3][3] = 1.0f; - + rmat.multiply(mat); multiply(rmat); diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp index b0037c3ab..7d9dcafe6 100644 --- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp +++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp @@ -183,6 +183,7 @@ MediaPlayerPrivateQuickTimeVisualContext::MediaPlayerPrivateQuickTimeVisualConte , m_delayingLoad(false) , m_privateBrowsing(false) , m_preload(MediaPlayer::Auto) + , m_maxTimeLoadedAtLastDidLoadingProgress(0) { } @@ -583,15 +584,14 @@ float MediaPlayerPrivateQuickTimeVisualContext::maxTimeLoaded() const return m_movie->maxTimeLoaded(); } -unsigned MediaPlayerPrivateQuickTimeVisualContext::bytesLoaded() const +bool MediaPlayerPrivateQuickTimeVisualContext::didLoadingProgress() const { - if (!m_movie) - return 0; - float dur = duration(); - float maxTime = maxTimeLoaded(); - if (!dur) - return 0; - return totalBytes() * maxTime / dur; + if (!m_movie || !duration()) + return false; + float currentMaxTimeLoaded = maxTimeLoaded(); + bool didLoadingProgress = currentMaxTimeLoaded != m_maxTimeLoadedAtLastDidLoadingProgress; + m_maxTimeLoadedAtLastDidLoadingProgress = currentMaxTimeLoaded; + return didLoadingProgress; } unsigned MediaPlayerPrivateQuickTimeVisualContext::totalBytes() const diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h index 70fd2a5df..4c44af401 100644 --- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h +++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h @@ -99,7 +99,7 @@ private: PassRefPtr<TimeRanges> buffered() const; float maxTimeSeekable() const; - unsigned bytesLoaded() const; + bool didLoadingProgress() const; unsigned totalBytes() const; void setVisible(bool); @@ -201,6 +201,7 @@ private: String m_movieURL; bool m_privateBrowsing; MediaPlayer::Preload m_preload; + mutable float m_maxTimeLoadedAtLastDidLoadingProgress; #if DRAW_FRAME_RATE double m_frameCountWhilePlaying; double m_timeStartedPlaying; diff --git a/Source/WebCore/platform/graphics/wince/FontWinCE.cpp b/Source/WebCore/platform/graphics/wince/FontWinCE.cpp index c0a1eb2be..b46bf1170 100644 --- a/Source/WebCore/platform/graphics/wince/FontWinCE.cpp +++ b/Source/WebCore/platform/graphics/wince/FontWinCE.cpp @@ -85,13 +85,15 @@ public: }; TextRunComponent::TextRunComponent(const UChar *start, int length, const TextRun& parentTextRun, const Font &font, int o) - : m_textRun(start, length, parentTextRun.allowTabs(), 0, 0 + : m_textRun(start, length, 0, 0 , parentTextRun.allowsTrailingExpansion() ? TextRun::AllowTrailingExpansion : TextRun::ForbidTrailingExpansion , parentTextRun.direction() , parentTextRun.directionalOverride()) , m_offset(o) , m_spaces(0) { + m_textRun.setTabSize(parentTextRun.allowTabs(), parentTextRun.tabSize()); + WidthIterator it(&font, m_textRun); it.advance(m_textRun.length(), 0); m_width = it.m_runWidthSoFar; diff --git a/Source/WebCore/platform/graphics/wince/MediaPlayerPrivateWinCE.h b/Source/WebCore/platform/graphics/wince/MediaPlayerPrivateWinCE.h index 862937357..0faa04578 100644 --- a/Source/WebCore/platform/graphics/wince/MediaPlayerPrivateWinCE.h +++ b/Source/WebCore/platform/graphics/wince/MediaPlayerPrivateWinCE.h @@ -70,6 +70,7 @@ namespace WebCore { PassRefPtr<TimeRanges> buffered() const; float maxTimeSeekable() const; + // FIXME: bytesLoaded() should be replaced with didLoadingProgress() (by somebody who can find the implementation of this class). unsigned bytesLoaded() const; unsigned totalBytes() const; diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp index 3db393aef..02aa68c74 100644 --- a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp @@ -20,21 +20,23 @@ */ #include "config.h" - #include "ImageDecoder.h" -#include <algorithm> -#include <cmath> - #include "BMPImageDecoder.h" #include "GIFImageDecoder.h" #include "ICOImageDecoder.h" +#if PLATFORM(QT) +#include "ImageDecoderQt.h" +#endif #include "JPEGImageDecoder.h" #include "PNGImageDecoder.h" +#include "SharedBuffer.h" #if USE(WEBP) #include "WEBPImageDecoder.h" #endif -#include "SharedBuffer.h" + +#include <algorithm> +#include <cmath> using namespace std; @@ -107,11 +109,18 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaO if (matchesGIFSignature(contents)) return new GIFImageDecoder(alphaOption, gammaAndColorProfileOption); +#if !PLATFORM(QT) || (PLATFORM(QT) && HAVE(LIBPNG)) if (matchesPNGSignature(contents)) return new PNGImageDecoder(alphaOption, gammaAndColorProfileOption); + if (matchesICOSignature(contents) || matchesCURSignature(contents)) + return new ICOImageDecoder(alphaOption, gammaAndColorProfileOption); +#endif + +#if !PLATFORM(QT) || (PLATFORM(QT) && HAVE(LIBJPEG)) if (matchesJPEGSignature(contents)) return new JPEGImageDecoder(alphaOption, gammaAndColorProfileOption); +#endif #if USE(WEBP) if (matchesWebPSignature(contents)) @@ -121,9 +130,9 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaO if (matchesBMPSignature(contents)) return new BMPImageDecoder(alphaOption, gammaAndColorProfileOption); - if (matchesICOSignature(contents) || matchesCURSignature(contents)) - return new ICOImageDecoder(alphaOption, gammaAndColorProfileOption); - +#if PLATFORM(QT) + return new ImageDecoderQt(alphaOption, gammaAndColorProfileOption); +#endif return 0; } diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.h b/Source/WebCore/platform/image-decoders/ImageDecoder.h index 6ae738a3b..a6bc188e5 100644 --- a/Source/WebCore/platform/image-decoders/ImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/ImageDecoder.h @@ -40,9 +40,6 @@ #if USE(SKIA) #include "NativeImageSkia.h" #include "SkColorPriv.h" -#elif PLATFORM(QT) -#include <QPixmap> -#include <QImage> #endif namespace WebCore { @@ -64,7 +61,7 @@ namespace WebCore { DisposeOverwritePrevious // Clear frame to previous framebuffer // contents }; -#if USE(SKIA) || (PLATFORM(QT) && USE(QT_IMAGE_DECODER)) +#if USE(SKIA) typedef uint32_t PixelData; #else typedef unsigned PixelData; @@ -136,19 +133,10 @@ namespace WebCore { { #if USE(SKIA) return m_bitmap.bitmap().getAddr32(x, y); -#elif PLATFORM(QT) && USE(QT_IMAGE_DECODER) - m_image = m_pixmap.toImage(); - m_pixmap = QPixmap(); - return reinterpret_cast_ptr<QRgb*>(m_image.scanLine(y)) + x; #else return m_bytes + (y * width()) + x; #endif } - -#if PLATFORM(QT) && USE(QT_IMAGE_DECODER) - void setPixmap(const QPixmap& pixmap); -#endif - private: int width() const; int height() const; @@ -180,11 +168,6 @@ namespace WebCore { #if PLATFORM(CHROMIUM) && OS(DARWIN) ColorProfile m_colorProfile; #endif -#elif PLATFORM(QT) && USE(QT_IMAGE_DECODER) - mutable QPixmap m_pixmap; - mutable QImage m_image; - bool m_hasAlpha; - IntSize m_size; #else Vector<PixelData> m_backingStore; PixelData* m_bytes; // The memory is backed by m_backingStore. diff --git a/Source/WebCore/platform/image-decoders/qt/ImageFrameQt.cpp b/Source/WebCore/platform/image-decoders/qt/ImageFrameQt.cpp deleted file mode 100644 index 999ac2903..000000000 --- a/Source/WebCore/platform/image-decoders/qt/ImageFrameQt.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2008, 2009 Google, Inc. - * Copyright (C) 2009 Holger Hans Peter Freyther - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ImageDecoder.h" - -#include "NotImplemented.h" - -namespace WebCore { - -#if USE(QT_IMAGE_DECODER) - -ImageFrame::ImageFrame() - : m_hasAlpha(false) - , m_size() - , m_status(FrameEmpty) - , m_duration(0) - , m_disposalMethod(DisposeNotSpecified) - , m_premultiplyAlpha(true) -{ -} - -ImageFrame& ImageFrame::operator=(const ImageFrame& other) -{ - if (this == &other) - return *this; - - copyBitmapData(other); - setOriginalFrameRect(other.originalFrameRect()); - setStatus(other.status()); - setDuration(other.duration()); - setDisposalMethod(other.disposalMethod()); - setPremultiplyAlpha(other.premultiplyAlpha()); - return *this; -} - -void ImageFrame::clearPixelData() -{ - m_pixmap = QPixmap(); - m_image = QImage(); - m_status = FrameEmpty; - // NOTE: Do not reset other members here; clearFrameBufferCache() - // calls this to free the bitmap data, but other functions like - // initFrameBuffer() and frameComplete() may still need to read - // other metadata out of this frame later. -} - -void ImageFrame::zeroFillPixelData() -{ - if (m_pixmap.isNull() && !m_image.isNull()) { - m_pixmap = QPixmap(m_image.width(), m_image.height()); - m_image = QImage(); - } - m_pixmap.fill(QColor(0, 0, 0, 0)); -} - -bool ImageFrame::copyBitmapData(const ImageFrame& other) -{ - if (this == &other) - return true; - - m_image = other.m_image; - m_pixmap = other.m_pixmap; - m_size = other.m_size; - m_hasAlpha = other.m_hasAlpha; - return true; -} - -bool ImageFrame::setSize(int newWidth, int newHeight) -{ - // setSize() should only be called once, it leaks memory otherwise. - ASSERT(!width() && !height()); - - m_size = IntSize(newWidth, newHeight); - m_image = QImage(); - m_pixmap = QPixmap(newWidth, newHeight); - if (m_pixmap.isNull()) - return false; - - zeroFillPixelData(); - return true; -} - -QPixmap* ImageFrame::asNewNativeImage() const -{ - if (m_pixmap.isNull() && !m_image.isNull()) { - m_pixmap = QPixmap::fromImage(m_image); - m_image = QImage(); - } - return new QPixmap(m_pixmap); -} - -bool ImageFrame::hasAlpha() const -{ - return m_hasAlpha; -} - -void ImageFrame::setHasAlpha(bool alpha) -{ - m_hasAlpha = alpha; -} - -void ImageFrame::setColorProfile(const ColorProfile& colorProfile) -{ - notImplemented(); -} - -void ImageFrame::setStatus(FrameStatus status) -{ - m_status = status; -} - -// The image must not have format 8888 pre multiplied... -void ImageFrame::setPixmap(const QPixmap& pixmap) -{ - m_pixmap = pixmap; - m_image = QImage(); - m_size = pixmap.size(); - m_hasAlpha = pixmap.hasAlphaChannel(); -} - -int ImageFrame::width() const -{ - return m_size.width(); -} - -int ImageFrame::height() const -{ - return m_size.height(); -} - -#else - -QPixmap* ImageFrame::asNewNativeImage() const -{ - QImage::Format fmt; - if (m_hasAlpha) - fmt = m_premultiplyAlpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_ARGB32; - else - fmt = QImage::Format_RGB32; - - QImage img(reinterpret_cast<uchar*>(m_bytes), m_size.width(), m_size.height(), sizeof(PixelData) * m_size.width(), fmt); - - return new QPixmap(QPixmap::fromImage(img)); -} - -#endif // USE(QT_IMAGE_DECODER) - -} diff --git a/Source/WebCore/platform/network/blackberry/NetworkJob.cpp b/Source/WebCore/platform/network/blackberry/NetworkJob.cpp index 1e811961b..d5436163c 100644 --- a/Source/WebCore/platform/network/blackberry/NetworkJob.cpp +++ b/Source/WebCore/platform/network/blackberry/NetworkJob.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2010, 2011 Research In Motion Limited. All rights reserved. + * Copyright (C) 2009, 2010, 2011, 2012 Research In Motion Limited. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -208,6 +208,13 @@ void NetworkJob::handleNotifyStatusReceived(int status, const String& message) m_response.setHTTPStatusCode(status); m_response.setHTTPStatusText(message); + + if (!isError(m_extendedStatusCode)) + storeCredentials(); + else if (isUnauthorized(m_extendedStatusCode)) { + purgeCredentials(); + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "Authentication failed, purge the stored credentials for this site."); + } } void NetworkJob::notifyHeadersReceived(BlackBerry::Platform::NetworkRequest::HeaderList& headers) @@ -247,6 +254,36 @@ void NetworkJob::notifyMultipartHeaderReceived(const char* key, const char* valu handleNotifyMultipartHeaderReceived(key, value); } +void NetworkJob::notifyAuthReceived(BlackBerry::Platform::NetworkRequest::AuthType authType, const char* realm) +{ + using BlackBerry::Platform::NetworkRequest; + + ProtectionSpaceServerType serverType = ProtectionSpaceServerHTTP; + ProtectionSpaceAuthenticationScheme scheme = ProtectionSpaceAuthenticationSchemeDefault; + switch (authType) { + case NetworkRequest::AuthHTTPBasic: + scheme = ProtectionSpaceAuthenticationSchemeHTTPBasic; + break; + case NetworkRequest::AuthHTTPDigest: + scheme = ProtectionSpaceAuthenticationSchemeHTTPDigest; + break; + case NetworkRequest::AuthHTTPNTLM: + scheme = ProtectionSpaceAuthenticationSchemeNTLM; + break; + case NetworkRequest::AuthFTP: + serverType = ProtectionSpaceServerFTP; + break; + case NetworkRequest::AuthProxy: + serverType = ProtectionSpaceProxyHTTP; + break; + case NetworkRequest::AuthNone: + default: + return; + } + + sendRequestWithCredentials(serverType, scheme, realm); +} + void NetworkJob::notifyStringHeaderReceived(const String& key, const String& value) { if (shouldDeferLoading()) @@ -279,11 +316,7 @@ void NetworkJob::handleNotifyHeaderReceived(const String& key, const String& val m_response.setHTTPHeaderField(key, m_response.httpHeaderField(key) + "\r\n" + value); return; } - } else if (m_extendedStatusCode == 401 && lowerKey == "www-authenticate") - handleAuthHeader(ProtectionSpaceServerHTTP, value); - else if (m_extendedStatusCode == 407 && lowerKey == "proxy-authenticate" && !BlackBerry::Platform::Client::get()->getProxyAddress().empty()) - handleAuthHeader(ProtectionSpaceProxyHTTP, value); - else if (equalIgnoringCase(key, BlackBerry::Platform::NetworkRequest::HEADER_BLACKBERRY_FTP)) + } else if (equalIgnoringCase(key, BlackBerry::Platform::NetworkRequest::HEADER_BLACKBERRY_FTP)) handleFTPHeader(value); m_response.setHTTPHeaderField(key, value); @@ -441,14 +474,6 @@ void NetworkJob::handleNotifyClose(int status) notifyStatusReceived(BlackBerry::Platform::FilterStream::StatusNetworkError, 0); } - // If an HTTP authentication-enabled request is successful, save - // the credentials for later reuse. If the request fails, delete - // the saved credentials. - if (!isError(m_extendedStatusCode)) - storeCredentials(); - else if (isUnauthorized(m_extendedStatusCode)) - purgeCredentials(); - if (shouldReleaseClientResource()) { if (isRedirect(m_extendedStatusCode) && (m_redirectCount >= s_redirectMaximum)) m_extendedStatusCode = BlackBerry::Platform::FilterStream::StatusTooManyRedirects; @@ -528,8 +553,7 @@ bool NetworkJob::startNewJobWithRequest(ResourceRequest& newRequest, bool increa // Pass the ownership of the ResourceHandle to the new NetworkJob. RefPtr<ResourceHandle> handle = m_handle; - m_handle = 0; - m_multipartResponse = nullptr; + cancelJob(); NetworkManager::instance()->startJob(m_playerId, m_pageGroupName, @@ -649,62 +673,6 @@ void NetworkJob::sendMultipartResponseIfNeeded() } } -bool NetworkJob::handleAuthHeader(const ProtectionSpaceServerType space, const String& header) -{ - if (!m_handle) - return false; - - if (!m_handle->getInternal()->m_currentWebChallenge.isNull()) - return false; - - if (header.isEmpty()) - return false; - - if (equalIgnoringCase(header, "ntlm")) - sendRequestWithCredentials(space, ProtectionSpaceAuthenticationSchemeNTLM, "NTLM"); - - // Extract the auth scheme and realm from the header. - size_t spacePos = header.find(' '); - if (spacePos == notFound) { - LOG(Network, "%s-Authenticate field '%s' badly formatted: missing scheme.", space == ProtectionSpaceServerHTTP ? "WWW" : "Proxy", header.utf8().data()); - return false; - } - - String scheme = header.left(spacePos); - - ProtectionSpaceAuthenticationScheme protectionSpaceScheme = ProtectionSpaceAuthenticationSchemeDefault; - if (equalIgnoringCase(scheme, "basic")) - protectionSpaceScheme = ProtectionSpaceAuthenticationSchemeHTTPBasic; - else if (equalIgnoringCase(scheme, "digest")) - protectionSpaceScheme = ProtectionSpaceAuthenticationSchemeHTTPDigest; - else { - notImplemented(); - return false; - } - - size_t realmPos = header.findIgnoringCase("realm=", spacePos); - if (realmPos == notFound) { - LOG(Network, "%s-Authenticate field '%s' badly formatted: missing realm.", space == ProtectionSpaceServerHTTP ? "WWW" : "Proxy", header.utf8().data()); - return false; - } - size_t beginPos = realmPos + 6; - String realm = header.right(header.length() - beginPos); - if (realm.startsWith("\"")) { - beginPos += 1; - size_t endPos = header.find("\"", beginPos); - if (endPos == notFound) { - LOG(Network, "%s-Authenticate field '%s' badly formatted: invalid realm.", space == ProtectionSpaceServerHTTP ? "WWW" : "Proxy", header.utf8().data()); - return false; - } - realm = header.substring(beginPos, endPos - beginPos); - } - - // Get the user's credentials and resend the request. - sendRequestWithCredentials(space, protectionSpaceScheme, realm); - - return true; -} - bool NetworkJob::handleFTPHeader(const String& header) { size_t spacePos = header.find(' '); @@ -761,13 +729,18 @@ bool NetworkJob::sendRequestWithCredentials(ProtectionSpaceServerType type, Prot m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError()); m_handle->getInternal()->m_currentWebChallenge.setStored(true); } else { + if (m_handle->firstRequest().targetType() == ResourceRequest::TargetIsFavicon) { + // The favicon loading is triggerred after the main resource has been loaded + // and parsed, so if we cancel the authentication challenge when loading the main + // resource, we should also cancel loading the favicon when it starts to + // load. If not we will receive another challenge which may confuse the user. + return false; + } + // CredentialStore is empty. Ask the user via dialog. String username; String password; - if (!m_frame || !m_frame->loader() || !m_frame->loader()->client()) - return false; - if (type == ProtectionSpaceProxyHTTP) { username = BlackBerry::Platform::Client::get()->getProxyUsername().c_str(); password = BlackBerry::Platform::Client::get()->getProxyPassword().c_str(); @@ -776,30 +749,27 @@ bool NetworkJob::sendRequestWithCredentials(ProtectionSpaceServerType type, Prot if (username.isEmpty() || password.isEmpty()) { // Before asking the user for credentials, we check if the URL contains that. if (!m_handle->getInternal()->m_user.isEmpty() && !m_handle->getInternal()->m_pass.isEmpty()) { - username = m_handle->getInternal()->m_user.utf8().data(); - password = m_handle->getInternal()->m_pass.utf8().data(); + username = m_handle->getInternal()->m_user; + password = m_handle->getInternal()->m_pass; // Prevent them from been used again if they are wrong. // If they are correct, they will the put into CredentialStorage. m_handle->getInternal()->m_user = ""; m_handle->getInternal()->m_pass = ""; } else { - Credential inputCredential = m_frame->page()->chrome()->client()->platformPageClient()->authenticationChallenge(newURL, protectionSpace); + Credential inputCredential; + if (!m_frame->page()->chrome()->client()->platformPageClient()->authenticationChallenge(newURL, protectionSpace, inputCredential)) + return false; username = inputCredential.user(); password = inputCredential.password(); } } - if (username.isEmpty() && password.isEmpty()) - return false; - credential = Credential(username, password, CredentialPersistenceForSession); m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError()); } - // FIXME: Resend the resource request. Cloned from handleRedirect(). Not sure - // if we need everything that follows... ResourceRequest newRequest = m_handle->firstRequest(); newRequest.setURL(newURL); newRequest.setMustHandleInternally(true); diff --git a/Source/WebCore/platform/network/blackberry/NetworkJob.h b/Source/WebCore/platform/network/blackberry/NetworkJob.h index 11bd2aa59..a9a7b881b 100644 --- a/Source/WebCore/platform/network/blackberry/NetworkJob.h +++ b/Source/WebCore/platform/network/blackberry/NetworkJob.h @@ -69,6 +69,7 @@ public: virtual void notifyHeadersReceived(BlackBerry::Platform::NetworkRequest::HeaderList& headers); virtual void notifyMultipartHeaderReceived(const char* key, const char* value); // Exists only to resolve ambiguity between char* and String parameters + virtual void notifyAuthReceived(BlackBerry::Platform::NetworkRequest::AuthType, const char* realm); void notifyStringHeaderReceived(const String& key, const String& value); void handleNotifyHeaderReceived(const String& key, const String& value); void handleNotifyMultipartHeaderReceived(const String& key, const String& value); @@ -122,12 +123,10 @@ private: void handleAbout(); - // The server needs authentication credentials. Search in the - // CredentialStorage or prompt the user via dialog. - bool handleAuthHeader(const ProtectionSpaceServerType, const String& header); - bool handleFTPHeader(const String& header); + // The server needs authentication credentials. Search in the CredentialStorage + // or prompt the user via dialog, then resend the request with the credentials. bool sendRequestWithCredentials(ProtectionSpaceServerType, ProtectionSpaceAuthenticationScheme, const String& realm); void storeCredentials(); diff --git a/Source/WebCore/platform/network/blackberry/NetworkManager.cpp b/Source/WebCore/platform/network/blackberry/NetworkManager.cpp index bceb1da18..89d619c8b 100644 --- a/Source/WebCore/platform/network/blackberry/NetworkManager.cpp +++ b/Source/WebCore/platform/network/blackberry/NetworkManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2010, 2011 Research In Motion Limited. All rights reserved. + * Copyright (C) 2009, 2010, 2011, 2012 Research In Motion Limited. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -160,10 +160,10 @@ NetworkJob* NetworkManager::findJobForHandle(PassRefPtr<ResourceHandle> job) { for (unsigned i = 0; i < m_jobs.size(); ++i) { NetworkJob* networkJob = m_jobs[i]; - if (networkJob->handle() == job) { - // We have only one job for one handle. + // We have only one job for one handle (not including cancelled jobs which may hang + // around briefly), so return the first non-cancelled job. + if (!networkJob->isCancelled() && networkJob->handle() == job) return networkJob; - } } return 0; } diff --git a/Source/WebCore/platform/qt/DeviceMotionProviderQt.h b/Source/WebCore/platform/qt/DeviceMotionProviderQt.h index cf3d589e4..18437c626 100644 --- a/Source/WebCore/platform/qt/DeviceMotionProviderQt.h +++ b/Source/WebCore/platform/qt/DeviceMotionProviderQt.h @@ -25,7 +25,7 @@ #include <QAccelerometerFilter> #include <wtf/RefPtr.h> -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +#if !HAVE(QT5) using QTM_NAMESPACE::QAccelerometer; using QTM_NAMESPACE::QAccelerometerFilter; using QTM_NAMESPACE::QAccelerometerReading; diff --git a/Source/WebCore/platform/qt/DeviceOrientationProviderQt.h b/Source/WebCore/platform/qt/DeviceOrientationProviderQt.h index 6d3e19902..c7f6d2337 100644 --- a/Source/WebCore/platform/qt/DeviceOrientationProviderQt.h +++ b/Source/WebCore/platform/qt/DeviceOrientationProviderQt.h @@ -25,7 +25,7 @@ #include <QRotationFilter> #include <wtf/RefPtr.h> -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +#if !HAVE(QT5) using QTM_NAMESPACE::QRotationFilter; using QTM_NAMESPACE::QRotationReading; using QTM_NAMESPACE::QRotationSensor; diff --git a/Source/WebCore/platform/qt/KURLQt.cpp b/Source/WebCore/platform/qt/KURLQt.cpp index 2e75774f8..86e4ab7b6 100644 --- a/Source/WebCore/platform/qt/KURLQt.cpp +++ b/Source/WebCore/platform/qt/KURLQt.cpp @@ -34,7 +34,7 @@ KURL::KURL(const QUrl& url) KURL::operator QUrl() const { -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +#if !HAVE(QT5) QString str = QString::fromRawData(reinterpret_cast<const QChar*>(m_string.characters()), m_string.length()); QByteArray ba = str.toUtf8(); diff --git a/Source/WebCore/platform/qt/PlatformScreenQt.cpp b/Source/WebCore/platform/qt/PlatformScreenQt.cpp index 62dcf501f..8bfbf2625 100644 --- a/Source/WebCore/platform/qt/PlatformScreenQt.cpp +++ b/Source/WebCore/platform/qt/PlatformScreenQt.cpp @@ -38,7 +38,7 @@ #include "NotImplemented.h" #include "Widget.h" #include "QWebPageClient.h" -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) #include <QGuiApplication> #include <QScreen> #else @@ -71,7 +71,7 @@ static int screenNumber(Widget* w) int screenDepth(Widget* w) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) return QGuiApplication::screens().value(screenNumber(w))->depth(); #else return QApplication::desktop()->screen(screenNumber(w))->depth(); @@ -80,7 +80,7 @@ int screenDepth(Widget* w) int screenDepthPerComponent(Widget* w) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) int depth = QGuiApplication::primaryScreen()->depth(); // FIXME: Use widget's screen Q_UNUSED(w); @@ -114,7 +114,7 @@ int screenDepthPerComponent(Widget* w) bool screenIsMonochrome(Widget* w) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) Q_UNUSED(w); // FIXME: In Qt 5 colorCount() isn't even implemented beyond returning 256 :) return false; @@ -125,7 +125,7 @@ bool screenIsMonochrome(Widget* w) FloatRect screenRect(Widget* widget) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) QRect r = QGuiApplication::screens().value(screenNumber(widget))->geometry(); #else QRect r = QApplication::desktop()->screenGeometry(screenNumber(widget)); @@ -135,7 +135,7 @@ FloatRect screenRect(Widget* widget) FloatRect screenAvailableRect(Widget* widget) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) QRect r = QGuiApplication::screens().value(screenNumber(widget))->availableGeometry(); #else QRect r = QApplication::desktop()->availableGeometry(screenNumber(widget)); diff --git a/Source/WebCore/platform/qt/QWebPageClient.h b/Source/WebCore/platform/qt/QWebPageClient.h index 9541c64e2..6c9a1ae6c 100644 --- a/Source/WebCore/platform/qt/QWebPageClient.h +++ b/Source/WebCore/platform/qt/QWebPageClient.h @@ -110,7 +110,7 @@ public: virtual void createPlatformGraphicsContext3D(PlatformGraphicsContext3D*, PlatformGraphicsSurface3D*) = 0; #endif -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) virtual QWindow* ownerWindow() const; #endif diff --git a/Source/WebCore/platform/text/TextCheckerClient.h b/Source/WebCore/platform/text/TextCheckerClient.h index eb95bd1de..803bfb88b 100644 --- a/Source/WebCore/platform/text/TextCheckerClient.h +++ b/Source/WebCore/platform/text/TextCheckerClient.h @@ -31,29 +31,12 @@ #include "TextChecking.h" #include <wtf/Forward.h> +#include <wtf/PassRefPtr.h> #include <wtf/Vector.h> #include <wtf/text/WTFString.h> namespace WebCore { -class SpellChecker; -class TextCheckingRequest; - -struct GrammarDetail { - int location; - int length; - Vector<String> guesses; - String userDescription; -}; - -struct TextCheckingResult { - TextCheckingType type; - int location; - int length; - Vector<GrammarDetail> details; - String replacement; -}; - class TextCheckerClient { public: virtual ~TextCheckerClient() {} @@ -73,7 +56,7 @@ public: // provide more accurate correction suggestions. Caller can pass in more text in "context" to aid such spellcheckers on language // identification. Noramlly it's the text surrounding the "word" for which we are getting correction suggestions. virtual void getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) = 0; - virtual void requestCheckingOfString(SpellChecker*, const TextCheckingRequest&) = 0; + virtual void requestCheckingOfString(PassRefPtr<TextCheckingRequest>) = 0; }; } diff --git a/Source/WebCore/platform/text/TextChecking.h b/Source/WebCore/platform/text/TextChecking.h index be9ed5f9e..0742cb32d 100644 --- a/Source/WebCore/platform/text/TextChecking.h +++ b/Source/WebCore/platform/text/TextChecking.h @@ -31,6 +31,8 @@ #ifndef TextChecking_h #define TextChecking_h +#include <wtf/RefCounted.h> +#include <wtf/Vector.h> #include <wtf/text/WTFString.h> namespace WebCore { @@ -68,23 +70,40 @@ enum TextCheckingProcessType { TextCheckingProcessIncremental }; -class TextCheckingRequest { +struct GrammarDetail { + int location; + int length; + Vector<String> guesses; + String userDescription; +}; + +struct TextCheckingResult { + TextCheckingType type; + int location; + int length; + Vector<GrammarDetail> details; + String replacement; +}; + +class TextCheckingRequest : public RefCounted<TextCheckingRequest> { public: - TextCheckingRequest(int sequence, String text, TextCheckingTypeMask mask, TextCheckingProcessType processType) + TextCheckingRequest(int sequence, const String& text, TextCheckingTypeMask mask, TextCheckingProcessType processType) : m_sequence(sequence) , m_text(text) , m_mask(mask) , m_processType(processType) - { - } + { } + + virtual ~TextCheckingRequest() { } + virtual void didSucceed(const Vector<TextCheckingResult>&) = 0; + virtual void didCancel() = 0; - void setSequence(int sequence) { m_sequence = sequence; } int sequence() const { return m_sequence; } String text() const { return m_text; } TextCheckingTypeMask mask() const { return m_mask; } TextCheckingProcessType processType() const { return m_processType; } -private: +protected: int m_sequence; String m_text; TextCheckingTypeMask m_mask; diff --git a/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp b/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp index ca75f1b0d..0d9d48dbe 100644 --- a/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp +++ b/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp @@ -76,7 +76,10 @@ namespace WebCore { bool createdIterator = m_iterator && weakCompareAndSwap(reinterpret_cast<void**>(&nonSharedCharacterBreakIterator), m_iterator, 0); if (!createdIterator) m_iterator = new TextBreakIterator(); - setUpIterator(*m_iterator, QTextBoundaryFinder::Grapheme, buffer, length); + if (!setUpIterator(*m_iterator, QTextBoundaryFinder::Grapheme, buffer, length)) { + delete m_iterator; + m_iterator = 0; + } } NonSharedCharacterBreakIterator::~NonSharedCharacterBreakIterator() diff --git a/Source/WebCore/platform/text/wince/TextBreakIteratorWinCE.cpp b/Source/WebCore/platform/text/wince/TextBreakIteratorWinCE.cpp index 5be1ee903..40ba1c667 100644 --- a/Source/WebCore/platform/text/wince/TextBreakIteratorWinCE.cpp +++ b/Source/WebCore/platform/text/wince/TextBreakIteratorWinCE.cpp @@ -245,7 +245,7 @@ NonSharedCharacterBreakIterator::NonSharedCharacterBreakIterator(const UChar* bu bool createdIterator = m_iterator && weakCompareAndSwap(reinterpret_cast<void**>(&nonSharedCharacterBreakIterator), m_iterator, 0); if (!createdIterator) m_iterator = new CharBreakIterator; - m_iterator.reset(string, length); + m_iterator->reset(buffer, length); } NonSharedCharacterBreakIterator::~NonSharedCharacterBreakIterator() diff --git a/Source/WebCore/platform/win/DragDataWin.cpp b/Source/WebCore/platform/win/DragDataWin.cpp index 46a9073cb..29f0e7671 100644 --- a/Source/WebCore/platform/win/DragDataWin.cpp +++ b/Source/WebCore/platform/win/DragDataWin.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2012 Baidu Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -111,7 +112,24 @@ bool DragData::containsFiles() const unsigned DragData::numberOfFiles() const { - return 0; + if (!m_platformDragData) + return 0; + + STGMEDIUM medium; + if (FAILED(m_platformDragData->GetData(cfHDropFormat(), &medium))) + return 0; + + HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal)); + + if (!hdrop) + return 0; + + unsigned numFiles = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0); + + DragFinish(hdrop); + GlobalUnlock(medium.hGlobal); + + return numFiles; } void DragData::asFilenames(Vector<String>& result) const diff --git a/Source/WebCore/platform/wx/ClipboardWx.cpp b/Source/WebCore/platform/wx/ClipboardWx.cpp index 8a3a9c8a3..24220b9d7 100644 --- a/Source/WebCore/platform/wx/ClipboardWx.cpp +++ b/Source/WebCore/platform/wx/ClipboardWx.cpp @@ -26,7 +26,9 @@ #include "config.h" #include "ClipboardWx.h" +#include "Editor.h" #include "FileList.h" +#include "Frame.h" #include "HashTable.h" #include "IntPoint.h" #include "NotImplemented.h" @@ -127,9 +129,9 @@ void ClipboardWx::writeURL(const KURL& url, const String& string, Frame* frame) Pasteboard::generalPasteboard()->writeURL(url, string, frame); } -void ClipboardWx::writeRange(Range*, Frame*) +void ClipboardWx::writeRange(Range* range, Frame* frame) { - notImplemented(); + Pasteboard::generalPasteboard()->writeSelection(range, frame->editor()->smartInsertDeleteEnabled() && frame->selection()->granularity() == WordGranularity, frame); } bool ClipboardWx::hasData() diff --git a/Source/WebCore/platform/wx/FileSystemWx.cpp b/Source/WebCore/platform/wx/FileSystemWx.cpp index 1a2edd5a0..d3f7b18fc 100644 --- a/Source/WebCore/platform/wx/FileSystemWx.cpp +++ b/Source/WebCore/platform/wx/FileSystemWx.cpp @@ -91,7 +91,7 @@ bool getFileMetadata(const String& path, FileMetadata& metadata) if (!wxFileExists(path)) return false; wxFileName fileName(path); - metadata.length = fileName.GetSize(); + metadata.length = fileName.GetSize().GetValue(); metadata.modificationTime = fileName.GetModificationTime().GetTicks(); metadata.type = fileName.IsDir() ? FileMetadata::TypeDirectory : FileMetadata::TypeFile; return true; diff --git a/Source/WebCore/platform/wx/PasteboardWx.cpp b/Source/WebCore/platform/wx/PasteboardWx.cpp index 2bd7177f8..752fdaccf 100644 --- a/Source/WebCore/platform/wx/PasteboardWx.cpp +++ b/Source/WebCore/platform/wx/PasteboardWx.cpp @@ -53,7 +53,10 @@ Pasteboard* Pasteboard::generalPasteboard() void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame) { if (wxTheClipboard->Open()) { - wxTheClipboard->SetData( new wxTextDataObject(frame->editor()->selectedText()) ); +#if wxCHECK_VERSION(2, 9, 4) + wxTheClipboard->SetData(new wxHTMLDataObject(createMarkup(selectedRange, 0, AnnotateForInterchange))); +#endif + wxTheClipboard->SetData(new wxTextDataObject(frame->editor()->selectedText())); wxTheClipboard->Close(); } } @@ -91,11 +94,21 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP { RefPtr<DocumentFragment> fragment = 0; if (wxTheClipboard->Open()) { - if (allowPlainText && wxTheClipboard->IsSupported( wxDF_TEXT )) { - wxTextDataObject data; - wxTheClipboard->GetData( data ); - chosePlainText = true; - fragment = createFragmentFromText(context.get(), data.GetText()); +#if wxCHECK_VERSION(2, 9, 4) + if (wxTheClipboard->IsSupported(wxDF_HTML)) { + wxHTMLDataObject data; + wxTheClipboard->GetData(data); + chosePlainText = false; + fragment = createFragmentFromMarkup(frame->document(), data.GetHTML(), "", FragmentScriptingNotAllowed); + } else +#endif + { + if (allowPlainText && wxTheClipboard->IsSupported( wxDF_TEXT )) { + wxTextDataObject data; + wxTheClipboard->GetData( data ); + chosePlainText = true; + fragment = createFragmentFromText(context.get(), data.GetText()); + } } wxTheClipboard->Close(); } |