diff options
Diffstat (limited to 'WebCore/platform/graphics/android')
76 files changed, 0 insertions, 16879 deletions
diff --git a/WebCore/platform/graphics/android/AndroidAnimation.cpp b/WebCore/platform/graphics/android/AndroidAnimation.cpp deleted file mode 100644 index 1eb7f39..0000000 --- a/WebCore/platform/graphics/android/AndroidAnimation.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "config.h" -#include "AndroidAnimation.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "Animation.h" -#include "GraphicsLayerAndroid.h" - -#include "Timer.h" -#include "TimingFunction.h" -#include "TranslateTransformOperation.h" -#include "UnitBezier.h" - -#include <wtf/CurrentTime.h> - -#ifdef DEBUG - -#include <cutils/log.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "AndroidAnimation", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - - -namespace WebCore { - -static long gDebugAndroidAnimationInstances; - -long AndroidAnimation::instancesCount() -{ - return gDebugAndroidAnimationInstances; -} - -AndroidAnimation::AndroidAnimation(AnimatedPropertyID type, - const Animation* animation, - KeyframeValueList* operations, - double beginTime) - : m_beginTime(beginTime) - , m_duration(animation->duration()) - , m_finished(false) - , m_iterationCount(animation->iterationCount()) - , m_direction(animation->direction()) - , m_timingFunction(animation->timingFunction()) - , m_type(type) - , m_operations(operations) - , m_originalLayer(0) -{ - ASSERT(m_timingFunction); - - if (!static_cast<int>(beginTime)) // time not set - m_beginTime = WTF::currentTime(); - - gDebugAndroidAnimationInstances++; -} - -AndroidAnimation::AndroidAnimation(AndroidAnimation* anim) - : m_beginTime(anim->m_beginTime) - , m_duration(anim->m_duration) - , m_finished(anim->m_finished) - , m_iterationCount(anim->m_iterationCount) - , m_direction(anim->m_direction) - , m_timingFunction(anim->m_timingFunction) - , m_type(anim->m_type) - , m_operations(anim->m_operations) - , m_originalLayer(0) -{ - gDebugAndroidAnimationInstances++; -} - -AndroidAnimation::~AndroidAnimation() -{ - gDebugAndroidAnimationInstances--; -} - -double AndroidAnimation::elapsedTime(double time) -{ - if (m_beginTime <= 0.000001) // overflow or not correctly set - m_beginTime = time; - - m_elapsedTime = time - m_beginTime; - - if (m_duration <= 0) - m_duration = 0.000001; - - if (m_elapsedTime < 0) // animation not yet started. - return 0; - - return m_elapsedTime; -} - -bool AndroidAnimation::checkIterationsAndProgress(double time, float* finalProgress) -{ - double progress = elapsedTime(time); - double dur = m_duration; - if (m_iterationCount > 0) - dur *= m_iterationCount; - - if (m_duration <= 0) - return false; - - // If not infinite, return false if we are done - if (m_iterationCount > 0 && progress > dur) { - *finalProgress = 1.0; - return false; - } - - double fractionalTime = progress / m_duration; - int integralTime = static_cast<int>(fractionalTime); - - fractionalTime -= integralTime; - - if ((m_direction == Animation::AnimationDirectionAlternate) && (integralTime & 1)) - fractionalTime = 1 - fractionalTime; - - *finalProgress = fractionalTime; - return true; -} - -double AndroidAnimation::applyTimingFunction(float from, float to, double progress, - const TimingFunction* tf) -{ - double fractionalTime = progress; - double offset = from; - double scale = 1.0 / (to - from); - - if (scale != 1 || offset) - fractionalTime = (fractionalTime - offset) * scale; - - const TimingFunction* timingFunction = tf; - - if (!timingFunction) - timingFunction = m_timingFunction.get(); - - if (timingFunction && timingFunction->isCubicBezierTimingFunction()) { - const CubicBezierTimingFunction* bezierFunction = static_cast<const CubicBezierTimingFunction*>(timingFunction); - UnitBezier bezier(bezierFunction->x1(), - bezierFunction->y1(), - bezierFunction->x2(), - bezierFunction->y2()); - if (m_duration > 0) - fractionalTime = bezier.solve(fractionalTime, 1.0f / (200.0f * m_duration)); - } else if (timingFunction && timingFunction->isStepsTimingFunction()) { - const StepsTimingFunction* stepFunction = static_cast<const StepsTimingFunction*>(timingFunction); - if (stepFunction->stepAtStart()) { - fractionalTime = (floor(stepFunction->numberOfSteps() * fractionalTime) + 1) / stepFunction->numberOfSteps(); - if (fractionalTime > 1.0) - fractionalTime = 1.0; - } else { - fractionalTime = floor(stepFunction->numberOfSteps() * fractionalTime) / stepFunction->numberOfSteps(); - } - } - return fractionalTime; -} - -PassRefPtr<AndroidOpacityAnimation> AndroidOpacityAnimation::create( - const Animation* animation, - KeyframeValueList* operations, - double beginTime) -{ - return adoptRef(new AndroidOpacityAnimation(animation, operations, - beginTime)); -} - -AndroidOpacityAnimation::AndroidOpacityAnimation(const Animation* animation, - KeyframeValueList* operations, - double beginTime) - : AndroidAnimation(AnimatedPropertyOpacity, animation, operations, beginTime) -{ -} - -AndroidOpacityAnimation::AndroidOpacityAnimation(AndroidOpacityAnimation* anim) - : AndroidAnimation(anim) -{ -} - -PassRefPtr<AndroidAnimation> AndroidOpacityAnimation::copy() -{ - return adoptRef(new AndroidOpacityAnimation(this)); -} - -void AndroidAnimation::pickValues(double progress, int* start, int* end) -{ - float distance = -1; - unsigned int foundAt = 0; - for (unsigned int i = 0; i < m_operations->size(); i++) { - const AnimationValue* value = m_operations->at(i); - float key = value->keyTime(); - float d = progress - key; - if (distance == -1 || (d >= 0 && d < distance && i + 1 < m_operations->size())) { - distance = d; - foundAt = i; - } - } - - *start = foundAt; - - if (foundAt + 1 < m_operations->size()) - *end = foundAt + 1; - else - *end = foundAt; -} - -bool AndroidOpacityAnimation::evaluate(LayerAndroid* layer, double time) -{ - float progress; - if (!checkIterationsAndProgress(time, &progress)) - return false; - - if (progress < 0) // we still want to be evaluated until we get progress > 0 - return true; - - if (progress >= 1) { - m_finished = true; - if (layer != m_originalLayer) - return false; - } - - if (!m_originalLayer) - m_originalLayer = layer; - - // First, we need to get the from and to values - - int from, to; - pickValues(progress, &from, &to); - FloatAnimationValue* fromValue = (FloatAnimationValue*) m_operations->at(from); - FloatAnimationValue* toValue = (FloatAnimationValue*) m_operations->at(to); - - XLOG("[layer %d] opacity fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f", - layer->uniqueId(), - fromValue, fromValue->keyTime(), - toValue, toValue->keyTime(), progress); - - // We now have the correct two values to work with, let's compute the - // progress value - - const TimingFunction* timingFunction = fromValue->timingFunction(); - progress = applyTimingFunction(fromValue->keyTime(), toValue->keyTime(), - progress, timingFunction); - float value = fromValue->value() + ((toValue->value() - fromValue->value()) * progress); - - layer->setOpacity(value); - - XLOG("AndroidOpacityAnimation::evaluate(%p, %p, %.2f) value=%.6f", this, layer, time, value); - - return true; -} - -PassRefPtr<AndroidTransformAnimation> AndroidTransformAnimation::create( - const Animation* animation, - KeyframeValueList* operations, - double beginTime) -{ - return adoptRef(new AndroidTransformAnimation(animation, operations, beginTime)); -} - -AndroidTransformAnimation::AndroidTransformAnimation(const Animation* animation, - KeyframeValueList* operations, - double beginTime) - : AndroidAnimation(AnimatedPropertyWebkitTransform, animation, operations, beginTime) -{ -} - -AndroidTransformAnimation::AndroidTransformAnimation(AndroidTransformAnimation* anim) - : AndroidAnimation(anim) -{ -} - -PassRefPtr<AndroidAnimation> AndroidTransformAnimation::copy() -{ - return adoptRef(new AndroidTransformAnimation(this)); -} - -bool AndroidTransformAnimation::evaluate(LayerAndroid* layer, double time) -{ - float progress; - bool ret = true; - if (!checkIterationsAndProgress(time, &progress)) { - m_finished = true; - ret = false; - } - - if (progress < 0) // we still want to be evaluated until we get progress > 0 - return true; - - if (progress >= 1) { - m_finished = true; - if (layer != m_originalLayer) - return false; - } - - if (!m_originalLayer) - m_originalLayer = layer; - - IntSize size(layer->getSize().width(), layer->getSize().height()); - TransformationMatrix matrix; - XLOG("Evaluate transforms animations, %d operations, progress %.2f for layer %d (%d, %d)" - , m_operations->size(), progress, layer->uniqueId(), size.width(), size.height()); - - if (!m_operations->size()) - return false; - - // First, we need to get the from and to values - - int from, to; - pickValues(progress, &from, &to); - TransformAnimationValue* fromValue = (TransformAnimationValue*) m_operations->at(from); - TransformAnimationValue* toValue = (TransformAnimationValue*) m_operations->at(to); - - XLOG("[layer %d] fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f", - layer->uniqueId(), - fromValue, fromValue->keyTime(), - toValue, toValue->keyTime(), progress); - - // We now have the correct two values to work with, let's compute the - // progress value - - const TimingFunction* timingFunction = fromValue->timingFunction(); - float p = applyTimingFunction(fromValue->keyTime(), toValue->keyTime(), - progress, timingFunction); - XLOG("progress %.2f => %.2f from: %.2f to: %.2f", progress, p, fromValue->keyTime(), - toValue->keyTime()); - progress = p; - - // With both values and the progress, we also need to check out that - // the operations are compatible (i.e. we are animating the same number - // of values; if not we do a matrix blend) - - TransformationMatrix transformMatrix; - bool valid = true; - unsigned int fromSize = fromValue->value()->size(); - if (fromSize) { - if (toValue->value()->size() != fromSize) - valid = false; - else { - for (unsigned int j = 0; j < fromSize && valid; j++) { - if (!fromValue->value()->operations()[j]->isSameType( - *toValue->value()->operations()[j])) - valid = false; - } - } - } - - if (valid) { - for (size_t i = 0; i < toValue->value()->size(); ++i) - toValue->value()->operations()[i]->blend(fromValue->value()->at(i), - progress)->apply(transformMatrix, size); - } else { - TransformationMatrix source; - - fromValue->value()->apply(size, source); - toValue->value()->apply(size, transformMatrix); - - transformMatrix.blend(source, progress); - } - - // Set the final transform on the layer - layer->setTransform(transformMatrix); - - return ret; -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/AndroidAnimation.h b/WebCore/platform/graphics/android/AndroidAnimation.h deleted file mode 100644 index 6f1410d..0000000 --- a/WebCore/platform/graphics/android/AndroidAnimation.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef AndroidAnimation_h -#define AndroidAnimation_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "FloatPoint.h" -#include "FloatPoint3D.h" -#include "GraphicsLayer.h" -#include "HashMap.h" -#include "LayerAndroid.h" -#include "RefPtr.h" -#include "Timer.h" -#include "TransformOperation.h" -#include "Vector.h" - -namespace WebCore { - -class TimingFunction; - -class AndroidAnimation : public RefCounted<AndroidAnimation> { - public: - AndroidAnimation(AnimatedPropertyID type, - const Animation* animation, - KeyframeValueList* operations, - double beginTime); - AndroidAnimation(AndroidAnimation* anim); - - virtual ~AndroidAnimation(); - virtual PassRefPtr<AndroidAnimation> copy() = 0; - double elapsedTime(double time); - void pickValues(double progress, int* start, int* end); - bool checkIterationsAndProgress(double time, float* finalProgress); - double applyTimingFunction(float from, float to, double progress, - const TimingFunction* timingFunction); - virtual bool evaluate(LayerAndroid* layer, double time) = 0; - static long instancesCount(); - void setName(const String& name) { m_name = name; } - String name() { return m_name; } - AnimatedPropertyID type() { return m_type; } - bool finished() { return m_finished; } - - protected: - double m_beginTime; - double m_elapsedTime; - double m_duration; - bool m_finished; - int m_iterationCount; - int m_direction; - RefPtr<TimingFunction> m_timingFunction; - String m_name; - AnimatedPropertyID m_type; - KeyframeValueList* m_operations; - LayerAndroid* m_originalLayer; -}; - -class AndroidOpacityAnimation : public AndroidAnimation { - public: - static PassRefPtr<AndroidOpacityAnimation> create(const Animation* animation, - KeyframeValueList* operations, - double beginTime); - AndroidOpacityAnimation(const Animation* animation, - KeyframeValueList* operations, - double beginTime); - AndroidOpacityAnimation(AndroidOpacityAnimation* anim); - virtual PassRefPtr<AndroidAnimation> copy(); - - virtual bool evaluate(LayerAndroid* layer, double time); -}; - -class AndroidTransformAnimation : public AndroidAnimation { - public: - static PassRefPtr<AndroidTransformAnimation> create( - const Animation* animation, - KeyframeValueList* operations, - double beginTime); - AndroidTransformAnimation(const Animation* animation, - KeyframeValueList* operations, - double beginTime); - - AndroidTransformAnimation(AndroidTransformAnimation* anim); - virtual PassRefPtr<AndroidAnimation> copy(); - - virtual bool evaluate(LayerAndroid* layer, double time); -}; - -} // namespace WebCore - - -#endif // USE(ACCELERATED_COMPOSITING) - -#endif // AndroidAnimation_h diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp deleted file mode 100644 index 964422a..0000000 --- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "BackedDoubleBufferedTexture.h" - -#include "BaseTile.h" -#include "ClassTracker.h" -#include "DeleteTextureOperation.h" -#include "GLUtils.h" -#include "TilesManager.h" - -#define LOG_NDEBUG 1 -#define LOG_TAG "BackedDoubleBufferedTexture.cpp" -#include <utils/Log.h> - -namespace WebCore { - -BackedDoubleBufferedTexture::BackedDoubleBufferedTexture(uint32_t w, uint32_t h, - SkBitmap* bitmap, - SkBitmap::Config config) - : DoubleBufferedTexture(eglGetCurrentContext()) - , m_usedLevel(-1) - , m_config(config) - , m_owner(0) - , m_delayedReleaseOwner(0) - , m_delayedRelease(false) - , m_busy(false) -{ - m_size.set(w, h); - if (bitmap) { - m_bitmap = bitmap; - m_sharedBitmap = true; - m_canvas = new SkCanvas(*m_bitmap); - } else { - m_bitmap = 0; - m_sharedBitmap = false; - m_canvas = 0; - } - -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("BackedDoubleBufferedTexture"); -#endif -} - -SkCanvas* BackedDoubleBufferedTexture::canvas() -{ - if (!m_bitmap && !m_sharedBitmap) { - m_bitmap = new SkBitmap(); - m_bitmap->setConfig(m_config, m_size.width(), m_size.height()); - m_bitmap->allocPixels(); - m_bitmap->eraseColor(0); - m_canvas = new SkCanvas(*m_bitmap); - } - return m_canvas; -} - -BackedDoubleBufferedTexture::~BackedDoubleBufferedTexture() -{ - if (!m_sharedBitmap) - delete m_bitmap; - delete m_canvas; - SharedTexture* textures[3] = { &m_textureA, &m_textureB, 0 }; - destroyTextures(textures); -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("BackedDoubleBufferedTexture"); -#endif -} - -void BackedDoubleBufferedTexture::destroyTextures(SharedTexture** textures) -{ - int x = 0; - while (textures[x]) { - // We need to delete the source texture and EGLImage in the texture - // generation thread. In theory we should be able to delete the EGLImage - // from either thread, but it currently throws an error if not deleted - // in the same EGLContext from which it was created. - textures[x]->lock(); - DeleteTextureOperation* operation = new DeleteTextureOperation( - textures[x]->getSourceTextureId(), textures[x]->getEGLImage()); - textures[x]->unlock(); - TilesManager::instance()->scheduleOperation(operation); - x++; - } -} - -TextureInfo* BackedDoubleBufferedTexture::producerLock() -{ - m_busyLock.lock(); - m_busy = true; - m_busyLock.unlock(); - return DoubleBufferedTexture::producerLock(); -} - -void BackedDoubleBufferedTexture::producerRelease() -{ - DoubleBufferedTexture::producerRelease(); - setNotBusy(); -} - -void BackedDoubleBufferedTexture::producerReleaseAndSwap() -{ - DoubleBufferedTexture::producerReleaseAndSwap(); - setNotBusy(); -} - -void BackedDoubleBufferedTexture::setNotBusy() -{ - android::Mutex::Autolock lock(m_busyLock); - m_busy = false; - if (m_delayedRelease) { - if (m_owner == m_delayedReleaseOwner) - m_owner = 0; - - m_delayedRelease = false; - m_delayedReleaseOwner = 0; - } - m_busyCond.signal(); -} - -bool BackedDoubleBufferedTexture::busy() -{ - android::Mutex::Autolock lock(m_busyLock); - return m_busy; -} - -bool BackedDoubleBufferedTexture::textureExist(TextureInfo* textureInfo) -{ - if (!m_bitmap) - return false; - - if (!m_bitmap->width() || !m_bitmap->height()) - return false; - - if (textureInfo->m_width == m_bitmap->width() && - textureInfo->m_height == m_bitmap->height()) - return true; - - return false; -} - -void BackedDoubleBufferedTexture::producerUpdate(TextureInfo* textureInfo) -{ - if (!m_bitmap) - return; - - // no need to upload a texture since the bitmap is empty - if (!m_bitmap->width() && !m_bitmap->height()) { - producerRelease(); - return; - } - - if (textureExist(textureInfo)) - GLUtils::updateTextureWithBitmap(textureInfo->m_textureId, *m_bitmap); - else { - GLUtils::createTextureWithBitmap(textureInfo->m_textureId, *m_bitmap); - textureInfo->m_width = m_bitmap->width(); - textureInfo->m_height = m_bitmap->height(); - } - - if (!m_sharedBitmap) { - delete m_bitmap; - delete m_canvas; - m_bitmap = 0; - m_canvas = 0; - } - - producerReleaseAndSwap(); -} - -bool BackedDoubleBufferedTexture::acquire(TextureOwner* owner, bool force) -{ - if (m_owner == owner) { - if (m_delayedRelease) { - m_delayedRelease = false; - m_delayedReleaseOwner = 0; - } - return true; - } - - return setOwner(owner, force); -} - -bool BackedDoubleBufferedTexture::tryAcquire(TextureOwner* owner, TiledPage* currentPage, TiledPage* nextPage) -{ - m_busyLock.lock(); - if (!m_busy - && m_owner - && m_owner->page() != currentPage - && m_owner->page() != nextPage) { - m_busyLock.unlock(); - return this->acquire(owner); - } - m_busyLock.unlock(); - return false; -} - -bool BackedDoubleBufferedTexture::setOwner(TextureOwner* owner, bool force) -{ - // if the writable texture is busy (i.e. currently being written to) then we - // can't change the owner out from underneath that texture - m_busyLock.lock(); - while (m_busy && force) - m_busyCond.wait(m_busyLock); - bool busy = m_busy; - m_busyLock.unlock(); - - if (!busy) { - // if we are not busy we can try to remove the texture from the layer; - // LayerAndroid::removeTexture() is protected by the same lock as - // LayerAndroid::paintBitmapGL(), so either we execute removeTexture() - // first and paintBitmapGL() will bail out, or we execute it after, - // and paintBitmapGL() will mark the texture as busy before - // relinquishing the lock. LayerAndroid::removeTexture() will call - // BackedDoubleBufferedTexture::release(), which will then do nothing - // if the texture is busy and we then don't return true. - bool proceed = true; - if (m_owner && m_owner != owner) - proceed = m_owner->removeTexture(this); - - if (proceed) { - m_owner = owner; - return true; - } - } - return false; -} - -bool BackedDoubleBufferedTexture::release(TextureOwner* owner) -{ - android::Mutex::Autolock lock(m_busyLock); - if (m_owner != owner) - return false; - - if (!m_busy) { - m_owner = 0; - } else { - m_delayedRelease = true; - m_delayedReleaseOwner = owner; - } - return true; -} - -void BackedDoubleBufferedTexture::setTile(TextureInfo* info, int x, int y, - float scale, unsigned int pictureCount) -{ - TextureTileInfo* textureInfo = m_texturesInfo.get(getWriteableTexture()); - if (!textureInfo) { - textureInfo = new TextureTileInfo(); - } - textureInfo->m_x = x; - textureInfo->m_y = y; - textureInfo->m_scale = scale; - textureInfo->m_picture = pictureCount; - m_texturesInfo.set(getWriteableTexture(), textureInfo); -} - -bool BackedDoubleBufferedTexture::readyFor(BaseTile* baseTile) -{ - TextureTileInfo* info = m_texturesInfo.get(getReadableTexture()); - if (info && - (info->m_x == baseTile->x()) && - (info->m_y == baseTile->y()) && - (info->m_scale == baseTile->scale()) && - (info->m_picture == baseTile->lastPaintedPicture())) { - return true; - } - return false; -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h deleted file mode 100644 index 7c2ea90..0000000 --- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 BackedDoubleBufferedTexture_h -#define BackedDoubleBufferedTexture_h - -#include "DoubleBufferedTexture.h" -#include "GLWebViewState.h" -#include "TextureOwner.h" -#include <SkBitmap.h> - -class SkCanvas; - -namespace WebCore { - -class BaseTile; - -class TextureTileInfo { - public: - TextureTileInfo() - : m_x(-1) - , m_y(-1) - , m_layerId(-1) - , m_scale(0) - , m_texture(0) - , m_picture(0) - { - } - int m_x; - int m_y; - int m_layerId; - float m_scale; - TextureInfo* m_texture; - unsigned int m_picture; -}; - -// DoubleBufferedTexture using a SkBitmap as backing mechanism -class BackedDoubleBufferedTexture : public DoubleBufferedTexture { -public: - // This object is to be constructed on the consumer's thread and must have - // a width and height greater than 0. - BackedDoubleBufferedTexture(uint32_t w, uint32_t h, - SkBitmap* bitmap = 0, - SkBitmap::Config config = SkBitmap::kARGB_8888_Config); - virtual ~BackedDoubleBufferedTexture(); - - // these functions override their parent - virtual TextureInfo* producerLock(); - virtual void producerRelease(); - virtual void producerReleaseAndSwap(); - - // updates the texture with current bitmap and releases (and if needed also - // swaps) the texture. - virtual void producerUpdate(TextureInfo* textureInfo); - void producerUpdate(TextureInfo* textureInfo, SkBitmap* bitmap, SkIRect& rect); - bool textureExist(TextureInfo* textureInfo); - - // The level can be one of the following values: - // * -1 for an unused texture. - // * 0 for the tiles intersecting with the viewport. - // * n where n > 0 for the distance between the viewport and the tile. - // We use this to prioritize the order in which we reclaim textures, see - // TilesManager::getAvailableTexture() for more information. - int usedLevel() { return m_usedLevel; } - void setUsedLevel(int used) { m_usedLevel = used; } - - // allows consumer thread to assign ownership of the texture to the tile. It - // returns false if ownership cannot be transferred because the tile is busy - bool acquire(TextureOwner* owner, bool force = false); - bool release(TextureOwner* owner); - bool tryAcquire(TextureOwner* owner, TiledPage* currentPage, TiledPage* nextPage); - - // set the texture owner if not busy. Return false if busy, true otherwise. - bool setOwner(TextureOwner* owner, bool force = false); - - // private member accessor functions - TextureOwner* owner() { return m_owner; } // only used by the consumer thread - TextureOwner* delayedReleaseOwner() { return m_delayedReleaseOwner; } - SkCanvas* canvas(); // only used by the producer thread - SkBitmap* bitmap() { return m_bitmap; } - - bool busy(); - void setNotBusy(); - - const SkSize& getSize() const { return m_size; } - - void setTile(TextureInfo* info, int x, int y, float scale, unsigned int pictureCount); - bool readyFor(BaseTile* baseTile); - -protected: - HashMap<SharedTexture*, TextureTileInfo*> m_texturesInfo; - -private: - void destroyTextures(SharedTexture** textures); - - SkBitmap* m_bitmap; - bool m_sharedBitmap; - SkSize m_size; - SkCanvas* m_canvas; - int m_usedLevel; - SkBitmap::Config m_config; - TextureOwner* m_owner; - - // When trying to release a texture, we may delay this if the texture is - // currently used (busy being painted). We use the following two variables - // to do so in setNotBusy() - TextureOwner* m_delayedReleaseOwner; - bool m_delayedRelease; - - // This values signals that the texture is currently in use by the consumer. - // This allows us to prevent the owner of the texture from changing while the - // consumer is holding a lock on the texture. - bool m_busy; - // We mutex protect the reads/writes of m_busy to ensure that we are reading - // the most up-to-date value even across processors in an SMP system. - android::Mutex m_busyLock; - // We use this condition variable to signal that the texture - // is not busy anymore - android::Condition m_busyCond; -}; - -} // namespace WebCore - -#endif // BackedDoubleBufferedTexture_h diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp deleted file mode 100644 index 09d80a1..0000000 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "BaseLayerAndroid.h" - -#if USE(ACCELERATED_COMPOSITING) -#include "ClassTracker.h" -#include "GLUtils.h" -#include "ShaderProgram.h" -#include "SkCanvas.h" -#include "TilesManager.h" -#include <GLES2/gl2.h> -#include <wtf/CurrentTime.h> -#endif // USE(ACCELERATED_COMPOSITING) - -#ifdef DEBUG - -#include <cutils/log.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseLayerAndroid", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -namespace WebCore { - -using namespace android; - -BaseLayerAndroid::BaseLayerAndroid() -#if USE(ACCELERATED_COMPOSITING) - : m_glWebViewState(0), - m_color(Color::white) -#endif -{ -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("BaseLayerAndroid"); -#endif -} - -BaseLayerAndroid::~BaseLayerAndroid() -{ -#if USE(ACCELERATED_COMPOSITING) - if (TilesManager::hardwareAccelerationEnabled()) - TilesManager::instance()->removeOperationsForBaseLayer(this); -#endif - m_content.clear(); -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("BaseLayerAndroid"); -#endif -} - -void BaseLayerAndroid::setContent(const PictureSet& src) -{ -#if USE(ACCELERATED_COMPOSITING) - // FIXME: We lock here because we do not want - // to paint and change the m_content concurrently. - // We should instead refactor PictureSet to use - // an atomic refcounting scheme and use atomic operations - // to swap PictureSets. - android::Mutex::Autolock lock(m_drawLock); -#endif - m_content.set(src); - // FIXME: We cannot set the size of the base layer because it will screw up - // the matrix used. We need to fix matrix computation for the base layer - // and then we can set the size. - // setSize(src.width(), src.height()); -} - -void BaseLayerAndroid::setExtra(SkPicture& src) -{ -#if USE(ACCELERATED_COMPOSITING) - android::Mutex::Autolock lock(m_drawLock); -#endif - m_extra.swap(src); -} - -void BaseLayerAndroid::drawCanvas(SkCanvas* canvas) -{ -#if USE(ACCELERATED_COMPOSITING) - android::Mutex::Autolock lock(m_drawLock); -#endif - if (!m_content.isEmpty()) - m_content.draw(canvas); - // TODO : replace with !m_extra.isEmpty() once such a call exists - if (m_extra.width() > 0) - m_extra.draw(canvas); -} - -#if USE(ACCELERATED_COMPOSITING) -bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double currentTime) -{ - if (!m_glWebViewState) - return false; - - bool goingDown = m_previousVisible.fTop - viewport.fTop <= 0; - bool goingLeft = m_previousVisible.fLeft - viewport.fLeft >= 0; - - m_glWebViewState->setViewport(viewport, scale); - - const SkIRect& viewportTileBounds = m_glWebViewState->viewportTileBounds(); - XLOG("drawBasePicture, TX: %d, TY: %d scale %.2f", viewportTileBounds.fLeft, - viewportTileBounds.fTop, scale); - - if (scale == m_glWebViewState->currentScale() - || m_glWebViewState->preZoomBounds().isEmpty()) - m_glWebViewState->setPreZoomBounds(viewportTileBounds); - - bool prepareNextTiledPage = false; - // If we have a different scale than the current one, we have to - // decide what to do. The current behaviour is to delay an update, - // so that we do not slow down zooming unnecessarily. - if (m_glWebViewState->currentScale() != scale - && (m_glWebViewState->scaleRequestState() == GLWebViewState::kNoScaleRequest - || m_glWebViewState->futureScale() != scale) - || m_glWebViewState->scaleRequestState() == GLWebViewState::kWillScheduleRequest) { - - // schedule the new request - m_glWebViewState->scheduleUpdate(currentTime, viewportTileBounds, scale); - - // If it's a new request, we will have to prepare the page. - if (m_glWebViewState->scaleRequestState() == GLWebViewState::kRequestNewScale) - prepareNextTiledPage = true; - } - - // If the viewport has changed since we scheduled the request, we also need to prepare. - if (((m_glWebViewState->scaleRequestState() == GLWebViewState::kRequestNewScale) - || (m_glWebViewState->scaleRequestState() == GLWebViewState::kReceivedNewScale)) - && (m_glWebViewState->futureViewport() != viewportTileBounds)) - prepareNextTiledPage = true; - - bool zooming = false; - if (m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest) { - prepareNextTiledPage = true; - zooming = true; - } - - // Display the current page - TiledPage* tiledPage = m_glWebViewState->frontPage(); - tiledPage->setScale(m_glWebViewState->currentScale()); - - // Let's prepare the page if needed - if (prepareNextTiledPage) { - TiledPage* nextTiledPage = m_glWebViewState->backPage(); - nextTiledPage->setScale(scale); - m_glWebViewState->setFutureViewport(viewportTileBounds); - m_glWebViewState->lockBaseLayerUpdate(); - nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds); - // Cancel pending paints for the foreground page - TilesManager::instance()->removePaintOperationsForPage(tiledPage, false); - } - - float transparency = 1; - bool doSwap = false; - - // If we fired a request, let's check if it's ready to use - if (m_glWebViewState->scaleRequestState() == GLWebViewState::kRequestNewScale) { - TiledPage* nextTiledPage = m_glWebViewState->backPage(); - if (nextTiledPage->ready(viewportTileBounds, m_glWebViewState->futureScale())) - m_glWebViewState->setScaleRequestState(GLWebViewState::kReceivedNewScale); - } - - // If the page is ready, display it. We do a short transition between - // the two pages (current one and future one with the new scale factor) - if (m_glWebViewState->scaleRequestState() == GLWebViewState::kReceivedNewScale) { - TiledPage* nextTiledPage = m_glWebViewState->backPage(); - double transitionTime = (scale < m_glWebViewState->currentScale()) ? - m_glWebViewState->zoomOutTransitionTime(currentTime) : - m_glWebViewState->zoomInTransitionTime(currentTime); - - float newTilesTransparency = 1; - if (scale < m_glWebViewState->currentScale()) - newTilesTransparency = 1 - m_glWebViewState->zoomOutTransparency(currentTime); - else - transparency = m_glWebViewState->zoomInTransparency(currentTime); - - nextTiledPage->draw(newTilesTransparency, viewportTileBounds); - - // The transition between the two pages is finished, swap them - if (currentTime > transitionTime) { - m_glWebViewState->resetTransitionTime(); - doSwap = true; - } - } - - const SkIRect& preZoomBounds = m_glWebViewState->preZoomBounds(); - - TiledPage* nextTiledPage = m_glWebViewState->backPage(); - bool needsRedraw = false; - - // We are now using an hybrid model -- during scrolling, - // we will display the current tiledPage even if some tiles are - // out of date. When standing still on the other hand, we wait until - // the back page is ready before swapping the pages, ensuring that the - // displayed content is in sync. - if (!doSwap && !zooming && !m_glWebViewState->moving()) { - if (!tiledPage->ready(preZoomBounds, m_glWebViewState->currentScale())) { - m_glWebViewState->lockBaseLayerUpdate(); - nextTiledPage->setScale(m_glWebViewState->currentScale()); - nextTiledPage->prepare(goingDown, goingLeft, preZoomBounds); - } - if (nextTiledPage->ready(preZoomBounds, m_glWebViewState->currentScale())) { - nextTiledPage->draw(transparency, preZoomBounds); - m_glWebViewState->resetFrameworkInval(); - m_glWebViewState->unlockBaseLayerUpdate(); - doSwap = true; - } else { - tiledPage->draw(transparency, preZoomBounds); - } - } else { - if (tiledPage->ready(preZoomBounds, m_glWebViewState->currentScale())) - m_glWebViewState->resetFrameworkInval(); - - // Ask for the tiles and draw -- tiles may be out of date. - if (!zooming) - m_glWebViewState->unlockBaseLayerUpdate(); - - if (!prepareNextTiledPage) - tiledPage->prepare(goingDown, goingLeft, preZoomBounds); - tiledPage->draw(transparency, preZoomBounds); - } - - if (m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest - || !tiledPage->ready(preZoomBounds, m_glWebViewState->currentScale())) - needsRedraw = true; - - if (doSwap) { - m_glWebViewState->setCurrentScale(scale); - m_glWebViewState->swapPages(); - m_glWebViewState->unlockBaseLayerUpdate(); - } - - m_glWebViewState->paintExtras(); - return needsRedraw; -} -#endif // USE(ACCELERATED_COMPOSITING) - -bool BaseLayerAndroid::drawGL(LayerAndroid* compositedRoot, - IntRect& viewRect, SkRect& visibleRect, - IntRect& webViewRect, int titleBarHeight, - IntRect& screenClip, float scale, SkColor color) -{ - bool needsRedraw = false; -#if USE(ACCELERATED_COMPOSITING) - int left = viewRect.x(); - int top = viewRect.y(); - int width = viewRect.width(); - int height = viewRect.height(); - XLOG("drawBasePicture drawGL() viewRect: %d, %d, %d, %d - %.2f", - left, top, width, height, scale); - - m_glWebViewState->setBackgroundColor(color); - glClearColor((float)m_color.red() / 255.0, - (float)m_color.green() / 255.0, - (float)m_color.blue() / 255.0, 1); - glClear(GL_COLOR_BUFFER_BIT); - - glViewport(left, top, width, height); - ShaderProgram* shader = TilesManager::instance()->shader(); - if (shader->program() == -1) { - XLOG("Reinit shader"); - shader->init(); - } - glUseProgram(shader->program()); - glUniform1i(shader->textureSampler(), 0); - shader->setViewRect(viewRect); - shader->setViewport(visibleRect); - shader->setWebViewRect(webViewRect); - shader->setTitleBarHeight(titleBarHeight); - shader->setScreenClip(screenClip); - shader->resetBlending(); - - double currentTime = WTF::currentTime(); - needsRedraw = drawBasePictureInGL(visibleRect, scale, currentTime); - if (!needsRedraw) - m_glWebViewState->resetFrameworkInval(); - - if (compositedRoot) { - TransformationMatrix ident; - - bool animsRunning = compositedRoot->evaluateAnimations(); - if (animsRunning) - needsRedraw = true; - - compositedRoot->updateFixedLayersPositions(visibleRect); - FloatRect clip(0, 0, viewRect.width(), viewRect.height()); - compositedRoot->updateGLPositions(ident, clip, 1); - SkMatrix matrix; - matrix.setTranslate(left, top); - - // At this point, the previous LayerAndroid* root has been destroyed, - // which will have removed the layers as owners of the textures. - // Let's now do a pass to reserve the textures for the current tree; - // it will only reserve existing textures, not create them on demand. -#ifdef DEBUG - TilesManager::instance()->printLayersTextures("reserve"); -#endif - // Get the current scale; if we are zooming, we don't change the scale - // factor immediately (see BaseLayerAndroid::drawBasePictureInGL()), but - // we change the scaleRequestState. When the state is kReceivedNewScale - // we can use the future scale instead of the current scale to request - // new textures. After a transition time, the scaleRequestState will be - // reset and the current scale will be set to the future scale. - float scale = m_glWebViewState->currentScale(); - if (m_glWebViewState->scaleRequestState() == GLWebViewState::kReceivedNewScale) { - scale = m_glWebViewState->futureScale(); - } - bool fullSetup = true; - if ((m_glWebViewState->previouslyUsedRoot() == compositedRoot) && - (compositedRoot->getScale() == scale) && - (!m_glWebViewState->moving())) - fullSetup = false; - - compositedRoot->setScale(scale); - - if (fullSetup) { - compositedRoot->computeTextureSize(currentTime); - compositedRoot->reserveGLTextures(); - -#ifdef DEBUG - int size = compositedRoot->countTextureSize(); - int nbLayers = compositedRoot->nbLayers(); - XLOG("We are using %d Mb for %d layers", size / 1024 / 1024, nbLayers); - compositedRoot->showLayers(); -#endif - // Now that we marked the textures being used, we delete - // the unnecessary ones to make space... - TilesManager::instance()->cleanupLayersTextures(compositedRoot); - } - // Finally do another pass to create new textures and schedule - // repaints if needed - compositedRoot->createGLTextures(); - - if (compositedRoot->drawGL(m_glWebViewState, matrix)) - needsRedraw = true; - else if (!animsRunning) - m_glWebViewState->resetLayersDirtyArea(); - - } else { - TilesManager::instance()->cleanupLayersTextures(0); - } - - glBindBuffer(GL_ARRAY_BUFFER, 0); - m_previousVisible = visibleRect; - -#endif // USE(ACCELERATED_COMPOSITING) -#ifdef DEBUG - ClassTracker::instance()->show(); -#endif - return needsRedraw; -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.h b/WebCore/platform/graphics/android/BaseLayerAndroid.h deleted file mode 100644 index 38e7e47..0000000 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 BaseLayerAndroid_h -#define BaseLayerAndroid_h - -#include "Color.h" -#include "GLWebViewState.h" -#include "IntRect.h" -#include "PictureSet.h" -#include "SkLayer.h" -#include "SkPicture.h" - -namespace WebCore { - -class BaseLayerAndroid : public SkLayer { - -public: - BaseLayerAndroid(); - virtual ~BaseLayerAndroid(); - -#if USE(ACCELERATED_COMPOSITING) - void setGLWebViewState(GLWebViewState* infos) { m_glWebViewState = infos; } - void setBackgroundColor(Color& color) { m_color = color; } -#endif - void setContent(const android::PictureSet& src); - void setExtra(SkPicture& extra); - android::PictureSet* content() { return &m_content; } - // This method will paint using the current PictureSet onto - // the passed canvas. We used it to paint the GL tiles as well as - // WebView::copyBaseContentToPicture(), so a lock is necessary as - // we are running in different threads. - void drawCanvas(SkCanvas* canvas); - - bool drawGL(LayerAndroid* compositedRoot, IntRect& rect, SkRect& viewport, - IntRect& webViewRect, int titleBarHeight, IntRect& screenClip, - float scale, SkColor color = SK_ColorWHITE); - void swapExtra(BaseLayerAndroid* base) { m_extra.swap(base->m_extra); } -private: -#if USE(ACCELERATED_COMPOSITING) - bool drawBasePictureInGL(SkRect& viewport, float scale, double currentTime); - - GLWebViewState* m_glWebViewState; - android::Mutex m_drawLock; - Color m_color; -#endif - android::PictureSet m_content; - SkPicture m_extra; - SkRect m_previousVisible; -}; - -} // namespace WebCore - -#endif // BaseLayerAndroid_h diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp deleted file mode 100644 index c74a278..0000000 --- a/WebCore/platform/graphics/android/BaseTile.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "BaseTile.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "GLUtils.h" -#include "SkBitmap.h" -#include "SkBitmapRef.h" -#include "SkCanvas.h" -#include "SkPicture.h" -#include "TilesManager.h" - -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> -#include <cutils/atomic.h> - -#ifdef DEBUG - -#include <cutils/log.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTile", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -namespace WebCore { - -BaseTile::BaseTile() - : m_page(0) - , m_x(-1) - , m_y(-1) - , m_texture(0) - , m_scale(1) - , m_dirty(true) - , m_repaintPending(false) - , m_usable(true) - , m_lastDirtyPicture(0) - , m_fullRepaintA(true) - , m_fullRepaintB(true) - , m_lastPaintedPicture(0) -{ -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("BaseTile"); -#endif - m_currentDirtyArea = &m_dirtyAreaA; -} - -BaseTile::~BaseTile() -{ - setUsedLevel(-1); - if (m_texture) - m_texture->release(this); - -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("BaseTile"); -#endif -} - -// All the following functions must be called from the main GL thread. - -void BaseTile::setContents(TiledPage* page, int x, int y) -{ - android::AutoMutex lock(m_atomicSync); - m_page = page; - m_x = x; - m_y = y; -} - -void BaseTile::reserveTexture() -{ - BackedDoubleBufferedTexture* texture = TilesManager::instance()->getAvailableTexture(this); - - android::AutoMutex lock(m_atomicSync); - if (texture && m_texture != texture) { - m_lastPaintedPicture = 0; - fullInval(); - m_texture = texture; - } -} - -bool BaseTile::removeTexture(BackedDoubleBufferedTexture* texture) -{ - XLOG("%x removeTexture res: %x... page %x", this, m_texture, m_page); - // We update atomically, so paintBitmap() can see the correct value - android::AutoMutex lock(m_atomicSync); - if (m_texture == texture) - m_texture = 0; - return true; -} - -void BaseTile::fullInval() -{ - m_dirtyAreaA.setEmpty(); - m_dirtyAreaB.setEmpty(); - m_fullRepaintA = true; - m_fullRepaintB = true; - m_dirty = true; -} - -void BaseTile::setScale(float scale) -{ - android::AutoMutex lock(m_atomicSync); - if (m_scale != scale) { - m_scale = scale; - fullInval(); - } -} - -void BaseTile::markAsDirty(int unsigned pictureCount, - const SkRegion& dirtyArea) -{ - android::AutoMutex lock(m_atomicSync); - m_lastDirtyPicture = pictureCount; - m_dirtyAreaA.op(dirtyArea, SkRegion::kUnion_Op); - m_dirtyAreaB.op(dirtyArea, SkRegion::kUnion_Op); - m_dirty = true; -} - -void BaseTile::setUsable(bool usable) -{ - android::AutoMutex lock(m_atomicSync); - m_usable = usable; -} - - -bool BaseTile::isDirty() -{ - android::AutoMutex lock(m_atomicSync); - return m_dirty; -} - -bool BaseTile::isRepaintPending() -{ - android::AutoMutex lock(m_atomicSync); - return m_repaintPending; -} - -void BaseTile::setRepaintPending(bool pending) -{ - android::AutoMutex lock(m_atomicSync); - m_repaintPending = pending; -} - -void BaseTile::setUsedLevel(int usedLevel) -{ - if (m_texture) - m_texture->setUsedLevel(usedLevel); -} - -int BaseTile::usedLevel() -{ - if (m_texture) - return m_texture->usedLevel(); - return -1; -} - -void BaseTile::draw(float transparency, SkRect& rect, float scale) -{ - if (m_x < 0 || m_y < 0 || m_scale != scale) - return; - - // No need to mutex protect reads of m_texture as it is only written to by - // the consumer thread. - if (!m_texture) { - XLOG("%x on page %x (%d, %d) trying to draw, but no m_texture!", this, m_page, x(), y()); - return; - } - - // Early return if set to un-usable in purpose! - m_atomicSync.lock(); - bool usable = m_usable; - bool isTexturePainted = m_lastPaintedPicture; - m_atomicSync.unlock(); - if (!usable) { - XLOG("early return at BaseTile::draw b/c tile set to unusable !"); - return; - } - if (!isTexturePainted) { - XLOG("early return at BaseTile::draw b/c tile is not painted !"); - return; - } - - TextureInfo* textureInfo = m_texture->consumerLock(); - if (!textureInfo) { - XLOG("%x (%d, %d) trying to draw, but no textureInfo!", this, x(), y()); - m_texture->consumerRelease(); - return; - } - - if (m_texture->readyFor(this)) { - XLOG("draw tile %d, %d, %.2f with texture %x", x(), y(), scale(), m_texture); - TilesManager::instance()->shader()->drawQuad(rect, textureInfo->m_textureId, - transparency); - } - m_texture->consumerRelease(); -} - -bool BaseTile::isTileReady() -{ - if (!m_texture) - return false; - if (m_texture->owner() != this) - return false; - - android::AutoMutex lock(m_atomicSync); - if (m_dirty) - return false; - - m_texture->consumerLock(); - bool ready = m_texture->readyFor(this); - m_texture->consumerRelease(); - - if (ready) - return true; - - m_dirty = true; - return false; -} - -void BaseTile::drawTileInfo(SkCanvas* canvas, - BackedDoubleBufferedTexture* texture, - int x, int y, float scale, - int pictureCount) -{ - SkPaint paint; - char str[256]; - snprintf(str, 256, "(%d,%d) %.2f, tl%x tx%x p%x c%x", - x, y, scale, this, texture, m_page, pictureCount); - paint.setARGB(255, 0, 0, 0); - canvas->drawText(str, strlen(str), 0, 10, paint); - paint.setARGB(255, 255, 0, 0); - canvas->drawText(str, strlen(str), 0, 11, paint); -} - -// This is called from the texture generation thread -void BaseTile::paintBitmap() -{ - - // We acquire the values below atomically. This ensures that we are reading - // values correctly across cores. Further, once we have these values they - // can be updated by other threads without consequence. - m_atomicSync.lock(); - bool dirty = m_dirty; - BackedDoubleBufferedTexture* texture = m_texture; - SkRegion dirtyArea = *m_currentDirtyArea; - float scale = m_scale; - const int x = m_x; - const int y = m_y; - m_atomicSync.unlock(); - - if (!dirty || !texture) { - return; - } - - TiledPage* tiledPage = m_page; - - texture->producerAcquireContext(); - TextureInfo* textureInfo = texture->producerLock(); - - // at this point we can safely check the ownership (if the texture got - // transferred to another BaseTile under us) - if (texture->owner() != this || texture->usedLevel() > 1) { - texture->producerRelease(); - return; - } - - SkSize size = texture->getSize(); - float tileWidth = size.width(); - float tileHeight = size.height(); - - const float invScale = 1 / scale; - float w = tileWidth * invScale; - float h = tileHeight * invScale; - - SkCanvas* canvas; - unsigned int pictureCount = 0; - - SkRegion::Iterator cliperator(dirtyArea); - - bool fullRepaint = false; - if (((m_currentDirtyArea == &m_dirtyAreaA) && m_fullRepaintA) || - ((m_currentDirtyArea == &m_dirtyAreaB) && m_fullRepaintB)) - fullRepaint = true; - - if (fullRepaint) { - SkIRect rect; - pictureCount = paintPartialBitmap(rect, 0, 0, scale, texture, - textureInfo, tiledPage, true); - } else { - while (!cliperator.done()) { - SkRect dirtyRect; - dirtyRect.set(cliperator.rect()); - - float left = x * tileWidth; - float top = y * tileHeight; - - // compute the rect to corresponds to pixels - SkRect realTileRect; - realTileRect.fLeft = left; - realTileRect.fTop = top; - realTileRect.fRight = left + tileWidth; - realTileRect.fBottom = top + tileHeight; - - // scale the dirtyRect for intersect computation. - SkRect realDirtyRect = SkRect::MakeWH(dirtyRect.width() * scale, - dirtyRect.height() * scale); - realDirtyRect.offset(dirtyRect.fLeft * scale, dirtyRect.fTop * scale); - - if (!realTileRect.intersect(realDirtyRect)) { - cliperator.next(); - continue; - } - - realTileRect.fLeft = floorf(realTileRect.fLeft); - realTileRect.fTop = floorf(realTileRect.fTop); - realTileRect.fRight = ceilf(realTileRect.fRight); - realTileRect.fBottom = ceilf(realTileRect.fBottom); - - SkIRect finalRealRect; - finalRealRect.fLeft = static_cast<int>(realTileRect.fLeft) % static_cast<int>(tileWidth); - finalRealRect.fTop = static_cast<int>(realTileRect.fTop) % static_cast<int>(tileHeight); - finalRealRect.fRight = finalRealRect.fLeft + realTileRect.width(); - finalRealRect.fBottom = finalRealRect.fTop + realTileRect.height(); - - // the canvas translate can be recomputed accounting for the scale - float tx = - realTileRect.fLeft / scale; - float ty = - realTileRect.fTop / scale; - - pictureCount = paintPartialBitmap(finalRealRect, tx, ty, scale, texture, - textureInfo, tiledPage); - - cliperator.next(); - } - } - XLOG("%x update texture %x for tile %d, %d scale %.2f (m_scale: %.2f)", this, textureInfo, x, y, scale, m_scale); - - m_atomicSync.lock(); - texture->setTile(textureInfo, x, y, scale, pictureCount); - texture->producerReleaseAndSwap(); - - if (texture == m_texture) { - m_lastPaintedPicture = pictureCount; - - // set the fullrepaint flags - - if ((m_currentDirtyArea == &m_dirtyAreaA) && m_fullRepaintA) - m_fullRepaintA = false; - - if ((m_currentDirtyArea == &m_dirtyAreaB) && m_fullRepaintB) - m_fullRepaintB = false; - - // The various checks to see if we are still dirty... - - m_dirty = false; - - if (m_scale != scale) - m_dirty = true; - - if (!fullRepaint) - m_currentDirtyArea->op(dirtyArea, SkRegion::kDifference_Op); - - if (!m_currentDirtyArea->isEmpty()) - m_dirty = true; - - // Now we can swap the dirty areas - - m_currentDirtyArea = m_currentDirtyArea == &m_dirtyAreaA ? &m_dirtyAreaB : &m_dirtyAreaA; - - if (!m_currentDirtyArea->isEmpty()) - m_dirty = true; - - if (!m_dirty) - m_usable = true; - } - - m_atomicSync.unlock(); -} - -int BaseTile::paintPartialBitmap(SkIRect r, float ptx, float pty, - float scale, BackedDoubleBufferedTexture* texture, - TextureInfo* textureInfo, - TiledPage* tiledPage, bool fullRepaint) -{ - SkIRect rect = r; - float tx = ptx; - float ty = pty; - if (!texture->textureExist(textureInfo)) { - fullRepaint = true; - } - - if ((rect.width() > TilesManager::instance()->tileWidth()) || - (rect.height() > TilesManager::instance()->tileHeight())) - fullRepaint = true; - - if (fullRepaint) { - rect.set(0, 0, TilesManager::instance()->tileWidth(), - TilesManager::instance()->tileHeight()); - tx = - x() * TilesManager::instance()->tileWidth() / scale; - ty = - y() * TilesManager::instance()->tileHeight() / scale; - } - - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); - bitmap.allocPixels(); - bitmap.eraseColor(0); - - SkCanvas canvas(bitmap); - canvas.drawARGB(255, 255, 255, 255); - - SkPicture picture; - SkCanvas* nCanvas = picture.beginRecording(rect.width(), rect.height()); - nCanvas->scale(scale, scale); - nCanvas->translate(tx, ty); - int pictureCount = tiledPage->paintBaseLayerContent(nCanvas); - picture.endRecording(); - - bool visualIndicator = TilesManager::instance()->getShowVisualIndicator(); - if (visualIndicator) - canvas.save(); - picture.draw(&canvas); - if (visualIndicator) - canvas.restore(); - - if (visualIndicator) { - int color = 20 + pictureCount % 100; - canvas.drawARGB(color, 0, 255, 0); - - SkPaint paint; - paint.setARGB(128, 255, 0, 0); - paint.setStrokeWidth(3); - canvas.drawLine(0, 0, rect.width(), rect.height(), paint); - paint.setARGB(128, 0, 255, 0); - canvas.drawLine(0, rect.height(), rect.width(), 0, paint); - paint.setARGB(128, 0, 0, 255); - canvas.drawLine(0, 0, rect.width(), 0, paint); - canvas.drawLine(rect.width(), 0, rect.width(), rect.height(), paint); - - drawTileInfo(&canvas, texture, x(), y(), scale, pictureCount); - } - - if (!texture->textureExist(textureInfo)) { - GLUtils::createTextureWithBitmap(textureInfo->m_textureId, bitmap); - textureInfo->m_width = rect.width(); - textureInfo->m_height = rect.height(); - } else { - GLUtils::updateTextureWithBitmap(textureInfo->m_textureId, rect.fLeft, rect.fTop, bitmap); - } - - bitmap.reset(); - - return pictureCount; -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/BaseTile.h b/WebCore/platform/graphics/android/BaseTile.h deleted file mode 100644 index 7b28f76..0000000 --- a/WebCore/platform/graphics/android/BaseTile.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 BaseTile_h -#define BaseTile_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "HashMap.h" -#include "SharedTexture.h" -#include "SkBitmap.h" -#include "SkCanvas.h" -#include "SkRect.h" -#include "SkRegion.h" -#include "TextureOwner.h" - -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES2/gl2.h> -#include <utils/threads.h> - -namespace WebCore { - -class TiledPage; -class BackedDoubleBufferedTexture; - -/** - * An individual tile that is used to construct part of a webpage's BaseLayer of - * content. Each tile is assigned to a TiledPage and is responsible for drawing - * and displaying their section of the page. The lifecycle of a tile is: - * - * 1. Each tile is created on the main GL thread and assigned to a specific - * location within a TiledPage. - * 2. When needed the tile is passed to the background thread where it paints - * the BaseLayer's most recent PictureSet to a bitmap which is then uploaded - * to the GPU. - * 3. After the bitmap is uploaded to the GPU the main GL thread then uses the - * tile's draw() function to display the tile to the screen. - * 4. Steps 2-3 are repeated as necessary. - * 5. The tile is destroyed when the user navigates to a new page. - * - */ -class BaseTile : public TextureOwner { -public: - BaseTile(); - ~BaseTile(); - - void setContents(TiledPage* page, int x, int y); - bool isAvailable() const { return !m_texture; } - - void reserveTexture(); - void setUsedLevel(int); - int usedLevel(); - bool isTileReady(); - void draw(float transparency, SkRect& rect, float scale); - - // the only thread-safe function called by the background thread - void paintBitmap(); - int paintPartialBitmap(SkIRect rect, float tx, float ty, - float scale, BackedDoubleBufferedTexture* texture, - TextureInfo* textureInfo, - TiledPage* tiledPage, - bool fullRepaint = false); - void drawTileInfo(SkCanvas* canvas, - BackedDoubleBufferedTexture* texture, - int x, int y, float scale, int pictureCount); - - void markAsDirty(const unsigned int pictureCount, - const SkRegion& dirtyArea); - bool isDirty(); - bool isRepaintPending(); - void setRepaintPending(bool pending); - void setUsable(bool usable); - float scale() const { return m_scale; } - void setScale(float scale); - void fullInval(); - - int x() const { return m_x; } - int y() const { return m_y; } - unsigned int lastPaintedPicture() const { return m_lastPaintedPicture; } - BackedDoubleBufferedTexture* texture() { return m_texture; } - - // TextureOwner implementation - virtual bool removeTexture(BackedDoubleBufferedTexture* texture); - virtual TiledPage* page() { return m_page; } - -private: - // these variables are only set when the object is constructed - TiledPage* m_page; - int m_x; - int m_y; - - // The remaining variables can be updated throughout the lifetime of the object - BackedDoubleBufferedTexture* m_texture; - float m_scale; - // used to signal that the that the tile is out-of-date and needs to be redrawn - bool m_dirty; - // used to signal that a repaint is pending - bool m_repaintPending; - // used to signal whether or not the draw can use this tile. - bool m_usable; - // stores the id of the latest picture from webkit that caused this tile to - // become dirty. A tile is no longer dirty when it has been painted with a - // picture that is newer than this value. - unsigned int m_lastDirtyPicture; - - // store the dirty region - SkRegion m_dirtyAreaA; - SkRegion m_dirtyAreaB; - bool m_fullRepaintA; - bool m_fullRepaintB; - SkRegion* m_currentDirtyArea; - - // stores the id of the latest picture painted to the tile. If the id is 0 - // then we know that the picture has not yet been painted an there is nothing - // to display (dirty or otherwise). - unsigned int m_lastPaintedPicture; - - // This mutex serves two purposes. (1) It ensures that certain operations - // happen atomically and (2) it makes sure those operations are synchronized - // across all threads and cores. - android::Mutex m_atomicSync; - -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) -#endif // BaseTile_h diff --git a/WebCore/platform/graphics/android/BitmapAllocatorAndroid.cpp b/WebCore/platform/graphics/android/BitmapAllocatorAndroid.cpp deleted file mode 100644 index 66340ee..0000000 --- a/WebCore/platform/graphics/android/BitmapAllocatorAndroid.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "BitmapAllocatorAndroid.h" -#include "SharedBufferStream.h" -#include "SkImageRef_GlobalPool.h" -#include "SkImageRef_ashmem.h" - -// made this up, so we don't waste a file-descriptor on small images, plus -// we don't want to lose too much on the round-up to a page size (4K) -#define MIN_ASHMEM_ALLOC_SIZE (32*1024) - - -static bool should_use_ashmem(const SkBitmap& bm) { - return bm.getSize() >= MIN_ASHMEM_ALLOC_SIZE; -} - -/////////////////////////////////////////////////////////////////////////////// - -namespace WebCore { - -BitmapAllocatorAndroid::BitmapAllocatorAndroid(SharedBuffer* data, - int sampleSize) -{ - fStream = new SharedBufferStream(data); - fSampleSize = sampleSize; -} - -BitmapAllocatorAndroid::~BitmapAllocatorAndroid() -{ - fStream->unref(); -} - -bool BitmapAllocatorAndroid::allocPixelRef(SkBitmap* bitmap, SkColorTable*) -{ - SkPixelRef* ref; - if (should_use_ashmem(*bitmap)) { -// SkDebugf("ashmem [%d %d]\n", bitmap->width(), bitmap->height()); - ref = new SkImageRef_ashmem(fStream, bitmap->config(), fSampleSize); - } else { -// SkDebugf("globalpool [%d %d]\n", bitmap->width(), bitmap->height()); - ref = new SkImageRef_GlobalPool(fStream, bitmap->config(), fSampleSize); - } - bitmap->setPixelRef(ref)->unref(); - return true; -} - -} diff --git a/WebCore/platform/graphics/android/BitmapAllocatorAndroid.h b/WebCore/platform/graphics/android/BitmapAllocatorAndroid.h deleted file mode 100644 index 11716e3..0000000 --- a/WebCore/platform/graphics/android/BitmapAllocatorAndroid.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 WebCore_BitmapAllocatorAndroid_DEFINED -#define WebCore_BitmapAllocatorAndroid_DEFINED - -#include "SkBitmap.h" - -namespace WebCore { - - class SharedBuffer; - class SharedBufferStream; - - /** Returns a custom allocator that takes advantage of ashmem and global - pools to best manage the pixel memory for a decoded image. This should - be used for images that are logically immutable, and can be re-decoded - at will based on available memory. - */ - class BitmapAllocatorAndroid : public SkBitmap::Allocator { - public: - BitmapAllocatorAndroid(SharedBuffer* data, int sampleSize); - virtual ~BitmapAllocatorAndroid(); - - // overrides - virtual bool allocPixelRef(SkBitmap*, SkColorTable*); - - private: - SharedBufferStream* fStream; - int fSampleSize; - }; - -} - -size_t computeMaxBitmapSizeForCache(); - -#endif diff --git a/WebCore/platform/graphics/android/ClassTracker.cpp b/WebCore/platform/graphics/android/ClassTracker.cpp deleted file mode 100644 index ad2b4dd..0000000 --- a/WebCore/platform/graphics/android/ClassTracker.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "ClassTracker.h" - -#include <cutils/log.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ClassTracker", __VA_ARGS__) - -namespace WebCore { - -ClassTracker* ClassTracker::instance() -{ - if (!gInstance) - gInstance = new ClassTracker(); - return gInstance; -} - -ClassTracker* ClassTracker::gInstance = 0; - -void ClassTracker::increment(String name) -{ - int value = 0; - if (m_classes.contains(name)) - value = m_classes.get(name); - - m_classes.set(name, value + 1); -} - -void ClassTracker::decrement(String name) -{ - int value = 0; - if (m_classes.contains(name)) - value = m_classes.get(name); - - m_classes.set(name, value - 1); -} - -void ClassTracker::show() -{ - XLOG("*** Tracking %d classes ***", m_classes.size()); - for (HashMap<String, int>::iterator iter = m_classes.begin(); iter != m_classes.end(); ++iter) { - XLOG("class %s has %d instances", - iter->first.latin1().data(), iter->second); - } -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/android/ClassTracker.h b/WebCore/platform/graphics/android/ClassTracker.h deleted file mode 100644 index 0afde59..0000000 --- a/WebCore/platform/graphics/android/ClassTracker.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 ClassTracker_h -#define ClassTracker_h - -#include <wtf/HashMap.h> -#include <wtf/text/StringHash.h> - -#define DEBUG_COUNT // Add instances tracking -#undef DEBUG_COUNT - -namespace WebCore { - -class ClassTracker { - public: - static ClassTracker* instance(); - void show(); - void increment(String name); - void decrement(String name); - private: - ClassTracker() {}; - HashMap<String, int> m_classes; - static ClassTracker* gInstance; -}; - -} - -#endif // ClassTracker_h diff --git a/WebCore/platform/graphics/android/DeleteTextureOperation.h b/WebCore/platform/graphics/android/DeleteTextureOperation.h deleted file mode 100644 index 32717a0..0000000 --- a/WebCore/platform/graphics/android/DeleteTextureOperation.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 DeleteTextureOperation_h -#define DeleteTextureOperation_h - -#include "GLUtils.h" -#include "QueuedOperation.h" - -namespace WebCore { - -class DeleteTextureOperation : public QueuedOperation { - public: - DeleteTextureOperation(GLuint textureId, EGLImageKHR eglImage) - : QueuedOperation(QueuedOperation::DeleteTexture, 0) - , m_textureId(textureId) - , m_eglImage(eglImage) {} - virtual bool operator==(const QueuedOperation* operation) - { - if (operation->type() != type()) - return false; - const DeleteTextureOperation* op = static_cast<const DeleteTextureOperation*>(operation); - return op->m_textureId == m_textureId; - } - virtual void run() - { - if (m_textureId) - GLUtils::deleteTexture(&m_textureId); - if (m_eglImage) - eglDestroyImageKHR(eglGetCurrentDisplay(), m_eglImage); - } - private: - GLuint m_textureId; - EGLImageKHR m_eglImage; -}; - -} - -#endif // DeleteTextureOperation_h diff --git a/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp deleted file mode 100644 index 395bb2b..0000000 --- a/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "DoubleBufferedTexture.h" - -#include "ClassTracker.h" -#include "GLUtils.h" - -#define LOG_NDEBUG 1 -#define LOG_TAG "DoubleBufferedTexture.cpp" -#include <utils/Log.h> - -namespace WebCore { - -DoubleBufferedTexture::DoubleBufferedTexture(EGLContext sharedContext) -{ - m_display = eglGetCurrentDisplay(); - m_pContext = EGL_NO_CONTEXT; - m_cContext = sharedContext; - m_writeableTexture = &m_textureA; - m_lockedConsumerTexture = GL_NO_TEXTURE; - m_supportsEGLImage = GLUtils::isEGLImageSupported(); -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("DoubleBufferedTexture"); -#endif -} - -DoubleBufferedTexture::~DoubleBufferedTexture() -{ -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("DoubleBufferedTexture"); -#endif -} - -SharedTexture* DoubleBufferedTexture::getWriteableTexture() -{ - return reinterpret_cast<SharedTexture*>( - android_atomic_release_load((int32_t*)&m_writeableTexture)); -} - -SharedTexture* DoubleBufferedTexture::getReadableTexture() -{ - return (getWriteableTexture() != &m_textureA) ? &m_textureA : &m_textureB; -} - -EGLContext DoubleBufferedTexture::producerAcquireContext() -{ - - if (m_pContext != EGL_NO_CONTEXT) { - LOGV("AquireContext has previously generated a context.\n"); - return m_pContext; - } - - // check to see if a context already exists on this thread - EGLContext context = eglGetCurrentContext(); - - // if no context exists then create one - if (context == EGL_NO_CONTEXT) { - EGLContext sharedContext = m_supportsEGLImage ? EGL_NO_CONTEXT : m_cContext; - context = GLUtils::createBackgroundContext(sharedContext); - } - - if (context == EGL_NO_CONTEXT) { - LOGE("eglCreateContext failed"); - return EGL_NO_CONTEXT; - } - - // initialize the producer's textures - m_textureA.lock(); - m_textureB.lock(); - m_textureA.initSourceTexture(); - m_textureB.initSourceTexture(); - LOGV("Initialized Textures A/B (%d:%d)", m_textureA.getSourceTextureId(), - m_textureB.getSourceTextureId()); - m_textureA.unlock(); - m_textureB.unlock(); - - m_pContext = context; - return context; -} - -void DoubleBufferedTexture::producerDeleteTextures() -{ - m_textureA.lock(); - m_textureB.lock(); - LOGV("Deleting Producer Textures A/B (%d:%d)", m_textureA.getSourceTextureId(), - m_textureB.getSourceTextureId()); - m_textureA.deleteSourceTexture(); - m_textureB.deleteSourceTexture(); - m_textureA.unlock(); - m_textureB.unlock(); -} - -void DoubleBufferedTexture::consumerDeleteTextures() -{ - m_textureA.lock(); - m_textureB.lock(); - LOGV("Deleting Consumer Textures A/B (%d:%d)", m_textureA.getTargetTextureId(), - m_textureB.getTargetTextureId()); - m_textureA.deleteTargetTexture(); - m_textureB.deleteTargetTexture(); - m_textureA.unlock(); - m_textureB.unlock(); -} - -TextureInfo* DoubleBufferedTexture::producerLock() -{ - SharedTexture* sharedTex = getWriteableTexture(); - LOGV("Acquiring P Lock (%d)", sharedTex->getSourceTextureId()); - TextureInfo* texInfo = sharedTex->lockSource(); - LOGV("Acquired P Lock"); - - return texInfo; -} - -void DoubleBufferedTexture::producerRelease() -{ - // get the writable texture and unlock it - SharedTexture* sharedTex = getWriteableTexture(); - LOGV("Releasing P Lock (%d)", sharedTex->getSourceTextureId()); - sharedTex->releaseSource(); - LOGV("Released P Lock (%d)", sharedTex->getSourceTextureId()); -} - -void DoubleBufferedTexture::producerReleaseAndSwap() -{ - producerRelease(); - - // swap the front and back buffers using an atomic op for the memory barrier - android_atomic_acquire_store((int32_t)getReadableTexture(), (int32_t*)&m_writeableTexture); -} - -TextureInfo* DoubleBufferedTexture::consumerLock() -{ - SharedTexture* sharedTex = getReadableTexture(); - LOGV("Acquiring C Lock (%d)", sharedTex->getSourceTextureId()); - m_lockedConsumerTexture = sharedTex; - - TextureInfo* texInfo = sharedTex->lockTarget(); - LOGV("Acquired C Lock"); - - if (!texInfo) - LOGV("Released C Lock (Empty)"); - - return texInfo; -} - -void DoubleBufferedTexture::consumerRelease() -{ - // we must check to see what texture the consumer had locked since the - // producer may have swapped out the readable buffer - SharedTexture* sharedTex = m_lockedConsumerTexture; - sharedTex->releaseTarget(); - LOGV("Released C Lock (%d)", sharedTex->getSourceTextureId()); -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/android/DoubleBufferedTexture.h b/WebCore/platform/graphics/android/DoubleBufferedTexture.h deleted file mode 100644 index ba56c0e..0000000 --- a/WebCore/platform/graphics/android/DoubleBufferedTexture.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 DoubleBufferedTexture_h -#define DoubleBufferedTexture_h - -#include "SharedTexture.h" -#include <EGL/egl.h> - -namespace WebCore { - -class DoubleBufferedTexture { -public: - // consumer thread functions - DoubleBufferedTexture(EGLContext sharedContext); - virtual ~DoubleBufferedTexture(); - - // provider thread functions - virtual TextureInfo* producerLock(); - virtual void producerRelease(); - virtual void producerReleaseAndSwap(); - EGLContext producerAcquireContext(); - void producerDeleteTextures(); - - // consumer thread functions - TextureInfo* consumerLock(); - void consumerRelease(); - void consumerDeleteTextures(); - -protected: - SharedTexture* getReadableTexture(); - SharedTexture* getWriteableTexture(); - - SharedTexture m_textureA; - SharedTexture m_textureB; - -private: - - SharedTexture* m_writeableTexture; - SharedTexture* m_lockedConsumerTexture; // only used by the consumer - - EGLDisplay m_display; - EGLContext m_pContext; - EGLContext m_cContext; - - bool m_supportsEGLImage; -}; - -} // namespace WebCore - -#endif // DoubleBufferedTexture_h diff --git a/WebCore/platform/graphics/android/FontAndroid.cpp b/WebCore/platform/graphics/android/FontAndroid.cpp deleted file mode 100644 index 6966e7d..0000000 --- a/WebCore/platform/graphics/android/FontAndroid.cpp +++ /dev/null @@ -1,1043 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * Copyright (C) 2006 Apple Computer, 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "EmojiFont.h" -#include "Font.h" -#include "FontData.h" -#include "FontFallbackList.h" -#include "GraphicsContext.h" -#include "GlyphBuffer.h" -#include "IntRect.h" -#include "NotImplemented.h" -#include "PlatformGraphicsContext.h" -#include "SkCanvas.h" -#include "SkColorFilter.h" -#include "SkLayerDrawLooper.h" -#include "SkPaint.h" -#include "SkTemplates.h" -#include "SkTypeface.h" -#include "SkUtils.h" - -#ifdef SUPPORT_COMPLEX_SCRIPTS -#include "HarfbuzzSkia.h" -#include <unicode/normlzr.h> -#include <unicode/uchar.h> -#include <wtf/OwnArrayPtr.h> -#include <wtf/OwnPtr.h> -#include <wtf/unicode/Unicode.h> -#endif - -using namespace android; - -namespace WebCore { - -static void updateForFont(SkPaint* paint, const SimpleFontData* font) { - font->platformData().setupPaint(paint); - paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); -} - -static SkPaint* setupFill(SkPaint* paint, GraphicsContext* gc, - const SimpleFontData* font) { - gc->setupFillPaint(paint); - updateForFont(paint, font); - return paint; -} - -static SkPaint* setupStroke(SkPaint* paint, GraphicsContext* gc, - const SimpleFontData* font) { - gc->setupStrokePaint(paint); - updateForFont(paint, font); - return paint; -} - -static bool setupForText(SkPaint* paint, GraphicsContext* gc, - const SimpleFontData* font) { - int mode = gc->textDrawingMode() & (TextModeFill | TextModeStroke); - if (!mode) - return false; - - FloatSize shadowOffset; - float shadowBlur; - Color shadowColor; - ColorSpace shadowColorSpace; - bool hasShadow = gc->getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace); - bool hasBothStrokeAndFill = - (mode & (TextModeStroke | TextModeFill)) == (TextModeStroke | TextModeFill); - if (hasShadow || hasBothStrokeAndFill) { - SkLayerDrawLooper* looper = new SkLayerDrawLooper; - paint->setLooper(looper)->unref(); - - // Specify the behavior of the looper - SkLayerDrawLooper::LayerInfo info; - info.fPaintBits = SkLayerDrawLooper::kEntirePaint_Bits; - info.fColorMode = SkXfermode::kSrc_Mode; - - // The paint is only valid until the looper receives another call to - // addLayer(). Therefore, we must cache certain state for later use. - bool hasFillPaint = false; - bool hasStrokePaint = false; - SkScalar strokeWidth; - - if ((mode & TextModeStroke) && gc->willStroke()) { - strokeWidth = setupStroke(looper->addLayer(info), gc, font)->getStrokeWidth(); - hasStrokePaint = true; - } - if ((mode & TextModeFill) && gc->willFill()) { - setupFill(looper->addLayer(info), gc, font); - hasFillPaint = true; - } - - if (hasShadow) { - SkPaint shadowPaint; - SkPoint offset; - if (gc->setupShadowPaint(&shadowPaint, &offset)) { - - // add an offset to the looper when creating a shadow layer - info.fOffset.set(offset.fX, offset.fY); - - SkPaint* p = looper->addLayer(info); - *p = shadowPaint; - - // Currently, only GraphicsContexts associated with the - // HTMLCanvasElement have shadows ignore transforms set. This - // allows us to distinguish between CSS and Canvas shadows which - // have different rendering specifications. - if (gc->shadowsIgnoreTransforms()) { - SkColorFilter* cf = SkColorFilter::CreateModeFilter(p->getColor(), - SkXfermode::kSrcIn_Mode); - p->setColorFilter(cf)->unref(); - } else { // in CSS - p->setShader(NULL); - } - - if (hasStrokePaint && !hasFillPaint) { - // stroke the shadow if we have stroke but no fill - p->setStyle(SkPaint::kStroke_Style); - p->setStrokeWidth(strokeWidth); - } - updateForFont(p, font); - } - } - } else if (mode & TextModeFill) { - (void)setupFill(paint, gc, font); - } else if (mode & TextModeStroke) { - (void)setupStroke(paint, gc, font); - } else { - return false; - } - return true; -} - -bool Font::canReturnFallbackFontsForComplexText() -{ - return false; -} - -void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, - const GlyphBuffer& glyphBuffer, int from, int numGlyphs, - const FloatPoint& point) const -{ - // compile-time assert - SkASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t)); - - SkPaint paint; - if (!setupForText(&paint, gc, font)) { - return; - } - - SkScalar x = SkFloatToScalar(point.x()); - SkScalar y = SkFloatToScalar(point.y()); - const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from); - const GlyphBufferAdvance* adv = glyphBuffer.advances(from); - SkAutoSTMalloc<32, SkPoint> storage(numGlyphs); - SkPoint* pos = storage.get(); - - SkCanvas* canvas = gc->platformContext()->mCanvas; - - /* We need an array of [x,y,x,y,x,y,...], but webkit is giving us - point.xy + [width, height, width, height, ...], so we have to convert - */ - - if (EmojiFont::IsAvailable()) { - // set filtering, to make scaled images look nice(r) - paint.setFilterBitmap(true); - - int localIndex = 0; - int localCount = 0; - for (int i = 0; i < numGlyphs; i++) { - if (EmojiFont::IsEmojiGlyph(glyphs[i])) { - if (localCount) - canvas->drawPosText(&glyphs[localIndex], - localCount * sizeof(uint16_t), - &pos[localIndex], paint); - EmojiFont::Draw(canvas, glyphs[i], x, y, paint); - // reset local index/count track for "real" glyphs - localCount = 0; - localIndex = i + 1; - } else { - pos[i].set(x, y); - localCount += 1; - } - x += SkFloatToScalar(adv[i].width()); - y += SkFloatToScalar(adv[i].height()); - } - // draw the last run of glyphs (if any) - if (localCount) - canvas->drawPosText(&glyphs[localIndex], - localCount * sizeof(uint16_t), - &pos[localIndex], paint); - } else { - for (int i = 0; i < numGlyphs; i++) { - pos[i].set(x, y); - x += SkFloatToScalar(adv[i].width()); - y += SkFloatToScalar(adv[i].height()); - } - canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint); - } -} - -void Font::drawEmphasisMarksForComplexText(WebCore::GraphicsContext*, WebCore::TextRun const&, WTF::AtomicString const&, WebCore::FloatPoint const&, int, int) const -{ - notImplemented(); -} - -#ifndef SUPPORT_COMPLEX_SCRIPTS - -FloatRect Font::selectionRectForComplexText(const TextRun& run, - const FloatPoint& point, int h, int, int) const -{ - SkPaint paint; - SkScalar width, left; - SkPaint::FontMetrics metrics; - - primaryFont()->platformData().setupPaint(&paint); - - width = paint.measureText(run.characters(), run.length() << 1); - SkScalar spacing = paint.getFontMetrics(&metrics); - - return FloatRect(point.x(), - point.y(), - roundf(SkScalarToFloat(width)), - roundf(SkScalarToFloat(spacing))); -} - -void Font::drawComplexText(GraphicsContext* gc, TextRun const& run, - FloatPoint const& point, int, int) const -{ - SkCanvas* canvas = gc->platformContext()->mCanvas; - SkPaint paint; - - if (!setupForText(&paint, gc, primaryFont())) { - return; - } - - // go to chars, instead of glyphs, which was set by setupForText() - paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - - canvas->drawText(run.characters(), run.length() << 1, - SkFloatToScalar(point.x()), SkFloatToScalar(point.y()), - paint); -} - -float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>*, GlyphOverflow*) const -{ - SkPaint paint; - - primaryFont()->platformData().setupPaint(&paint); - -//printf("--------- complext measure %d chars\n", run.to() - run.from()); - - SkScalar width = paint.measureText(run.characters(), run.length() << 1); - return SkScalarToFloat(width); -} - -int Font::offsetForPositionForComplexText(const TextRun& run, float x, - bool includePartialGlyphs) const -{ - SkPaint paint; - int count = run.length(); - SkAutoSTMalloc<64, SkScalar> storage(count); - SkScalar* widths = storage.get(); - - primaryFont()->platformData().setupPaint(&paint); - - count = paint.getTextWidths(run.characters(), count << 1, widths); - - if (count > 0) - { - SkScalar pos = 0; - for (int i = 0; i < count; i++) - { - if (x < SkScalarRound(pos + SkScalarHalf(widths[i]))) - return i; - pos += widths[i]; - } - } - return count; -} - -#else - -// TODO Should we remove the multilayer support? -// If yes. remove isCanvasMultiLayered() and adjustTextRenderMode(). -static bool isCanvasMultiLayered(SkCanvas* canvas) -{ - SkCanvas::LayerIter layerIterator(canvas, false); - layerIterator.next(); - return !layerIterator.done(); -} - -static void adjustTextRenderMode(SkPaint* paint, bool isCanvasMultiLayered) -{ - // Our layers only have a single alpha channel. This means that subpixel - // rendered text cannot be compositied correctly when the layer is - // collapsed. Therefore, subpixel text is disabled when we are drawing - // onto a layer. - if (isCanvasMultiLayered) - paint->setLCDRenderText(false); -} - -// Harfbuzz uses 26.6 fixed point values for pixel offsets. However, we don't -// handle subpixel positioning so this function is used to truncate Harfbuzz -// values to a number of pixels. -static int truncateFixedPointToInteger(HB_Fixed value) -{ - return value >> 6; -} - -// TextRunWalker walks a TextRun and presents each script run in sequence. A -// TextRun is a sequence of code-points with the same embedding level (i.e. they -// are all left-to-right or right-to-left). A script run is a subsequence where -// all the characters have the same script (e.g. Arabic, Thai etc). Shaping is -// only ever done with script runs since the shapers only know how to deal with -// a single script. -// -// After creating it, the script runs are either iterated backwards or forwards. -// It defaults to backwards for RTL and forwards otherwise (which matches the -// presentation order), however you can set it with |setBackwardsIteration|. -// -// Once you have setup the object, call |nextScriptRun| to get the first script -// run. This will return false when the iteration is complete. At any time you -// can call |reset| to start over again. -class TextRunWalker { -public: - TextRunWalker(const TextRun&, unsigned, const Font*); - ~TextRunWalker(); - - bool isWordBreak(unsigned, bool); - // setPadding sets a number of pixels to be distributed across the TextRun. - // WebKit uses this to justify text. - void setPadding(int); - void reset(); - void setBackwardsIteration(bool); - // Advance to the next script run, returning false when the end of the - // TextRun has been reached. - bool nextScriptRun(); - float widthOfFullRun(); - - // setWordSpacingAdjustment sets a delta (in pixels) which is applied at - // each word break in the TextRun. - void setWordSpacingAdjustment(int wordSpacingAdjustment) - { - m_wordSpacingAdjustment = wordSpacingAdjustment; - } - - // setLetterSpacingAdjustment sets an additional number of pixels that is - // added to the advance after each output cluster. This matches the behaviour - // of WidthIterator::advance. - // - // (NOTE: currently does nothing because I don't know how to get the - // cluster information from Harfbuzz.) - void setLetterSpacingAdjustment(int letterSpacingAdjustment) - { - m_letterSpacing = letterSpacingAdjustment; - } - - // setWordAndLetterSpacing calls setWordSpacingAdjustment() and - // setLetterSpacingAdjustment() to override m_wordSpacingAdjustment - // and m_letterSpacing. - void setWordAndLetterSpacing(int wordSpacingAdjustment, int letterSpacingAdjustment); - - // Set the x offset for the next script run. This affects the values in - // |xPositions| - void setXOffsetToZero() { m_offsetX = 0; } - bool rtl() const { return m_run.rtl(); } - const uint16_t* glyphs() const { return m_glyphs16; } - - // Return the length of the array returned by |glyphs| - unsigned length() const { return m_item.num_glyphs; } - - // Return the x offset for each of the glyphs. Note that this is translated - // by the current x offset and that the x offset is updated for each script - // run. - const SkScalar* xPositions() const { return m_xPositions; } - - // Get the advances (widths) for each glyph. - const HB_Fixed* advances() const { return m_item.advances; } - - // Return the width (in px) of the current script run. - unsigned width() const { return m_pixelWidth; } - - // Return the cluster log for the current script run. For example: - // script run: f i a n c é (fi gets ligatured) - // log clutrs: 0 0 1 2 3 4 - // So, for each input code point, the log tells you which output glyph was - // generated for it. - const unsigned short* logClusters() const { return m_item.log_clusters; } - - // return the number of code points in the current script run - unsigned numCodePoints() const { return m_numCodePoints; } - - const FontPlatformData* fontPlatformDataForScriptRun() { - return reinterpret_cast<FontPlatformData*>(m_item.font->userData); - } - -private: - void setupFontForScriptRun(); - HB_FontRec* allocHarfbuzzFont(); - void deleteGlyphArrays(); - void createGlyphArrays(int); - void resetGlyphArrays(); - void shapeGlyphs(); - void setGlyphXPositions(bool); - - static void normalizeSpacesAndMirrorChars(const UChar* source, bool rtl, - UChar* destination, int length); - static const TextRun& getNormalizedTextRun(const TextRun& originalRun, - OwnPtr<TextRun>& normalizedRun, OwnArrayPtr<UChar>& normalizedBuffer); - - // This matches the logic in RenderBlock::findNextLineBreak - static bool isCodepointSpace(HB_UChar16 c) { return c == ' ' || c == '\t'; } - - const Font* const m_font; - HB_ShaperItem m_item; - uint16_t* m_glyphs16; // A vector of 16-bit glyph ids. - SkScalar* m_xPositions; // A vector of x positions for each glyph. - ssize_t m_indexOfNextScriptRun; // Indexes the script run in |m_run|. - const unsigned m_startingX; // Offset in pixels of the first script run. - unsigned m_offsetX; // Offset in pixels to the start of the next script run. - unsigned m_pixelWidth; // Width (in px) of the current script run. - unsigned m_numCodePoints; // Code points in current script run. - unsigned m_glyphsArrayCapacity; // Current size of all the Harfbuzz arrays. - - OwnPtr<TextRun> m_normalizedRun; - OwnArrayPtr<UChar> m_normalizedBuffer; // A buffer for normalized run. - const TextRun& m_run; - bool m_iterateBackwards; - int m_wordSpacingAdjustment; // delta adjustment (pixels) for each word break. - float m_padding; // pixels to be distributed over the line at word breaks. - float m_padPerWordBreak; // pixels to be added to each word break. - float m_padError; // |m_padPerWordBreak| might have a fractional component. - // Since we only add a whole number of padding pixels at - // each word break we accumulate error. This is the - // number of pixels that we are behind so far. - unsigned m_letterSpacing; // pixels to be added after each glyph. -}; - - -TextRunWalker::TextRunWalker(const TextRun& run, unsigned startingX, const Font* font) - : m_font(font) - , m_startingX(startingX) - , m_offsetX(m_startingX) - , m_run(getNormalizedTextRun(run, m_normalizedRun, m_normalizedBuffer)) - , m_iterateBackwards(m_run.rtl()) - , m_wordSpacingAdjustment(0) - , m_padding(0) - , m_padPerWordBreak(0) - , m_padError(0) - , m_letterSpacing(0) -{ - // Do not use |run| inside this constructor. Use |m_run| instead. - - memset(&m_item, 0, sizeof(m_item)); - // We cannot know, ahead of time, how many glyphs a given script run - // will produce. We take a guess that script runs will not produce more - // than twice as many glyphs as there are code points plus a bit of - // padding and fallback if we find that we are wrong. - createGlyphArrays((m_run.length() + 2) * 2); - - m_item.log_clusters = new unsigned short[m_run.length()]; - - m_item.face = 0; - m_item.font = allocHarfbuzzFont(); - - m_item.item.bidiLevel = m_run.rtl(); - - m_item.string = m_run.characters(); - m_item.stringLength = m_run.length(); - - reset(); -} - -TextRunWalker::~TextRunWalker() -{ - fastFree(m_item.font); - deleteGlyphArrays(); - delete[] m_item.log_clusters; -} - -bool TextRunWalker::isWordBreak(unsigned index, bool isRTL) -{ - if (!isRTL) - return index && isCodepointSpace(m_item.string[index]) - && !isCodepointSpace(m_item.string[index - 1]); - return index != m_item.stringLength - 1 && isCodepointSpace(m_item.string[index]) - && !isCodepointSpace(m_item.string[index + 1]); -} - -// setPadding sets a number of pixels to be distributed across the TextRun. -// WebKit uses this to justify text. -void TextRunWalker::setPadding(int padding) -{ - m_padding = padding; - if (!m_padding) - return; - - // If we have padding to distribute, then we try to give an equal - // amount to each space. The last space gets the smaller amount, if - // any. - unsigned numWordBreaks = 0; - bool isRTL = m_iterateBackwards; - - for (unsigned i = 0; i < m_item.stringLength; i++) { - if (isWordBreak(i, isRTL)) - numWordBreaks++; - } - - if (numWordBreaks) - m_padPerWordBreak = m_padding / numWordBreaks; - else - m_padPerWordBreak = 0; -} - -void TextRunWalker::reset() -{ - if (m_iterateBackwards) - m_indexOfNextScriptRun = m_run.length() - 1; - else - m_indexOfNextScriptRun = 0; - m_offsetX = m_startingX; -} - -void TextRunWalker::setBackwardsIteration(bool isBackwards) -{ - m_iterateBackwards = isBackwards; - reset(); -} - -// Advance to the next script run, returning false when the end of the -// TextRun has been reached. -bool TextRunWalker::nextScriptRun() -{ - if (m_iterateBackwards) { - // In right-to-left mode we need to render the shaped glyph backwards and - // also render the script runs themselves backwards. So given a TextRun: - // AAAAAAACTTTTTTT (A = Arabic, C = Common, T = Thai) - // we render: - // TTTTTTCAAAAAAA - // (and the glyphs in each A, C and T section are backwards too) - if (!hb_utf16_script_run_prev(&m_numCodePoints, &m_item.item, m_run.characters(), - m_run.length(), &m_indexOfNextScriptRun)) - return false; - } else { - if (!hb_utf16_script_run_next(&m_numCodePoints, &m_item.item, m_run.characters(), - m_run.length(), &m_indexOfNextScriptRun)) - return false; - - // It is actually wrong to consider script runs at all in this code. - // Other WebKit code (e.g. Mac) segments complex text just by finding - // the longest span of text covered by a single font. - // But we currently need to call hb_utf16_script_run_next anyway to fill - // in the harfbuzz data structures to e.g. pick the correct script's shaper. - // So we allow that to run first, then do a second pass over the range it - // found and take the largest subregion that stays within a single font. - const FontData* glyphData = m_font->glyphDataForCharacter( - m_item.string[m_item.item.pos], false).fontData; - unsigned endOfRun; - for (endOfRun = 1; endOfRun < m_item.item.length; ++endOfRun) { - const FontData* nextGlyphData = m_font->glyphDataForCharacter( - m_item.string[m_item.item.pos + endOfRun], false).fontData; - if (nextGlyphData != glyphData) - break; - } - m_item.item.length = endOfRun; - m_indexOfNextScriptRun = m_item.item.pos + endOfRun; - } - - setupFontForScriptRun(); - shapeGlyphs(); - setGlyphXPositions(rtl()); - - return true; -} - -float TextRunWalker::widthOfFullRun() -{ - float widthSum = 0; - while (nextScriptRun()) - widthSum += width(); - - return widthSum; -} - -void TextRunWalker::setWordAndLetterSpacing(int wordSpacingAdjustment, - int letterSpacingAdjustment) -{ - setWordSpacingAdjustment(wordSpacingAdjustment); - setLetterSpacingAdjustment(letterSpacingAdjustment); -} - -void TextRunWalker::setupFontForScriptRun() -{ - const FontData* fontData = m_font->glyphDataForCharacter( - m_item.string[m_item.item.pos], false).fontData; - const FontPlatformData& platformData = - fontData->fontDataForCharacter(' ')->platformData(); - m_item.face = platformData.harfbuzzFace(); - void* opaquePlatformData = const_cast<FontPlatformData*>(&platformData); - m_item.font->userData = opaquePlatformData; -} - -HB_FontRec* TextRunWalker::allocHarfbuzzFont() -{ - HB_FontRec* font = reinterpret_cast<HB_FontRec*>(fastMalloc(sizeof(HB_FontRec))); - memset(font, 0, sizeof(HB_FontRec)); - font->klass = &harfbuzzSkiaClass; - font->userData = 0; - // The values which harfbuzzSkiaClass returns are already scaled to - // pixel units, so we just set all these to one to disable further - // scaling. - font->x_ppem = 1; - font->y_ppem = 1; - font->x_scale = 1; - font->y_scale = 1; - - return font; -} - -void TextRunWalker::deleteGlyphArrays() -{ - delete[] m_item.glyphs; - delete[] m_item.attributes; - delete[] m_item.advances; - delete[] m_item.offsets; - delete[] m_glyphs16; - delete[] m_xPositions; -} - -void TextRunWalker::createGlyphArrays(int size) -{ - m_item.glyphs = new HB_Glyph[size]; - m_item.attributes = new HB_GlyphAttributes[size]; - m_item.advances = new HB_Fixed[size]; - m_item.offsets = new HB_FixedPoint[size]; - - m_glyphs16 = new uint16_t[size]; - m_xPositions = new SkScalar[size]; - - m_item.num_glyphs = size; - m_glyphsArrayCapacity = size; // Save the GlyphArrays size. -} - -void TextRunWalker::resetGlyphArrays() -{ - int size = m_item.num_glyphs; - // All the types here don't have pointers. It is safe to reset to - // zero unless Harfbuzz breaks the compatibility in the future. - memset(m_item.glyphs, 0, size * sizeof(m_item.glyphs[0])); - memset(m_item.attributes, 0, size * sizeof(m_item.attributes[0])); - memset(m_item.advances, 0, size * sizeof(m_item.advances[0])); - memset(m_item.offsets, 0, size * sizeof(m_item.offsets[0])); - memset(m_glyphs16, 0, size * sizeof(m_glyphs16[0])); - memset(m_xPositions, 0, size * sizeof(m_xPositions[0])); -} - -void TextRunWalker::shapeGlyphs() -{ - // HB_ShapeItem() resets m_item.num_glyphs. If the previous call to - // HB_ShapeItem() used less space than was available, the capacity of - // the array may be larger than the current value of m_item.num_glyphs. - // So, we need to reset the num_glyphs to the capacity of the array. - m_item.num_glyphs = m_glyphsArrayCapacity; - resetGlyphArrays(); - while (!HB_ShapeItem(&m_item)) { - // We overflowed our arrays. Resize and retry. - // HB_ShapeItem fills in m_item.num_glyphs with the needed size. - deleteGlyphArrays(); - createGlyphArrays(m_item.num_glyphs << 1); - resetGlyphArrays(); - } -} - -void TextRunWalker::setGlyphXPositions(bool isRTL) -{ - int position = 0; - // logClustersIndex indexes logClusters for the first (or last when - // RTL) codepoint of the current glyph. Each time we advance a glyph, - // we skip over all the codepoints that contributed to the current - // glyph. - unsigned logClustersIndex = isRTL && m_item.num_glyphs ? m_item.num_glyphs - 1 : 0; - - for (unsigned iter = 0; iter < m_item.num_glyphs; ++iter) { - // Glyphs are stored in logical order, but for layout purposes we - // always go left to right. - int i = isRTL ? m_item.num_glyphs - iter - 1 : iter; - - m_glyphs16[i] = m_item.glyphs[i]; - int offsetX = truncateFixedPointToInteger(m_item.offsets[i].x); - m_xPositions[i] = SkIntToScalar(m_offsetX + position + offsetX); - - int advance = truncateFixedPointToInteger(m_item.advances[i]); - // The first half of the conjunction works around the case where - // output glyphs aren't associated with any codepoints by the - // clusters log. - if (logClustersIndex < m_item.item.length - && isWordBreak(m_item.item.pos + logClustersIndex, isRTL)) { - advance += m_wordSpacingAdjustment; - - if (m_padding > 0) { - int toPad = roundf(m_padPerWordBreak + m_padError); - m_padError += m_padPerWordBreak - toPad; - - if (m_padding < toPad) - toPad = m_padding; - m_padding -= toPad; - advance += toPad; - } - } - - // TODO We would like to add m_letterSpacing after each cluster, but I - // don't know where the cluster information is. This is typically - // fine for Roman languages, but breaks more complex languages - // terribly. - // advance += m_letterSpacing; - - if (isRTL) { - while (logClustersIndex > 0 && logClusters()[logClustersIndex] == i) - logClustersIndex--; - } else { - while (logClustersIndex < m_item.item.length - && logClusters()[logClustersIndex] == i) - logClustersIndex++; - } - - position += advance; - } - - m_pixelWidth = position; - m_offsetX += m_pixelWidth; -} - -void TextRunWalker::normalizeSpacesAndMirrorChars(const UChar* source, bool rtl, - UChar* destination, int length) -{ - int position = 0; - bool error = false; - // Iterate characters in source and mirror character if needed. - while (position < length) { - UChar32 character; - int nextPosition = position; - U16_NEXT(source, nextPosition, length, character); - if (Font::treatAsSpace(character)) - character = ' '; - else if (rtl) - character = u_charMirror(character); - U16_APPEND(destination, position, length, character, error); - ASSERT(!error); - position = nextPosition; - } -} - -const TextRun& TextRunWalker::getNormalizedTextRun(const TextRun& originalRun, - OwnPtr<TextRun>& normalizedRun, OwnArrayPtr<UChar>& normalizedBuffer) -{ - // Normalize the text run in three ways: - // 1) Convert the |originalRun| to NFC normalized form if combining diacritical marks - // (U+0300..) are used in the run. This conversion is necessary since most OpenType - // fonts (e.g., Arial) don't have substitution rules for the diacritical marks in - // their GSUB tables. - // - // Note that we don't use the icu::Normalizer::isNormalized(UNORM_NFC) API here since - // the API returns FALSE (= not normalized) for complex runs that don't require NFC - // normalization (e.g., Arabic text). Unless the run contains the diacritical marks, - // Harfbuzz will do the same thing for us using the GSUB table. - // 2) Convert spacing characters into plain spaces, as some fonts will provide glyphs - // for characters like '\n' otherwise. - // 3) Convert mirrored characters such as parenthesis for rtl text. - - // Convert to NFC form if the text has diacritical marks. - icu::UnicodeString normalizedString; - UErrorCode error = U_ZERO_ERROR; - - for (int16_t i = 0; i < originalRun.length(); ++i) { - UChar ch = originalRun[i]; - if (::ublock_getCode(ch) == UBLOCK_COMBINING_DIACRITICAL_MARKS) { - icu::Normalizer::normalize(icu::UnicodeString(originalRun.characters(), - originalRun.length()), UNORM_NFC, 0 /* no options */, - normalizedString, error); - if (U_FAILURE(error)) - return originalRun; - break; - } - } - - // Normalize space and mirror parenthesis for rtl text. - int normalizedBufferLength; - const UChar* sourceText; - if (normalizedString.isEmpty()) { - normalizedBufferLength = originalRun.length(); - sourceText = originalRun.characters(); - } else { - normalizedBufferLength = normalizedString.length(); - sourceText = normalizedString.getBuffer(); - } - - normalizedBuffer.set(new UChar[normalizedBufferLength + 1]); - - normalizeSpacesAndMirrorChars(sourceText, originalRun.rtl(), normalizedBuffer.get(), - normalizedBufferLength); - - normalizedRun.set(new TextRun(originalRun)); - normalizedRun->setText(normalizedBuffer.get(), normalizedBufferLength); - return *normalizedRun; -} - -FloatRect Font::selectionRectForComplexText(const TextRun& run, - const FloatPoint& point, int height, int from, int to) const -{ - - int fromX = -1, toX = -1, fromAdvance = -1, toAdvance = -1; - TextRunWalker walker(run, 0, this); - walker.setWordAndLetterSpacing(wordSpacing(), letterSpacing()); - - // Base will point to the x offset for the current script run. Note that, in - // the LTR case, width will be 0. - int base = walker.rtl() ? walker.widthOfFullRun() : 0; - const int leftEdge = base; - - // We want to enumerate the script runs in code point order in the following - // code. This call also resets |walker|. - walker.setBackwardsIteration(false); - - while (walker.nextScriptRun() && (fromX == -1 || toX == -1)) { - // TextRunWalker will helpfully accumulate the x offsets for different - // script runs for us. For this code, however, we always want the x - // offsets to start from zero so we call this before each script run. - walker.setXOffsetToZero(); - - if (walker.rtl()) - base -= walker.width(); - - int numCodePoints = static_cast<int>(walker.numCodePoints()); - if (fromX == -1 && from < numCodePoints) { - // |from| is within this script run. So we index the clusters log to - // find which glyph this code-point contributed to and find its x - // position. - int glyph = walker.logClusters()[from]; - fromX = base + walker.xPositions()[glyph]; - fromAdvance = walker.advances()[glyph]; - } else - from -= numCodePoints; - - if (toX == -1 && to < numCodePoints) { - int glyph = walker.logClusters()[to]; - toX = base + walker.xPositions()[glyph]; - toAdvance = walker.advances()[glyph]; - } else - to -= numCodePoints; - - if (!walker.rtl()) - base += walker.width(); - } - - // The position in question might be just after the text. - const int rightEdge = base; - if (fromX == -1 && !from) - fromX = leftEdge; - else if (walker.rtl()) - fromX += truncateFixedPointToInteger(fromAdvance); - - if (toX == -1 && !to) - toX = rightEdge; - - ASSERT(fromX != -1 && toX != -1); - - if (fromX < toX) - return FloatRect(point.x() + fromX, point.y(), toX - fromX, height); - - return FloatRect(point.x() + toX, point.y(), fromX - toX, height); -} - -void Font::drawComplexText(GraphicsContext* gc, TextRun const& run, - FloatPoint const& point, int, int) const -{ - if (!run.length()) - return; - - int mode = gc->textDrawingMode(); - bool fill = mode & TextModeFill; - bool stroke = mode & TextModeStroke; - if (!fill && !stroke) - return; - - SkPaint fillPaint, strokePaint; - if (fill) - setupFill(&fillPaint, gc, primaryFont()); - if (stroke) - setupStroke(&strokePaint, gc, primaryFont()); - - SkCanvas* canvas = gc->platformContext()->mCanvas; - bool haveMultipleLayers = isCanvasMultiLayered(canvas); - TextRunWalker walker(run, point.x(), this); - walker.setWordAndLetterSpacing(wordSpacing(), letterSpacing()); - walker.setPadding(run.padding()); - - while (walker.nextScriptRun()) { - if (fill) { - walker.fontPlatformDataForScriptRun()->setupPaint(&fillPaint); - adjustTextRenderMode(&fillPaint, haveMultipleLayers); - canvas->drawPosTextH(walker.glyphs(), walker.length() << 1, - walker.xPositions(), point.y(), fillPaint); - } - if (stroke) { - walker.fontPlatformDataForScriptRun()->setupPaint(&strokePaint); - adjustTextRenderMode(&strokePaint, haveMultipleLayers); - canvas->drawPosTextH(walker.glyphs(), walker.length() << 1, - walker.xPositions(), point.y(), strokePaint); - } - } -} - -float Font::floatWidthForComplexText(const TextRun& run, - HashSet<const SimpleFontData*>*, GlyphOverflow*) const -{ - TextRunWalker walker(run, 0, this); - walker.setWordAndLetterSpacing(wordSpacing(), letterSpacing()); - return walker.widthOfFullRun(); -} - -static int glyphIndexForXPositionInScriptRun(const TextRunWalker& walker, int x) -{ - const HB_Fixed* advances = walker.advances(); - int glyphIndex; - if (walker.rtl()) { - for (glyphIndex = walker.length() - 1; glyphIndex >= 0; --glyphIndex) { - if (x < truncateFixedPointToInteger(advances[glyphIndex])) - break; - x -= truncateFixedPointToInteger(advances[glyphIndex]); - } - } else { - for (glyphIndex = 0; glyphIndex < static_cast<int>(walker.length()); - ++glyphIndex) { - if (x < truncateFixedPointToInteger(advances[glyphIndex])) - break; - x -= truncateFixedPointToInteger(advances[glyphIndex]); - } - } - - return glyphIndex; -} - -int Font::offsetForPositionForComplexText(const TextRun& run, float x, - bool includePartialGlyphs) const -{ - // (Mac code ignores includePartialGlyphs, and they don't know what it's - // supposed to do, so we just ignore it as well.) - TextRunWalker walker(run, 0, this); - walker.setWordAndLetterSpacing(wordSpacing(), letterSpacing()); - - // If this is RTL text, the first glyph from the left is actually the last - // code point. So we need to know how many code points there are total in - // order to subtract. This is different from the length of the TextRun - // because UTF-16 surrogate pairs are a single code point, but 32-bits long. - // In LTR we leave this as 0 so that we get the correct value for - // |basePosition|, below. - unsigned totalCodePoints = 0; - if (walker.rtl()) { - ssize_t offset = 0; - while (offset < run.length()) { - utf16_to_code_point(run.characters(), run.length(), &offset); - totalCodePoints++; - } - } - - unsigned basePosition = totalCodePoints; - - // For RTL: - // code-point order: abcd efg hijkl - // on screen: lkjih gfe dcba - // ^ ^ - // | | - // basePosition--| | - // totalCodePoints----| - // Since basePosition is currently the total number of code-points, the - // first thing we do is decrement it so that it's pointing to the start of - // the current script-run. - // - // For LTR, basePosition is zero so it already points to the start of the - // first script run. - while (walker.nextScriptRun()) { - if (walker.rtl()) - basePosition -= walker.numCodePoints(); - - if (x >= 0 && x < static_cast<int>(walker.width())) { - // The x value in question is within this script run. We consider - // each glyph in presentation order and stop when we find the one - // covering this position. - const int glyphIndex = glyphIndexForXPositionInScriptRun(walker, x); - - // Now that we have a glyph index, we have to turn that into a - // code-point index. Because of ligatures, several code-points may - // have gone into a single glyph. We iterate over the clusters log - // and find the first code-point which contributed to the glyph. - - // Some shapers (i.e. Khmer) will produce cluster logs which report - // that /no/ code points contributed to certain glyphs. Because of - // this, we take any code point which contributed to the glyph in - // question, or any subsequent glyph. If we run off the end, then - // we take the last code point. - const unsigned short* log = walker.logClusters(); - for (unsigned j = 0; j < walker.numCodePoints(); ++j) { - if (log[j] >= glyphIndex) - return basePosition + j; - } - - return basePosition + walker.numCodePoints() - 1; - } - - x -= walker.width(); - - if (!walker.rtl()) - basePosition += walker.numCodePoints(); - } - - return basePosition; -} -#endif - -} diff --git a/WebCore/platform/graphics/android/FontCacheAndroid.cpp b/WebCore/platform/graphics/android/FontCacheAndroid.cpp deleted file mode 100644 index 428628c..0000000 --- a/WebCore/platform/graphics/android/FontCacheAndroid.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * Copyright (C) 2006 Apple Computer, 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "FontCache.h" - -#include "Font.h" -#include "FontPlatformData.h" -#include "NotImplemented.h" -#include "SimpleFontData.h" -#include "SkPaint.h" -#include "SkTypeface.h" -#include "SkUtils.h" -#include <wtf/text/CString.h> - -namespace WebCore { - -static const char* getFallbackFontName(const FontDescription& fontDescription) -{ - switch (fontDescription.genericFamily()) { - case FontDescription::StandardFamily: - case FontDescription::SerifFamily: - return "serif"; - case FontDescription::SansSerifFamily: - return "sans-serif"; - case FontDescription::MonospaceFamily: - return "monospace"; - case FontDescription::CursiveFamily: - return "cursive"; - case FontDescription::FantasyFamily: - return "fantasy"; - case FontDescription::NoFamily: - default: - return ""; - } -} - -static bool isFallbackFamily(String family) -{ - return family.startsWith("-webkit-") - || equalIgnoringCase(family, "serif") - || equalIgnoringCase(family, "sans-serif") - || equalIgnoringCase(family, "sans") - || equalIgnoringCase(family, "monospace") - || equalIgnoringCase(family, "cursive") - || equalIgnoringCase(family, "fantasy"); -} - -static char* AtomicStringToUTF8String(const AtomicString& utf16) -{ - SkASSERT(sizeof(uint16_t) == sizeof(utf16.characters()[0])); - const uint16_t* uni = (uint16_t*)utf16.characters(); - - size_t bytes = SkUTF16_ToUTF8(uni, utf16.length(), 0); - char* utf8 = (char*)sk_malloc_throw(bytes + 1); - - (void)SkUTF16_ToUTF8(uni, utf16.length(), utf8); - utf8[bytes] = 0; - return utf8; -} - - -void FontCache::platformInit() -{ -} - -const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) -{ - // since all of our fonts logically map to the fallback, we can always claim - // that each font supports all characters. - return font.primaryFont(); -} - -SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font) -{ - return 0; -} - -SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& description) -{ - static const AtomicString sansStr("sans-serif"); - static const AtomicString serifStr("serif"); - static const AtomicString monospaceStr("monospace"); - - FontPlatformData* fontPlatformData = 0; - switch (description.genericFamily()) { - case FontDescription::SerifFamily: - fontPlatformData = getCachedFontPlatformData(description, serifStr); - break; - case FontDescription::MonospaceFamily: - fontPlatformData = getCachedFontPlatformData(description, monospaceStr); - break; - case FontDescription::SansSerifFamily: - default: - fontPlatformData = getCachedFontPlatformData(description, sansStr); - break; - } - - ASSERT(fontPlatformData); - return getCachedFontData(fontPlatformData); -} - -FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) -{ - char* storage = 0; - const char* name = 0; - FontPlatformData* result = 0; - - if (family.length()) { - storage = AtomicStringToUTF8String(family); - name = storage; - } else - name = getFallbackFontName(fontDescription); - - int style = SkTypeface::kNormal; - if (fontDescription.weight() >= FontWeightBold) - style |= SkTypeface::kBold; - if (fontDescription.italic()) - style |= SkTypeface::kItalic; - - // CreateFromName always returns a typeface, falling back to a default font - // if the one requested is not found. Calling Equal() with a null pointer - // serves to compare the returned font against the default, with the caveat - // that the default is always of normal style. If we detect the default, we - // ignore it and allow WebCore to give us the next font on the CSS fallback - // list. The only exception is if the family name is a commonly used generic - // family, as when called by getSimilarFontPlatformData() and - // getLastResortFallbackFont(). In this case, the default font is an - // acceptable result. - - SkTypeface* tf = SkTypeface::CreateFromName(name, SkTypeface::kNormal); - - if (!SkTypeface::Equal(tf, 0) || isFallbackFamily(family.string())) { - // We had to use normal styling to see if this was a default font. If - // we need bold or italic, replace with the corrected typeface. - if (style != SkTypeface::kNormal) { - tf->unref(); - tf = SkTypeface::CreateFromName(name, (SkTypeface::Style)style); - } - - result = new FontPlatformData(tf, fontDescription.computedSize(), - (style & SkTypeface::kBold) && !tf->isBold(), - (style & SkTypeface::kItalic) && !tf->isItalic()); - } - - tf->unref(); - sk_free(storage); - return result; -} - - // new as of SVN change 36269, Sept 8, 2008 -void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks) -{ - // Don't understand this yet, but it seems safe to leave unimplemented -} - -} diff --git a/WebCore/platform/graphics/android/FontCustomPlatformData.cpp b/WebCore/platform/graphics/android/FontCustomPlatformData.cpp deleted file mode 100644 index 4795d9e..0000000 --- a/WebCore/platform/graphics/android/FontCustomPlatformData.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "FontCustomPlatformData.h" - -#include "SkTypeface.h" -#include "SkStream.h" -#include "SharedBuffer.h" -#include "FontPlatformData.h" - -namespace WebCore { - -FontCustomPlatformData::FontCustomPlatformData(SkTypeface* face) -{ - SkSafeRef(face); - m_typeface = face; -} - -FontCustomPlatformData::~FontCustomPlatformData() -{ - SkSafeUnref(m_typeface); - // the unref is enough to release the font data... -} - -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, - FontOrientation, FontRenderingMode) -{ - // turn bold/italic into fakeBold/fakeItalic - if (m_typeface != NULL) { - if (m_typeface->isBold() == bold) - bold = false; - if (m_typeface->isItalic() == italic) - italic = false; - } - return FontPlatformData(m_typeface, size, bold, italic); -} - -FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) -{ - // pass true until we know how we can share the data, and not have to - // make a copy of it. - SkStream* stream = new SkMemoryStream(buffer->data(), buffer->size(), true); - SkTypeface* face = SkTypeface::CreateFromStream(stream); - // Release the stream. - stream->unref(); - if (0 == face) { - SkDebugf("--------- SkTypeface::CreateFromBuffer failed %d\n", - buffer->size()); - return NULL; - } - - SkAutoUnref aur(face); - - return new FontCustomPlatformData(face); -} - -bool FontCustomPlatformData::supportsFormat(const String& format) -{ - return equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype") -#if ENABLE(OPENTYPE_SANITIZER) - || equalIgnoringCase(format, "woff") -#endif - ; -} - -} diff --git a/WebCore/platform/graphics/android/FontCustomPlatformData.h b/WebCore/platform/graphics/android/FontCustomPlatformData.h deleted file mode 100644 index 3514ae7..0000000 --- a/WebCore/platform/graphics/android/FontCustomPlatformData.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 FontCustomPlatformData_h -#define FontCustomPlatformData_h - -#include "FontOrientation.h" -#include "FontRenderingMode.h" -#include <wtf/Forward.h> -#include <wtf/Noncopyable.h> - -class SkTypeface; - -namespace WebCore { - -class FontPlatformData; -class SharedBuffer; - -class FontCustomPlatformData : public Noncopyable { -public: - FontCustomPlatformData(SkTypeface* face); - ~FontCustomPlatformData(); - - SkTypeface* typeface() const { return m_typeface; } - - FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode); - - static bool supportsFormat(const String&); -private: - SkTypeface* m_typeface; -}; - -FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer); - -} // namespace WebCore - -#endif // FontCustomPlatformData_h diff --git a/WebCore/platform/graphics/android/FontDataAndroid.cpp b/WebCore/platform/graphics/android/FontDataAndroid.cpp deleted file mode 100644 index 545dcf7..0000000 --- a/WebCore/platform/graphics/android/FontDataAndroid.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * Copyright (C) 2006 Apple Computer, 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "EmojiFont.h" -#include "Font.h" -#include "FontCache.h" -#include "SimpleFontData.h" -#include "FloatRect.h" -#include "FontDescription.h" -#include "SkPaint.h" -#include "SkTypeface.h" -#include "SkTime.h" - -using namespace android; - -namespace WebCore { - -void SimpleFontData::platformInit() -{ - SkPaint paint; - SkPaint::FontMetrics metrics; - - m_platformData.setupPaint(&paint); - (void)paint.getFontMetrics(&metrics); - - // use ceil instead of round to favor descent, given a lot of accidental - // clipping of descenders (e.g. 14pt 'g') in textedit fields - int d = SkScalarCeil(metrics.fDescent); - int s = SkScalarRound(metrics.fDescent - metrics.fAscent); - int a = s - d; - - m_ascent = a; - m_descent = d; - m_xHeight = SkScalarToFloat(-metrics.fAscent) * 0.56f; // hack I stole from the window's port - m_lineSpacing = a + d; - m_lineGap = SkScalarRound(metrics.fLeading); -} - -void SimpleFontData::platformCharWidthInit() -{ - m_avgCharWidth = 0.f; - m_maxCharWidth = 0.f; - initCharWidths(); -} - -void SimpleFontData::platformDestroy() -{ -} - -SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const -{ - if (!m_derivedFontData) - m_derivedFontData = DerivedFontData::create(isCustomFont()); - if (!m_derivedFontData->smallCaps) - m_derivedFontData->smallCaps = new SimpleFontData(FontPlatformData(m_platformData, fontDescription.computedSize() * 0.7f)); - - return m_derivedFontData->smallCaps.get(); -} - -SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const -{ - if (!m_derivedFontData) - m_derivedFontData = DerivedFontData::create(isCustomFont()); - if (!m_derivedFontData->emphasisMark) - m_derivedFontData->emphasisMark = new SimpleFontData(FontPlatformData(m_platformData, fontDescription.computedSize() * 0.5f)); - - return m_derivedFontData->emphasisMark.get(); -} - -bool SimpleFontData::containsCharacters(const UChar* characters, int length) const -{ - SkPaint paint; - - m_platformData.setupPaint(&paint); - paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - return paint.containsText(characters, length << 1); -} - -void SimpleFontData::determinePitch() -{ - m_treatAsFixedPitch = m_platformData.isFixedPitch(); -} - -FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const -{ - return FloatRect(); -} - -float SimpleFontData::platformWidthForGlyph(Glyph glyph) const -{ - SkASSERT(sizeof(glyph) == 2); // compile-time assert - - SkPaint paint; - - m_platformData.setupPaint(&paint); - - float advanceWidth; - if (EmojiFont::IsEmojiGlyph(glyph)) - advanceWidth = EmojiFont::GetAdvanceWidth(glyph, paint); - else { - paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); - advanceWidth = SkScalarToFloat(paint.measureText(&glyph, 2)); - } - return advanceWidth; -} - - -} diff --git a/WebCore/platform/graphics/android/FontPlatformData.h b/WebCore/platform/graphics/android/FontPlatformData.h deleted file mode 100644 index ba30efe..0000000 --- a/WebCore/platform/graphics/android/FontPlatformData.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * Copyright (C) 2006 Apple Computer, Inc. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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. - */ - -// This file is part of the internal font implementation. It should not be included by anyone other than -// FontMac.cpp, FontWin.cpp and Font.cpp. - -#ifndef FontPlatformData_H -#define FontPlatformData_H - -#include "FontOrientation.h" -#include <wtf/text/StringImpl.h> - -#ifndef NDEBUG -#include "PlatformString.h" -#endif - -class SkPaint; -class SkTypeface; - -struct HB_FaceRec_; - -namespace WebCore { - -class FontPlatformData { -public: - static FontPlatformData Deleted() { - return FontPlatformData(NULL, -1, false, false); - } - - FontPlatformData(); - FontPlatformData(const FontPlatformData&); - FontPlatformData(SkTypeface*, float textSize, bool fakeBold, bool fakeItalic); - FontPlatformData(const FontPlatformData& src, float textSize); - FontPlatformData(float size, bool syntheticBold, bool syntheticOblique); - - ~FontPlatformData(); - - FontPlatformData(WTF::HashTableDeletedValueType) - : mTypeface(hashTableDeletedFontValue()) { } - bool isHashTableDeletedValue() const { - return mTypeface == hashTableDeletedFontValue(); - } - - FontOrientation orientation() const { return Horizontal; } // FIXME: Implement. - - FontPlatformData& operator=(const FontPlatformData&); - bool operator==(const FontPlatformData& a) const; - - void setupPaint(SkPaint*) const; - - // ------------------------------------------------------------------------- - // Return Skia's unique id for this font. This encodes both the style and - // the font's file name so refers to a single face. - // ------------------------------------------------------------------------- - uint32_t uniqueID() const; - - float size() const { return mTextSize; } - unsigned hash() const; - bool isFixedPitch() const; - -#ifndef NDEBUG - String description() const { return ""; } -#endif - - HB_FaceRec_* harfbuzzFace() const; - -private: - class RefCountedHarfbuzzFace : public RefCounted<RefCountedHarfbuzzFace> { - public: - static PassRefPtr<RefCountedHarfbuzzFace> create(HB_FaceRec_* harfbuzzFace) - { - return adoptRef(new RefCountedHarfbuzzFace(harfbuzzFace)); - } - - ~RefCountedHarfbuzzFace(); - - HB_FaceRec_* face() const { return m_harfbuzzFace; } - - private: - RefCountedHarfbuzzFace(HB_FaceRec_* harfbuzzFace) : m_harfbuzzFace(harfbuzzFace) - { - } - - HB_FaceRec_* m_harfbuzzFace; - }; - - SkTypeface* mTypeface; - float mTextSize; - bool mFakeBold; - bool mFakeItalic; - mutable RefPtr<RefCountedHarfbuzzFace> m_harfbuzzFace; - - static SkTypeface* hashTableDeletedFontValue() { - return reinterpret_cast<SkTypeface*>(-1); - } -}; - -} /* namespace */ - -#endif diff --git a/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp b/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp deleted file mode 100644 index 337a94d..0000000 --- a/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * Copyright (C) 2006 Apple Computer, Inc. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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. - */ - -//This file is part of the internal font implementation. It should not be included by anyone other than -// FontMac.cpp, FontWin.cpp and Font.cpp. - -#include "config.h" -#include "FontPlatformData.h" - -#ifdef SUPPORT_COMPLEX_SCRIPTS -#include "HarfbuzzSkia.h" -#endif -#include "SkPaint.h" -#include "SkTypeface.h" - -//#define TRACE_FONTPLATFORMDATA_LIFE -//#define COUNT_FONTPLATFORMDATA_LIFE - -#ifdef COUNT_FONTPLATFORMDATA_LIFE -static int gCount; -static int gMaxCount; - -static void inc_count() -{ - if (++gCount > gMaxCount) - { - gMaxCount = gCount; - SkDebugf("---------- FontPlatformData %d\n", gMaxCount); - } -} - -static void dec_count() { --gCount; } -#else - #define inc_count() - #define dec_count() -#endif - -#ifdef TRACE_FONTPLATFORMDATA_LIFE - #define trace(num) SkDebugf("FontPlatformData%d %p %g %d %d\n", num, mTypeface, mTextSize, mFakeBold, mFakeItalic) -#else - #define trace(num) -#endif - -namespace WebCore { - -FontPlatformData::RefCountedHarfbuzzFace::~RefCountedHarfbuzzFace() -{ -#ifdef SUPPORT_COMPLEX_SCRIPTS - HB_FreeFace(m_harfbuzzFace); -#endif -} - -FontPlatformData::FontPlatformData() - : mTypeface(NULL), mTextSize(0), mFakeBold(false), mFakeItalic(false) -{ - inc_count(); - trace(1); -} - -FontPlatformData::FontPlatformData(const FontPlatformData& src) -{ - if (hashTableDeletedFontValue() != src.mTypeface) { - SkSafeRef(src.mTypeface); - } - - mTypeface = src.mTypeface; - - mTextSize = src.mTextSize; - mFakeBold = src.mFakeBold; - mFakeItalic = src.mFakeItalic; - m_harfbuzzFace = src.m_harfbuzzFace; - - inc_count(); - trace(2); -} - -FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold, bool fakeItalic) - : mTypeface(tf), mTextSize(textSize), mFakeBold(fakeBold), mFakeItalic(fakeItalic) -{ - if (hashTableDeletedFontValue() != mTypeface) { - SkSafeRef(mTypeface); - } - - inc_count(); - trace(3); -} - -FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize) - : mTypeface(src.mTypeface), mTextSize(textSize), mFakeBold(src.mFakeBold), mFakeItalic(src.mFakeItalic), - m_harfbuzzFace(src.m_harfbuzzFace) -{ - if (hashTableDeletedFontValue() != mTypeface) { - SkSafeRef(mTypeface); - } - - inc_count(); - trace(4); -} - -FontPlatformData::FontPlatformData(float size, bool bold, bool oblique) - : mTypeface(NULL), mTextSize(size), mFakeBold(bold), mFakeItalic(oblique) -{ - inc_count(); - trace(5); -} - -FontPlatformData::~FontPlatformData() -{ - dec_count(); -#ifdef TRACE_FONTPLATFORMDATA_LIFE - SkDebugf("----------- ~FontPlatformData\n"); -#endif - - if (hashTableDeletedFontValue() != mTypeface) { - SkSafeUnref(mTypeface); - } -} - -FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src) -{ - if (hashTableDeletedFontValue() != src.mTypeface) { - SkSafeRef(src.mTypeface); - } - if (hashTableDeletedFontValue() != mTypeface) { - SkSafeUnref(mTypeface); - } - - mTypeface = src.mTypeface; - mTextSize = src.mTextSize; - mFakeBold = src.mFakeBold; - mFakeItalic = src.mFakeItalic; - m_harfbuzzFace = src.m_harfbuzzFace; - - return *this; -} - -void FontPlatformData::setupPaint(SkPaint* paint) const -{ - float ts = mTextSize; - if (!(ts > 0)) - ts = 12; - - if (hashTableDeletedFontValue() == mTypeface) - paint->setTypeface(0); - else - paint->setTypeface(mTypeface); - - paint->setAntiAlias(true); - paint->setSubpixelText(true); - paint->setHinting(SkPaint::kSlight_Hinting); - paint->setTextSize(SkFloatToScalar(ts)); - paint->setFakeBoldText(mFakeBold); - paint->setTextSkewX(mFakeItalic ? -SK_Scalar1/4 : 0); -#ifndef SUPPORT_COMPLEX_SCRIPTS - paint->setTextEncoding(SkPaint::kUTF16_TextEncoding); -#endif -} - -uint32_t FontPlatformData::uniqueID() const -{ - if (hashTableDeletedFontValue() == mTypeface) - return SkTypeface::UniqueID(0); - else - return SkTypeface::UniqueID(mTypeface); -} - -bool FontPlatformData::operator==(const FontPlatformData& a) const -{ - return mTypeface == a.mTypeface && - mTextSize == a.mTextSize && - mFakeBold == a.mFakeBold && - mFakeItalic == a.mFakeItalic; -} - -unsigned FontPlatformData::hash() const -{ - unsigned h; - - if (hashTableDeletedFontValue() == mTypeface) { - h = reinterpret_cast<unsigned>(mTypeface); - } else { - h = SkTypeface::UniqueID(mTypeface); - } - - uint32_t sizeAsInt = *reinterpret_cast<const uint32_t*>(&mTextSize); - - h ^= 0x01010101 * (((int)mFakeBold << 1) | (int)mFakeItalic); - h ^= sizeAsInt; - return h; -} - -bool FontPlatformData::isFixedPitch() const -{ - if (mTypeface && (mTypeface != hashTableDeletedFontValue())) - return mTypeface->isFixedWidth(); - else - return false; -} - -HB_FaceRec_* FontPlatformData::harfbuzzFace() const -{ -#ifdef SUPPORT_COMPLEX_SCRIPTS - if (!m_harfbuzzFace) - m_harfbuzzFace = RefCountedHarfbuzzFace::create( - HB_NewFace(const_cast<FontPlatformData*>(this), harfbuzzSkiaGetTable)); - - return m_harfbuzzFace->face(); -#else - return NULL; -#endif -} -} diff --git a/WebCore/platform/graphics/android/GLUtils.cpp b/WebCore/platform/graphics/android/GLUtils.cpp deleted file mode 100644 index 5eabb85..0000000 --- a/WebCore/platform/graphics/android/GLUtils.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "GLUtils.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "ShaderProgram.h" - -#include <cutils/log.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GLUtils", __VA_ARGS__) - -namespace WebCore { - -using namespace android; - -///////////////////////////////////////////////////////////////////////////////////////// -// Matrix utilities -///////////////////////////////////////////////////////////////////////////////////////// - -void GLUtils::toGLMatrix(GLfloat* flattened, const TransformationMatrix& m) -{ - flattened[0] = m.m11(); // scaleX - flattened[1] = m.m12(); // skewY - flattened[2] = m.m13(); - flattened[3] = m.m14(); // persp0 - flattened[4] = m.m21(); // skewX - flattened[5] = m.m22(); // scaleY - flattened[6] = m.m23(); - flattened[7] = m.m24(); // persp1 - flattened[8] = m.m31(); - flattened[9] = m.m32(); - flattened[10] = m.m33(); - flattened[11] = m.m34(); - flattened[12] = m.m41(); // transX - flattened[13] = m.m42(); // transY - flattened[14] = m.m43(); - flattened[15] = m.m44(); // persp2 -} - -void GLUtils::toSkMatrix(SkMatrix& matrix, const TransformationMatrix& m) -{ - matrix[0] = m.m11(); // scaleX - matrix[1] = m.m21(); // skewX - matrix[2] = m.m41(); // transX - matrix[3] = m.m12(); // skewY - matrix[4] = m.m22(); // scaleY - matrix[5] = m.m42(); // transY - matrix[6] = m.m14(); // persp0 - matrix[7] = m.m24(); // persp1 - matrix[8] = m.m44(); // persp2 -} - -void GLUtils::setOrthographicMatrix(TransformationMatrix& ortho, float left, float top, - float right, float bottom, float nearZ, float farZ) -{ - float deltaX = right - left; - float deltaY = top - bottom; - float deltaZ = farZ - nearZ; - if (!deltaX || !deltaY || !deltaZ) - return; - - ortho.setM11(2.0f / deltaX); - ortho.setM41(-(right + left) / deltaX); - ortho.setM22(2.0f / deltaY); - ortho.setM42(-(top + bottom) / deltaY); - ortho.setM33(-2.0f / deltaZ); - ortho.setM43(-(nearZ + farZ) / deltaZ); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// GL & EGL error checks -///////////////////////////////////////////////////////////////////////////////////////// - -static void crashIfOOM(GLint errorCode) { - const GLint OOM_ERROR_CODE = 0x505; - if (errorCode == OOM_ERROR_CODE) { - XLOG("Fatal OOM detected."); - CRASH(); - } -} - -void GLUtils::checkEglError(const char* op, EGLBoolean returnVal) -{ - if (returnVal != EGL_TRUE) - XLOG("EGL ERROR - %s() returned %d\n", op, returnVal); - - for (EGLint error = eglGetError(); error != EGL_SUCCESS; error = eglGetError()) { - XLOG("after %s() eglError (0x%x)\n", op, error); - crashIfOOM(error); - } -} - -bool GLUtils::checkGlError(const char* op) -{ - bool ret = false; - for (GLint error = glGetError(); error; error = glGetError()) { - XLOG("GL ERROR - after %s() glError (0x%x)\n", op, error); - crashIfOOM(error); - ret = true; - } - return ret; -} - -bool GLUtils::checkGlErrorOn(void* p, const char* op) -{ - bool ret = false; - for (GLint error = glGetError(); error; error = glGetError()) { - XLOG("GL ERROR on %x - after %s() glError (0x%x)\n", p, op, error); - crashIfOOM(error); - ret = true; - } - return ret; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// GL & EGL extension checks -///////////////////////////////////////////////////////////////////////////////////////// - -bool GLUtils::isEGLImageSupported() -{ - const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS); - const char* glExtensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); - - return eglExtensions && glExtensions - && strstr(eglExtensions, "EGL_KHR_image_base") - && strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image") - && strstr(glExtensions, "GL_OES_EGL_image"); -} - -bool GLUtils::isEGLFenceSyncSupported() -{ - const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS); - return eglExtensions && strstr(eglExtensions, "EGL_KHR_fence_sync"); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Textures utilities -///////////////////////////////////////////////////////////////////////////////////////// - -static GLenum getInternalFormat(SkBitmap::Config config) -{ - switch (config) { - case SkBitmap::kA8_Config: - return GL_ALPHA; - case SkBitmap::kARGB_4444_Config: - return GL_RGBA; - case SkBitmap::kARGB_8888_Config: - return GL_RGBA; - case SkBitmap::kRGB_565_Config: - return GL_RGB; - default: - return -1; - } -} - -static GLenum getType(SkBitmap::Config config) -{ - switch (config) { - case SkBitmap::kA8_Config: - return GL_UNSIGNED_BYTE; - case SkBitmap::kARGB_4444_Config: - return GL_UNSIGNED_SHORT_4_4_4_4; - case SkBitmap::kARGB_8888_Config: - return GL_UNSIGNED_BYTE; - case SkBitmap::kIndex8_Config: - return -1; // No type for compressed data. - case SkBitmap::kRGB_565_Config: - return GL_UNSIGNED_SHORT_5_6_5; - default: - return -1; - } -} - -static EGLConfig defaultPbufferConfig(EGLDisplay display) -{ - EGLConfig config; - EGLint numConfigs; - - static const EGLint configAttribs[] = { - EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_NONE - }; - - eglChooseConfig(display, configAttribs, &config, 1, &numConfigs); - GLUtils::checkEglError("eglPbufferConfig"); - if (numConfigs != 1) - LOGI("eglPbufferConfig failed (%d)\n", numConfigs); - - return config; -} - -static EGLSurface createPbufferSurface(EGLDisplay display, const EGLConfig& config, - EGLint* errorCode) -{ - const EGLint attribList[] = { - EGL_WIDTH, 1, - EGL_HEIGHT, 1, - EGL_NONE - }; - EGLSurface surface = eglCreatePbufferSurface(display, config, attribList); - - if (errorCode) - *errorCode = eglGetError(); - else - GLUtils::checkEglError("eglCreatePbufferSurface"); - - if (surface == EGL_NO_SURFACE) - return EGL_NO_SURFACE; - - return surface; -} - -EGLContext GLUtils::createBackgroundContext(EGLContext sharedContext) -{ - checkEglError("<init>"); - EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - checkEglError("eglGetDisplay"); - if (display == EGL_NO_DISPLAY) { - XLOG("eglGetDisplay returned EGL_NO_DISPLAY"); - return EGL_NO_CONTEXT; - } - - EGLint majorVersion; - EGLint minorVersion; - EGLBoolean returnValue = eglInitialize(display, &majorVersion, &minorVersion); - checkEglError("eglInitialize", returnValue); - if (returnValue != EGL_TRUE) { - XLOG("eglInitialize failed\n"); - return EGL_NO_CONTEXT; - } - - EGLConfig config = defaultPbufferConfig(display); - EGLSurface surface = createPbufferSurface(display, config, 0); - - EGLint surfaceConfigId; - EGLBoolean success = eglGetConfigAttrib(display, config, EGL_CONFIG_ID, &surfaceConfigId); - - EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - EGLContext context = eglCreateContext(display, config, sharedContext, contextAttribs); - checkEglError("eglCreateContext"); - if (context == EGL_NO_CONTEXT) { - XLOG("eglCreateContext failed\n"); - return EGL_NO_CONTEXT; - } - - returnValue = eglMakeCurrent(display, surface, surface, context); - checkEglError("eglMakeCurrent", returnValue); - if (returnValue != EGL_TRUE) { - XLOG("eglMakeCurrent failed\n"); - return EGL_NO_CONTEXT; - } - - return context; -} - -void GLUtils::deleteTexture(GLuint* texture) -{ - glDeleteTextures(1, texture); - GLUtils::checkGlError("glDeleteTexture"); - *texture = 0; -} - -GLuint GLUtils::createSampleColorTexture(int r, int g, int b) { - GLuint texture; - glGenTextures(1, &texture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - GLubyte pixels[4 *3] = { - r, g, b, - r, g, b, - r, g, b, - r, g, b - }; - glBindTexture(GL_TEXTURE_2D, texture); - GLUtils::checkGlError("glBindTexture"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels); - GLUtils::checkGlError("glTexImage2D"); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - return texture; -} - -GLuint GLUtils::createSampleTexture() -{ - GLuint texture; - glGenTextures(1, &texture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - GLubyte pixels[4 *3] = { - 255, 0, 0, - 0, 255, 0, - 0, 0, 255, - 255, 255, 0 - }; - glBindTexture(GL_TEXTURE_2D, texture); - GLUtils::checkGlError("glBindTexture"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels); - GLUtils::checkGlError("glTexImage2D"); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - return texture; -} - -void GLUtils::createTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter) -{ - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glBindTexture(GL_TEXTURE_2D, texture); - GLUtils::checkGlError("glBindTexture"); - SkBitmap::Config config = bitmap.getConfig(); - int internalformat = getInternalFormat(config); - int type = getType(config); - bitmap.lockPixels(); - glTexImage2D(GL_TEXTURE_2D, 0, internalformat, bitmap.width(), bitmap.height(), - 0, internalformat, type, bitmap.getPixels()); - bitmap.unlockPixels(); - if (GLUtils::checkGlError("glTexImage2D")) { - XLOG("GL ERROR: glTexImage2D parameters are : bitmap.width() %d, bitmap.height() %d," - " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p", - bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels()); - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); - - // The following is a workaround -- remove when EGLImage texture upload is fixed. - GLuint fboID; - glGenFramebuffers(1, &fboID); - glBindFramebuffer(GL_FRAMEBUFFER, fboID); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); - glCheckFramebufferStatus(GL_FRAMEBUFFER); // should return GL_FRAMEBUFFER_COMPLETE - - glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO - glDeleteFramebuffers(1, &fboID); -} - -void GLUtils::updateTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter) -{ - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glBindTexture(GL_TEXTURE_2D, texture); - GLUtils::checkGlError("glBindTexture"); - SkBitmap::Config config = bitmap.getConfig(); - int internalformat = getInternalFormat(config); - int type = getType(config); - bitmap.lockPixels(); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(), - internalformat, type, bitmap.getPixels()); - bitmap.unlockPixels(); - if (GLUtils::checkGlError("glTexSubImage2D")) { - XLOG("GL ERROR: glTexSubImage2D parameters are : bitmap.width() %d, bitmap.height() %d," - " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p", - bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels()); - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); -} - -void GLUtils::updateTextureWithBitmap(GLuint texture, int x, int y, SkBitmap& bitmap, GLint filter) -{ - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glBindTexture(GL_TEXTURE_2D, texture); - GLUtils::checkGlError("glBindTexture"); - SkBitmap::Config config = bitmap.getConfig(); - int internalformat = getInternalFormat(config); - int type = getType(config); - bitmap.lockPixels(); - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, bitmap.width(), bitmap.height(), - internalformat, type, bitmap.getPixels()); - bitmap.unlockPixels(); - if (GLUtils::checkGlError("glTexSubImage2D")) { - XLOG("GL ERROR: glTexSubImage2D parameters are : bitmap.width() %d, bitmap.height() %d," - " x %d, y %d, internalformat 0x%x, type 0x%x, bitmap.getPixels() %p", - bitmap.width(), bitmap.height(), x, y, internalformat, type, bitmap.getPixels()); - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); -} - -void GLUtils::createEGLImageFromTexture(GLuint texture, EGLImageKHR* image) -{ - EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(texture); - static const EGLint attr[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; - *image = eglCreateImageKHR(eglGetCurrentDisplay(), eglGetCurrentContext(), - EGL_GL_TEXTURE_2D_KHR, buffer, attr); - GLUtils::checkEglError("eglCreateImage", (*image != EGL_NO_IMAGE_KHR)); -} - -void GLUtils::createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter) -{ - glBindTexture(GL_TEXTURE_2D, texture); - GLUtils::checkGlError("glBindTexture"); - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/GLUtils.h b/WebCore/platform/graphics/android/GLUtils.h deleted file mode 100644 index 1e8df39..0000000 --- a/WebCore/platform/graphics/android/GLUtils.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 GLUtils_h -#define GLUtils_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "SkBitmap.h" -#include "SkMatrix.h" -#include "TransformationMatrix.h" -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> - -namespace WebCore { - -class GLUtils { - -public: - // Matrix utilities - static void toGLMatrix(GLfloat* flattened, const TransformationMatrix& matrix); - static void toSkMatrix(SkMatrix& skmatrix, const TransformationMatrix& matrix); - static void setOrthographicMatrix(TransformationMatrix& ortho, float left, float top, - float right, float bottom, float nearZ, float farZ); - - // GL & EGL error checks - static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE); - static bool checkGlErrorOn(void* p, const char* op); - static bool checkGlError(const char* op); - - // GL & EGL extension checks - static bool isEGLImageSupported(); - static bool isEGLFenceSyncSupported(); - - // Texture utilities - static EGLContext createBackgroundContext(EGLContext sharedContext); - static void deleteTexture(GLuint* texture); - static GLuint createSampleColorTexture(int r, int g, int b); - static GLuint createSampleTexture(); - static void createTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter = GL_LINEAR); - static void updateTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter = GL_LINEAR); - static void updateTextureWithBitmap(GLuint texture, int x, int y, SkBitmap& bitmap, GLint filter = GL_LINEAR); - static void createEGLImageFromTexture(GLuint texture, EGLImageKHR* image); - static void createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter = GL_LINEAR); -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) -#endif // GLUtils_h diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp deleted file mode 100644 index 4acd563..0000000 --- a/WebCore/platform/graphics/android/GLWebViewState.cpp +++ /dev/null @@ -1,574 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "GLWebViewState.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "BaseLayerAndroid.h" -#include "ClassTracker.h" -#include "GLUtils.h" -#include "LayerAndroid.h" -#include "TilesManager.h" -#include <wtf/CurrentTime.h> - -#include <cutils/log.h> -#include <wtf/text/CString.h> - -#undef XLOGC -#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "GLWebViewState", __VA_ARGS__) - -#ifdef DEBUG - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GLWebViewState", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -#define FIRST_TILED_PAGE_ID 1 -#define SECOND_TILED_PAGE_ID 2 - -#define FRAMERATE_CAP 0.01666 // We cap at 60 fps - -namespace WebCore { - -using namespace android; - -GLWebViewState::GLWebViewState(android::Mutex* buttonMutex) - : m_scaleRequestState(kNoScaleRequest) - , m_currentScale(1) - , m_futureScale(1) - , m_updateTime(-1) - , m_transitionTime(-1) - , m_baseLayer(0) - , m_currentBaseLayer(0) - , m_previouslyUsedRoot(0) - , m_currentPictureCounter(0) - , m_usePageA(true) - , m_frameworkInval(0, 0, 0, 0) - , m_frameworkLayersInval(0, 0, 0, 0) - , m_globalButtonMutex(buttonMutex) - , m_baseLayerUpdate(true) - , m_backgroundColor(SK_ColorWHITE) - , m_prevDrawTime(0) - , m_displayRings(false) - , m_focusRingTexture(-1) -{ - m_viewport.setEmpty(); - m_previousViewport.setEmpty(); - m_futureViewportTileBounds.setEmpty(); - m_viewportTileBounds.setEmpty(); - m_preZoomBounds.setEmpty(); - - m_tiledPageA = new TiledPage(FIRST_TILED_PAGE_ID, this); - m_tiledPageB = new TiledPage(SECOND_TILED_PAGE_ID, this); -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("GLWebViewState"); -#endif -#ifdef MEASURES_PERF - m_timeCounter = 0; - m_totalTimeCounter = 0; - m_measurePerfs = false; -#endif -} - -GLWebViewState::~GLWebViewState() -{ - // We have to destroy the two tiled pages first as their destructor - // may depend on the existence of this GLWebViewState and some of its - // instance variables in order to complete. - // Explicitely, currently we need to have the m_currentBaseLayer around - // in order to complete any pending paint operations (the tiled pages - // will remove any pending operations, and wait if one is underway). - delete m_tiledPageA; - delete m_tiledPageB; - SkSafeUnref(m_currentBaseLayer); - SkSafeUnref(m_baseLayer); - m_baseLayer = 0; - m_currentBaseLayer = 0; -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("GLWebViewState"); -#endif -} - -void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval, - bool showVisualIndicator, bool isPictureAfterFirstLayout) -{ - android::Mutex::Autolock lock(m_baseLayerLock); - if (!layer || isPictureAfterFirstLayout) { - m_tiledPageA->setUsable(false); - m_tiledPageB->setUsable(false); - } - if (isPictureAfterFirstLayout) { - m_baseLayerUpdate = true; - m_invalidateRegion.setEmpty(); - } - if (m_baseLayer && layer) - m_baseLayer->swapExtra(layer); - - SkSafeRef(layer); - SkSafeUnref(m_baseLayer); - m_baseLayer = layer; - if (m_baseLayer) - m_baseLayer->setGLWebViewState(this); - - // We only update the layers if we are not currently - // waiting for a tiledPage to be painted - if (m_baseLayerUpdate) { - SkSafeRef(layer); - SkSafeUnref(m_currentBaseLayer); - m_currentBaseLayer = layer; - } - m_displayRings = false; - invalRegion(inval); - -#ifdef MEASURES_PERF - if (m_measurePerfs && !showVisualIndicator) - dumpMeasures(); - m_measurePerfs = showVisualIndicator; -#endif - - TilesManager::instance()->setShowVisualIndicator(showVisualIndicator); -} - -void GLWebViewState::setRings(Vector<IntRect>& rings, bool isPressed) -{ - android::Mutex::Autolock lock(m_baseLayerLock); - m_displayRings = true; - m_rings = rings; - m_ringsIsPressed = isPressed; -} - -void GLWebViewState::invalRegion(const SkRegion& region) -{ - SkRegion::Iterator iterator(region); - while (!iterator.done()) { - SkIRect r = iterator.rect(); - IntRect ir(r.fLeft, r.fTop, r.width(), r.height()); - inval(ir); - iterator.next(); - } -} - -void GLWebViewState::unlockBaseLayerUpdate() { - if (m_baseLayerUpdate) - return; - - m_baseLayerUpdate = true; - android::Mutex::Autolock lock(m_baseLayerLock); - SkSafeRef(m_baseLayer); - SkSafeUnref(m_currentBaseLayer); - m_currentBaseLayer = m_baseLayer; - - invalRegion(m_invalidateRegion); - m_invalidateRegion.setEmpty(); -} - -void GLWebViewState::setExtra(BaseLayerAndroid* layer, SkPicture& picture, - const IntRect& rect, bool allowSame) -{ - android::Mutex::Autolock lock(m_baseLayerLock); - if (!m_baseLayerUpdate) - return; - - layer->setExtra(picture); - - if (!allowSame && m_lastInval == rect) - return; - - if (!rect.isEmpty()) - inval(rect); - if (!m_lastInval.isEmpty()) - inval(m_lastInval); - m_lastInval = rect; - m_displayRings = false; -} - -void GLWebViewState::inval(const IntRect& rect) -{ - if (m_baseLayerUpdate) { - m_currentPictureCounter++; - if (!rect.isEmpty()) { - // find which tiles fall within the invalRect and mark them as dirty - m_tiledPageA->invalidateRect(rect, m_currentPictureCounter); - m_tiledPageB->invalidateRect(rect, m_currentPictureCounter); - if (m_frameworkInval.isEmpty()) - m_frameworkInval = rect; - else - m_frameworkInval.unite(rect); - XLOG("intermediate invalRect(%d, %d, %d, %d) after unite with rect %d %d %d %d", m_frameworkInval.x(), - m_frameworkInval.y(), m_frameworkInval.right(), m_frameworkInval.bottom(), - rect.x(), rect.y(), rect.right(), rect.bottom()); - } - } else { - m_invalidateRegion.op(rect.x(), rect.y(), rect.right(), rect.bottom(), SkRegion::kUnion_Op); - } -} - -void GLWebViewState::resetRings() -{ - m_displayRings = false; -} - -void GLWebViewState::drawFocusRing(IntRect& srcRect) -{ - // TODO: use a 9-patch texture to draw the focus ring - // instead of plain colors - const float alpha = 0.3; - float borderAlpha = 0.40; - - const int r = 104; - const int g = 153; - const int b = 255; - - int padding = 4; - int border = 1; - int fuzzyBorder = border * 2; - if (!m_ringsIsPressed) { - padding = 0; - border = 2; - fuzzyBorder = 3; - borderAlpha = 0.2; - } - if (m_focusRingTexture == -1) - m_focusRingTexture = GLUtils::createSampleColorTexture(r, g, b); - - SkRect rLeft, rTop, rRight, rBottom, rOverlay; - - IntRect rect(srcRect.x() - padding, srcRect.y() - padding, - srcRect.width() + (padding * 2), srcRect.height() + (padding * 2)); - rLeft.set(rect.x() - border, rect.y(), - rect.x(), rect.y() + rect.height()); - rTop.set(rect.x() - border, rect.y() - border, - rect.x() + rect.width() + border, rect.y()); - rRight.set(rect.x() + rect.width(), rect.y(), - rect.x() + rect.width() + border, - rect.y() + rect.height()); - rBottom.set(rect.x() - border, rect.y() + rect.height(), - rect.x() + rect.width() + border, - rect.y() + rect.height() + border); - rOverlay.set(rect.x() - fuzzyBorder, rect.y() - fuzzyBorder, - rect.x() + rect.width() + fuzzyBorder, - rect.y() + rect.height() + fuzzyBorder); - - TilesManager::instance()->shader()->drawQuad(rLeft, m_focusRingTexture, borderAlpha); - TilesManager::instance()->shader()->drawQuad(rTop, m_focusRingTexture, borderAlpha); - TilesManager::instance()->shader()->drawQuad(rRight, m_focusRingTexture, borderAlpha); - TilesManager::instance()->shader()->drawQuad(rBottom, m_focusRingTexture, borderAlpha); - if (m_ringsIsPressed) { - TilesManager::instance()->shader()->drawQuad(rOverlay, m_focusRingTexture, alpha); - } else { - rLeft.set(rect.x() - fuzzyBorder, rect.y(), - rect.x(), rect.y() + rect.height()); - rTop.set(rect.x() - fuzzyBorder, rect.y() - fuzzyBorder, - rect.x() + rect.width() + fuzzyBorder, rect.y()); - rRight.set(rect.x() + rect.width(), rect.y(), - rect.x() + rect.width() + fuzzyBorder, - rect.y() + rect.height()); - rBottom.set(rect.x() - fuzzyBorder, rect.y() + rect.height(), - rect.x() + rect.width() + fuzzyBorder, - rect.y() + rect.height() + fuzzyBorder); - TilesManager::instance()->shader()->drawQuad(rLeft, m_focusRingTexture, alpha); - TilesManager::instance()->shader()->drawQuad(rTop, m_focusRingTexture, alpha); - TilesManager::instance()->shader()->drawQuad(rRight, m_focusRingTexture, alpha); - TilesManager::instance()->shader()->drawQuad(rBottom, m_focusRingTexture, alpha); - } -} - -void GLWebViewState::paintExtras() -{ - if (m_displayRings) { - // TODO: handles correctly the multi-rings case - for (int i=0; i<m_rings.size(); i++) { - IntRect rect = m_rings.at(i); - drawFocusRing(rect); - } - } -} - -unsigned int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas) -{ - android::Mutex::Autolock lock(m_baseLayerLock); - if (m_currentBaseLayer) { - m_globalButtonMutex->lock(); - m_currentBaseLayer->drawCanvas(canvas); - m_globalButtonMutex->unlock(); - } - return m_currentPictureCounter; -} - -void GLWebViewState::scheduleUpdate(const double& currentTime, - const SkIRect& viewport, float scale) -{ - // if no update time, set it - if (updateTime() == -1) { - m_scaleRequestState = kWillScheduleRequest; - setUpdateTime(currentTime + s_updateInitialDelay); - setFutureScale(scale); - setFutureViewport(viewport); - return; - } - - if (currentTime < updateTime()) - return; - - // we reached the scheduled update time, check if we can update - if (futureScale() == scale) { - // we are still with the previous scale, let's go - // with the update - m_scaleRequestState = kRequestNewScale; - setUpdateTime(-1); - } else { - // we reached the update time, but the planned update was for - // a different scale factor -- meaning the user is still probably - // in the process of zooming. Let's push the update time a bit. - setUpdateTime(currentTime + s_updateDelay); - setFutureScale(scale); - setFutureViewport(viewport); - } -} - -double GLWebViewState::zoomInTransitionTime(double currentTime) -{ - if (m_transitionTime == -1) - m_transitionTime = currentTime + s_zoomInTransitionDelay; - return m_transitionTime; -} - -double GLWebViewState::zoomOutTransitionTime(double currentTime) -{ - if (m_transitionTime == -1) - m_transitionTime = currentTime + s_zoomOutTransitionDelay; - return m_transitionTime; -} - - -float GLWebViewState::zoomInTransparency(double currentTime) -{ - float t = zoomInTransitionTime(currentTime) - currentTime; - t *= s_invZoomInTransitionDelay; - return fmin(1, fmax(0, t)); -} - -float GLWebViewState::zoomOutTransparency(double currentTime) -{ - float t = zoomOutTransitionTime(currentTime) - currentTime; - t *= s_invZoomOutTransitionDelay; - return fmin(1, fmax(0, t)); -} - -TiledPage* GLWebViewState::sibling(TiledPage* page) -{ - return (page == m_tiledPageA) ? m_tiledPageB : m_tiledPageA; -} - -TiledPage* GLWebViewState::frontPage() -{ - android::Mutex::Autolock lock(m_tiledPageLock); - return m_usePageA ? m_tiledPageA : m_tiledPageB; -} - -TiledPage* GLWebViewState::backPage() -{ - android::Mutex::Autolock lock(m_tiledPageLock); - return m_usePageA ? m_tiledPageB : m_tiledPageA; -} - -void GLWebViewState::swapPages() -{ - android::Mutex::Autolock lock(m_tiledPageLock); - m_usePageA ^= true; - TiledPage* working = m_usePageA ? m_tiledPageB : m_tiledPageA; - if (m_scaleRequestState != kNoScaleRequest) - TilesManager::instance()->resetTextureUsage(working); - - m_scaleRequestState = kNoScaleRequest; -} - -int GLWebViewState::baseContentWidth() -{ - return m_currentBaseLayer ? m_currentBaseLayer->getWidth() : 0; - -} -int GLWebViewState::baseContentHeight() -{ - return m_currentBaseLayer ? m_currentBaseLayer->getHeight() : 0; -} - -void GLWebViewState::setViewport(SkRect& viewport, float scale) -{ - m_previousViewport = m_viewport; - if ((m_viewport == viewport) && - (m_futureScale == scale)) - return; - - m_viewport = viewport; - XLOG("New VIEWPORT %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f currentScale: %.2f futureScale: %.2f)", - m_viewport.fLeft, m_viewport.fTop, m_viewport.fRight, m_viewport.fBottom, - m_viewport.width(), m_viewport.height(), scale, m_currentScale, m_futureScale); - - const float invTileContentWidth = scale / TilesManager::tileWidth(); - const float invTileContentHeight = scale / TilesManager::tileHeight(); - - m_viewportTileBounds.set( - static_cast<int>(floorf(viewport.fLeft * invTileContentWidth)), - static_cast<int>(floorf(viewport.fTop * invTileContentHeight)), - static_cast<int>(ceilf(viewport.fRight * invTileContentWidth)), - static_cast<int>(ceilf(viewport.fBottom * invTileContentHeight))); - - int maxTextureCount = (m_viewportTileBounds.width() + TilesManager::instance()->expandedTileBoundsX() * 2 + 1) * - (m_viewportTileBounds.height() + TilesManager::instance()->expandedTileBoundsY() * 2 + 1) * 2; - TilesManager::instance()->setMaxTextureCount(maxTextureCount); - m_tiledPageA->updateBaseTileSize(); - m_tiledPageB->updateBaseTileSize(); -} - -#ifdef MEASURES_PERF -void GLWebViewState::dumpMeasures() -{ - for (int i = 0; i < m_timeCounter; i++) { - XLOGC("%d delay: %d ms", m_totalTimeCounter + i, - static_cast<int>(m_delayTimes[i]*1000)); - m_delayTimes[i] = 0; - } - m_totalTimeCounter += m_timeCounter; - m_timeCounter = 0; -} -#endif // MEASURES_PERF - -void GLWebViewState::resetFrameworkInval() -{ - m_frameworkInval.setX(0); - m_frameworkInval.setY(0); - m_frameworkInval.setWidth(0); - m_frameworkInval.setHeight(0); -} - -void GLWebViewState::addDirtyArea(const IntRect& rect) -{ - if (rect.isEmpty()) - return; - - IntRect inflatedRect = rect; - inflatedRect.inflate(8); - if (m_frameworkLayersInval.isEmpty()) - m_frameworkLayersInval = inflatedRect; - else - m_frameworkLayersInval.unite(inflatedRect); -} - -void GLWebViewState::resetLayersDirtyArea() -{ - m_frameworkLayersInval.setX(0); - m_frameworkLayersInval.setY(0); - m_frameworkLayersInval.setWidth(0); - m_frameworkLayersInval.setHeight(0); -} - -bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, - IntRect& webViewRect, int titleBarHeight, - IntRect& clip, float scale, SkColor color) -{ - glFinish(); - - double currentTime = WTF::currentTime(); - double delta = currentTime - m_prevDrawTime; - - if (delta < FRAMERATE_CAP) { - unsigned int usecs = (FRAMERATE_CAP - delta) * 1E6; - usleep(usecs); - } - - m_prevDrawTime = currentTime; - - m_baseLayerLock.lock(); - BaseLayerAndroid* baseLayer = m_currentBaseLayer; - SkSafeRef(baseLayer); - BaseLayerAndroid* baseForComposited = m_baseLayer; - SkSafeRef(baseForComposited); - m_baseLayerLock.unlock(); - if (!baseLayer) { - SkSafeUnref(baseForComposited); - return false; - } - - XLOG("drawGL, rect(%d, %d, %d, %d), viewport(%.2f, %.2f, %.2f, %.2f)", - rect.x(), rect.y(), rect.right(), rect.bottom(), - viewport.fLeft, viewport.fTop, viewport.fRight, viewport.fBottom); - - resetLayersDirtyArea(); - - if (!baseForComposited || - (baseForComposited && !baseForComposited->countChildren())) { - SkSafeRef(baseLayer); - SkSafeUnref(baseForComposited); - baseForComposited = baseLayer; - } - - LayerAndroid* compositedRoot = 0; - if (baseForComposited && baseForComposited->countChildren() >= 1) - compositedRoot = static_cast<LayerAndroid*>(baseForComposited->getChild(0)); - - bool ret = baseLayer->drawGL(compositedRoot, rect, viewport, webViewRect, titleBarHeight, clip, scale, color); - m_previouslyUsedRoot = compositedRoot; - if (ret) { - FloatRect frameworkInval = TilesManager::instance()->shader()->rectInInvScreenCoord(m_frameworkInval); - IntRect inval(frameworkInval.x(), frameworkInval.y(), frameworkInval.width(), frameworkInval.height()); - - inval.unite(m_frameworkLayersInval); - - invalRect->setX(inval.x()); - invalRect->setY(inval.y()); - invalRect->setWidth(inval.width()); - invalRect->setHeight(inval.height()); - - XLOG("invalRect(%d, %d, %d, %d)", inval.x(), - inval.y(), inval.right(), inval.bottom()); - } else { - resetFrameworkInval(); - } - -#ifdef MEASURES_PERF - if (m_measurePerfs) { - m_delayTimes[m_timeCounter++] = delta; - if (m_timeCounter >= MAX_MEASURES_PERF) - dumpMeasures(); - } -#endif - - SkSafeUnref(baseForComposited); - SkSafeUnref(baseLayer); - return ret; -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/GLWebViewState.h b/WebCore/platform/graphics/android/GLWebViewState.h deleted file mode 100644 index 980dd3c..0000000 --- a/WebCore/platform/graphics/android/GLWebViewState.h +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 GLWebViewState_h -#define GLWebViewState_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "DrawExtra.h" -#include "IntRect.h" -#include "SkCanvas.h" -#include "SkRect.h" -#include "SkRegion.h" -#include "TiledPage.h" -#include <utils/threads.h> - -// Performance measurements probe -// To use it, enable the visual indicators in debug mode. -// turning off the visual indicators will flush the measures. -// #define MEASURES_PERF -#define MAX_MEASURES_PERF 2000 - -namespace WebCore { - -class BaseLayerAndroid; -class LayerAndroid; - -///////////////////////////////////////////////////////////////////////////////// -// GL Architecture -///////////////////////////////////////////////////////////////////////////////// -// -// To draw things, WebView use a tree of layers. The root of that tree is a -// BaseLayerAndroid, which may have numerous LayerAndroid over it. The content -// of those layers are SkPicture, the content of the BaseLayer is an PictureSet. -// -// When drawing, we therefore have one large "surface" that is the BaseLayer, -// and (possibly) additional surfaces (usually smaller), which are the -// LayerAndroids. The BaseLayer usually corresponds to the normal web page -// content, the Layers are used for some parts such as specific divs (e.g. fixed -// position divs, or elements using CSS3D transforms, or containing video, -// plugins, etc.). -// -// *** NOTE: The GL drawing architecture only paints the BaseLayer for now. -// -// The rendering model is to use tiles to display the BaseLayer (as obviously a -// BaseLayer's area can be arbitrarly large). The idea is to compute a set of -// tiles covering the viewport's area, paint those tiles using the webview's -// content (i.e. the BaseLayer's PictureSet), then display those tiles. -// We check which tile we should use at every frame. -// -// Overview -// --------- -// -// The tiles are grouped into a TiledPage -- basically a map of tiles covering -// the BaseLayer's surface. When drawing, we ask the TiledPage to prepare() -// itself then draw itself on screen. The prepare() function is the one -// that schedules tiles to be painted -- i.e. the subset of tiles that intersect -// with the current viewport. When they are ready, we can display -// the TiledPage. -// -// Note that BaseLayerAndroid::drawGL() will return true to the java side if -// there is a need to be called again (i.e. if we do not have up to date -// textures or a transition is going on). -// -// Tiles are implemented as a BaseTile. It knows how to paint itself with the -// PictureSet, and to display itself. A GL texture is usually associated to it. -// -// We also works with two TiledPages -- one to display the page at the -// current scale factor, and another we use to paint the page at a different -// scale factor. I.e. when we zoom, we use TiledPage A, with its tiles scaled -// accordingly (and therefore possible loss of quality): this is fast as it's -// purely a hardware operation. When the user is done zooming, we ask for -// TiledPage B to be painted at the new scale factor, covering the -// viewport's area. When B is ready, we swap it with A. -// -// Texture allocation -// ------------------ -// -// Obviously we cannot have every BaseTile having a GL texture -- we need to -// get the GL textures from an existing pool, and reuse them. -// -// The way we do it is that when we call TiledPage::prepare(), we group the -// tiles we need (i.e. in the viewport and dirty) into a TilesSet and call -// BaseTile::reserveTexture() for each tile (which ensures there is a specific -// GL textures backing the BaseTiles). -// -// reserveTexture() will ask the TilesManager for a texture. The allocation -// mechanism goal is to (in order): -// - prefers to allocate the same texture as the previous time -// - prefers to allocate textures that are as far from the viewport as possible -// - prefers to allocate textures that are used by different TiledPages -// -// Note that to compute the distance of each tile from the viewport, each time -// we prepare() a TiledPage. Also during each prepare() we compute which tiles -// are dirty based on the info we have received from webkit. -// -// BaseTile Invalidation -// ------------------ -// -// We do not want to redraw a tile if the tile is up-to-date. A tile is -// considered to be dirty an in need of redrawing in the following cases -// - the tile has acquires a new texture -// - webkit invalidates all or part of the tiles contents -// -// To handle the case of webkit invalidation we store two ids (counters) of the -// pictureSets in the tile. The first id (A) represents the pictureSet used to -// paint the tile and the second id (B) represents the pictureSet in which the -// tile was invalidated by webkit. Thus, if A < B then tile is dirty. -// -// Painting scheduling -// ------------------- -// -// The next operation is to schedule this TilesSet to be painted -// (TilesManager::schedulePaintForTilesSet()). TexturesGenerator -// will get the TilesSet and ask the BaseTiles in it to be painted. -// -// BaseTile::paintBitmap() will paint the texture using the BaseLayer's -// PictureSet (calling TiledPage::paintBaseLayerContent() which in turns -// calls GLWebViewState::paintBaseLayerContent()). -// -// Note that TexturesGenerator is running in a separate thread, the textures -// are shared using EGLImages (this is necessary to not slow down the rendering -// speed -- updating GL textures in the main GL thread would slow things down). -// -///////////////////////////////////////////////////////////////////////////////// - -class GLWebViewState { -public: - enum GLScaleStates { - kNoScaleRequest = 0, - kWillScheduleRequest = 1, - kRequestNewScale = 2, - kReceivedNewScale = 3 - }; - typedef int32_t GLScaleState; - - GLWebViewState(android::Mutex* globalButtonMutex); - ~GLWebViewState(); - GLScaleState scaleRequestState() const { return m_scaleRequestState; } - void setScaleRequestState(GLScaleState state) { m_scaleRequestState = state; } - float currentScale() const { return m_currentScale; } - void setCurrentScale(float scale) { m_currentScale = scale; } - float futureScale() const { return m_futureScale; } - void setFutureScale(float scale) { m_futureScale = scale; } - const SkIRect& futureViewport() const { return m_futureViewportTileBounds; } - void setFutureViewport(const SkIRect& viewport) { m_futureViewportTileBounds = viewport; } - double updateTime() const { return m_updateTime; } - void setUpdateTime(double value) { m_updateTime = value; } - double zoomInTransitionTime(double currentTime); - double zoomOutTransitionTime(double currentTime); - float zoomInTransparency(double currentTime); - float zoomOutTransparency(double currentTime); - void resetTransitionTime() { m_transitionTime = -1; } - - unsigned int paintBaseLayerContent(SkCanvas* canvas); - void setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval, bool showVisualIndicator, - bool isPictureAfterFirstLayout); - void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&, bool allowSame); - void scheduleUpdate(const double& currentTime, const SkIRect& viewport, float scale); - void paintExtras(); - - void setRings(Vector<IntRect>& rings, bool isPressed); - void resetRings(); - void drawFocusRing(IntRect& rect); - - TiledPage* sibling(TiledPage* page); - TiledPage* frontPage(); - TiledPage* backPage(); - void swapPages(); - - // dimensions of the current base layer - int baseContentWidth(); - int baseContentHeight(); - - void setViewport(SkRect& viewport, float scale); - - // a rect containing the coordinates of all tiles in the current viewport - const SkIRect& viewportTileBounds() const { return m_viewportTileBounds; } - // a rect containing the viewportTileBounds before there was a scale change - const SkIRect& preZoomBounds() const { return m_preZoomBounds; } - void setPreZoomBounds(const SkIRect& bounds) { m_preZoomBounds = bounds; } - - unsigned int currentPictureCounter() const { return m_currentPictureCounter; } - - void lockBaseLayerUpdate() { m_baseLayerUpdate = false; } - void unlockBaseLayerUpdate(); - - bool moving() { - // This will only works if we are not zooming -- we check - // for this in BaseLayerAndroid::drawBasePictureInGL() - if ((m_viewport.fLeft != m_previousViewport.fLeft || - m_viewport.fTop != m_previousViewport.fTop) && - m_viewport.width() == m_previousViewport.width() && - m_viewport.height() == m_previousViewport.height()) - return true; - return false; - } - - bool drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, - IntRect& webViewRect, int titleBarHeight, - IntRect& clip, float scale, SkColor color = SK_ColorWHITE); - - void setBackgroundColor(SkColor color) { m_backgroundColor = color; } - SkColor getBackgroundColor() { return m_backgroundColor; } - -#ifdef MEASURES_PERF - void dumpMeasures(); -#endif - - void resetFrameworkInval(); - void addDirtyArea(const IntRect& rect); - void resetLayersDirtyArea(); - LayerAndroid* previouslyUsedRoot() { return m_previouslyUsedRoot; } - -private: - void inval(const IntRect& rect); // caller must hold m_baseLayerLock - void invalRegion(const SkRegion& region); - - // Delay between scheduling a new page when the scale - // factor changes (i.e. zooming in or out) - static const double s_updateInitialDelay = 0.3; // 300 ms - // If the scale factor continued to change and we completed - // the original delay, we push back the update by this value - static const double s_updateDelay = 0.1; // 100 ms - - // Delay for the transition between the two pages - static const double s_zoomInTransitionDelay = 0.1; // 100 ms - static const double s_invZoomInTransitionDelay = 10; - static const double s_zoomOutTransitionDelay = 0.2; // 200 ms - static const double s_invZoomOutTransitionDelay = 5; - - GLScaleState m_scaleRequestState; - float m_currentScale; - float m_futureScale; - double m_updateTime; - double m_transitionTime; - android::Mutex m_tiledPageLock; - SkRect m_viewport; - SkRect m_previousViewport; - SkIRect m_viewportTileBounds; - SkIRect m_futureViewportTileBounds; - SkIRect m_preZoomBounds; - android::Mutex m_baseLayerLock; - BaseLayerAndroid* m_baseLayer; - BaseLayerAndroid* m_currentBaseLayer; - LayerAndroid* m_previouslyUsedRoot; - - unsigned int m_currentPictureCounter; - bool m_usePageA; - TiledPage* m_tiledPageA; - TiledPage* m_tiledPageB; - IntRect m_lastInval; - IntRect m_frameworkInval; - IntRect m_frameworkLayersInval; - android::Mutex* m_globalButtonMutex; - - bool m_baseLayerUpdate; - SkRegion m_invalidateRegion; - - SkColor m_backgroundColor; - double m_prevDrawTime; - -#ifdef MEASURES_PERF - unsigned int m_totalTimeCounter; - int m_timeCounter; - double m_delayTimes[MAX_MEASURES_PERF]; - bool m_measurePerfs; -#endif - bool m_displayRings; - Vector<IntRect> m_rings; - bool m_ringsIsPressed; - int m_focusRingTexture; -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) -#endif // GLWebViewState_h diff --git a/WebCore/platform/graphics/android/GlyphMapAndroid.cpp b/WebCore/platform/graphics/android/GlyphMapAndroid.cpp deleted file mode 100644 index da9d99a..0000000 --- a/WebCore/platform/graphics/android/GlyphMapAndroid.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * Copyright (C) 2006 Apple Computer, 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "EmojiFont.h" -#include "GlyphPageTreeNode.h" -#include "SkTemplates.h" -#include "SkPaint.h" -#include "SkUtils.h" -#include "SimpleFontData.h" - -using namespace android; - -namespace WebCore { - -#define NO_BREAK_SPACE_UNICHAR 0xA0 - -bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) -{ - if (SkUTF16_IsHighSurrogate(buffer[bufferLength-1])) { - SkDebugf("%s last char is high-surrogate", __FUNCTION__); - return false; - } - - SkPaint paint; - fontData->platformData().setupPaint(&paint); - paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - - SkAutoSTMalloc <GlyphPage::size, uint16_t> glyphStorage(length); - uint16_t* glyphs = glyphStorage.get(); - unsigned count = paint.textToGlyphs(buffer, bufferLength << 1, glyphs); - if (count != length) { - SkDebugf("%s count != length\n", __FUNCTION__); - return false; - } - - unsigned allGlyphs = 0; // track if any of the glyphIDs are non-zero - - // search for emoji. If we knew for sure that buffer was a contiguous range - // of chars, we could quick-reject the range to avoid this loop (usually) - if (EmojiFont::IsAvailable()) { - const UChar* curr = buffer; - for (unsigned i = 0; i < length; i++) { - SkUnichar uni = SkUTF16_NextUnichar(&curr); - uint16_t glyphID = glyphs[i]; - // only sniff if the normal font failed to recognize it - if (!glyphID) - glyphID = EmojiFont::UnicharToGlyph(uni); - setGlyphDataForIndex(offset + i, glyphID, fontData); - allGlyphs |= glyphID; - } - } else { - for (unsigned i = 0; i < length; i++) { - uint16_t glyphID = glyphs[i]; - setGlyphDataForIndex(offset + i, glyphID, fontData); - allGlyphs |= glyphID; - } - } - return allGlyphs != 0; -} - -} diff --git a/WebCore/platform/graphics/android/GradientAndroid.cpp b/WebCore/platform/graphics/android/GradientAndroid.cpp deleted file mode 100644 index b8dc9dd..0000000 --- a/WebCore/platform/graphics/android/GradientAndroid.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "Gradient.h" - -#include "android_graphics.h" -#include "CSSParser.h" -#include "GraphicsContext.h" -#include "NotImplemented.h" -#include "SkCanvas.h" -#include "SkColorShader.h" -#include "SkGradientShader.h" -#include "SkPaint.h" - -class PlatformGradientRec { -public: - PlatformGradientRec() : m_shader(NULL) {} - ~PlatformGradientRec() { SkSafeUnref(m_shader); } - - SkShader* m_shader; - SkShader::TileMode m_tileMode; - int m_colorCountWhenShaderWasBuilt; -}; - -namespace WebCore { - -void Gradient::platformDestroy() -{ - delete m_gradient; - m_gradient = 0; -} - -static U8CPU F2B(float x) -{ - return (int)(x * 255); -} - -SkShader* Gradient::getShader(SkShader::TileMode mode) -{ - if (NULL == m_gradient) - m_gradient = new PlatformGradientRec; - else if (mode == m_gradient->m_tileMode) - return m_gradient->m_shader; - - // need to ensure that the m_stops array is sorted. We call getColor() - // which, as a side effect, does the sort. - // TODO: refactor Gradient.h to formally expose a sort method - { - float r, g, b, a; - this->getColor(0, &r, &g, &b, &a); - } - - SkPoint pts[2] = { m_p0, m_p1 }; // convert to SkPoint - - const size_t count = m_stops.size(); - SkAutoMalloc storage(count * (sizeof(SkColor) + sizeof(SkScalar))); - SkColor* colors = (SkColor*)storage.get(); - SkScalar* pos = (SkScalar*)(colors + count); - - Vector<ColorStop>::iterator iter = m_stops.begin(); - for (int i = 0; iter != m_stops.end(); i++) { - pos[i] = SkFloatToScalar(iter->stop); - colors[i] = SkColorSetARGB(F2B(iter->alpha), F2B(iter->red), - F2B(iter->green), F2B(iter->blue)); - ++iter; - } - - SkShader* s; - if (m_radial) - s = SkGradientShader::CreateTwoPointRadial(pts[0], - SkFloatToScalar(m_r0), - pts[1], - SkFloatToScalar(m_r1), - colors, pos, count, mode); - else - s = SkGradientShader::CreateLinear(pts, colors, pos, count, mode); - - if (NULL == s) - s = new SkColorShader(0); - - // zap our previous shader, if present - SkSafeUnref(m_gradient->m_shader); - m_gradient->m_shader = s; - m_gradient->m_tileMode = mode; - SkMatrix matrix = m_gradientSpaceTransformation; - s->setLocalMatrix(matrix); - - return s; -} - -void Gradient::fill(GraphicsContext* context, const FloatRect& rect) -{ - SkRect r; - SkPaint paint; - // we don't care about the mode, so try to use the existing one - SkShader::TileMode mode = m_gradient ? m_gradient->m_tileMode : - SkShader::kClamp_TileMode; - - paint.setAntiAlias(true); - paint.setShader(this->getShader(mode)); - android_gc2canvas(context)->drawRect(rect, paint); -} - - -} //namespace diff --git a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp deleted file mode 100644 index 888be5b..0000000 --- a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp +++ /dev/null @@ -1,1334 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "GraphicsContext.h" - -#include "AffineTransform.h" -#include "Gradient.h" -#include "NotImplemented.h" -#include "Path.h" -#include "Pattern.h" -#include "PlatformGraphicsContext.h" -#include "SkBitmapRef.h" -#include "SkBlurDrawLooper.h" -#include "SkBlurMaskFilter.h" -#include "SkCanvas.h" -#include "SkColorPriv.h" -#include "SkDashPathEffect.h" -#include "SkDevice.h" -#include "SkGradientShader.h" -#include "SkPaint.h" -#include "SkString.h" -#include "SkiaUtils.h" -#include "TransformationMatrix.h" -#include "android_graphics.h" - -using namespace std; - -#define GC2CANVAS(ctx) (ctx)->m_data->getPlatformGfxCtx()->mCanvas - -namespace WebCore { - -static int RoundToInt(float x) -{ - return (int)roundf(x); -} - -template <typename T> T* deepCopyPtr(const T* src) -{ - return src ? new T(*src) : 0; -} - -// Set a bitmap shader that mimics dashing by width-on, width-off. -// Returns false if it could not succeed (e.g. there was an existing shader) -static bool setBitmapDash(SkPaint* paint, int width) { - if (width <= 0 || paint->getShader()) - return false; - - SkColor c = paint->getColor(); - - SkBitmap bm; - bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 1); - bm.allocPixels(); - bm.lockPixels(); - - // set the ON pixel - *bm.getAddr32(0, 0) = SkPreMultiplyARGB(0xFF, SkColorGetR(c), - SkColorGetG(c), SkColorGetB(c)); - // set the OFF pixel - *bm.getAddr32(1, 0) = 0; - bm.unlockPixels(); - - SkMatrix matrix; - matrix.setScale(SkIntToScalar(width), SK_Scalar1); - - SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode, - SkShader::kClamp_TileMode); - s->setLocalMatrix(matrix); - - paint->setShader(s)->unref(); - return true; -} - -// TODO / questions - -// alpha: how does this interact with the alpha in Color? multiply them together? -// mode: do I always respect this? If so, then -// the rgb() & 0xFF000000 check will abort drawing too often -// Is Color premultiplied or not? If it is, then I can't blindly pass it to paint.setColor() - -struct ShadowRec { - SkScalar blur; - SkScalar dx; - SkScalar dy; - SkColor color; // alpha>0 means valid shadow - ShadowRec(SkScalar b = 0, - SkScalar x = 0, - SkScalar y = 0, - SkColor c = 0) // by default, alpha=0, so no shadow - : blur(b), dx(x), dy(y), color(c) - {}; -}; - -class GraphicsContextPlatformPrivate { -public: - struct State { - SkPath* path; - SkPathEffect* pathEffect; - float miterLimit; - float alpha; - float strokeThickness; - SkPaint::Cap lineCap; - SkPaint::Join lineJoin; - SkXfermode::Mode mode; - int dashRatio; // Ratio of the length of a dash to its width - ShadowRec shadow; - SkColor fillColor; - SkColor strokeColor; - bool useAA; - // This is a list of clipping paths which are currently active, in the - // order in which they were pushed. - WTF::Vector<SkPath> antiAliasClipPaths; - - State() - : path(0) // Lazily allocated - , pathEffect(0) - , miterLimit(4) - , alpha(1) - , strokeThickness(0) // Same as default in GraphicsContextPrivate.h - , lineCap(SkPaint::kDefault_Cap) - , lineJoin(SkPaint::kDefault_Join) - , mode(SkXfermode::kSrcOver_Mode) - , dashRatio(3) - , fillColor(SK_ColorBLACK) - , strokeColor(SK_ColorBLACK) - , useAA(true) - { - } - - State(const State& other) - : pathEffect(other.pathEffect) - , miterLimit(other.miterLimit) - , alpha(other.alpha) - , strokeThickness(other.strokeThickness) - , lineCap(other.lineCap) - , lineJoin(other.lineJoin) - , mode(other.mode) - , dashRatio(other.dashRatio) - , shadow(other.shadow) - , fillColor(other.fillColor) - , strokeColor(other.strokeColor) - , useAA(other.useAA) - { - path = deepCopyPtr<SkPath>(other.path); - SkSafeRef(pathEffect); - } - - ~State() - { - delete path; - SkSafeUnref(pathEffect); - } - - void setShadow(int radius, int dx, int dy, SkColor c) - { - // Cut the radius in half, to visually match the effect seen in - // safari browser - shadow.blur = SkScalarHalf(SkIntToScalar(radius)); - shadow.dx = SkIntToScalar(dx); - shadow.dy = SkIntToScalar(dy); - shadow.color = c; - } - - bool setupShadowPaint(GraphicsContext* ctx, SkPaint* paint, SkPoint* offset) - { - paint->setAntiAlias(true); - paint->setDither(true); - paint->setXfermodeMode(mode); - paint->setColor(shadow.color); - offset->set(shadow.dx, shadow.dy); - - // Currently, only GraphicsContexts associated with the - // HTMLCanvasElement have shadows ignore transforms set. This - // allows us to distinguish between CSS and Canvas shadows which - // have different rendering specifications. - uint32_t flags = SkBlurMaskFilter::kHighQuality_BlurFlag; - if (ctx->shadowsIgnoreTransforms()) { - offset->fY = -offset->fY; - flags |= SkBlurMaskFilter::kIgnoreTransform_BlurFlag; - } - - if (shadow.blur > 0) { - paint->setMaskFilter(SkBlurMaskFilter::Create(shadow.blur, - SkBlurMaskFilter::kNormal_BlurStyle))->unref(); - } - return SkColorGetA(shadow.color) && (shadow.blur || shadow.dx || shadow.dy); - } - - SkColor applyAlpha(SkColor c) const - { - int s = RoundToInt(alpha * 256); - if (s >= 256) - return c; - if (s < 0) - return 0; - - int a = SkAlphaMul(SkColorGetA(c), s); - return (c & 0x00FFFFFF) | (a << 24); - } - }; - - GraphicsContextPlatformPrivate(GraphicsContext* gfxCtx, PlatformGraphicsContext* platformGfxCtx) - : m_parentGfxCtx(gfxCtx) - , m_platformGfxCtx(platformGfxCtx) - , m_stateStack(sizeof(State)) - { - State* state = static_cast<State*>(m_stateStack.push_back()); - new (state) State(); - m_state = state; - } - - ~GraphicsContextPlatformPrivate() - { - // We force restores so we don't leak any subobjects owned by our - // stack of State records. - while (m_stateStack.count() > 0) - this->restore(); - - if (m_platformGfxCtx && m_platformGfxCtx->deleteUs()) - delete m_platformGfxCtx; - } - - void save() - { - State* newState = static_cast<State*>(m_stateStack.push_back()); - new (newState) State(*m_state); - m_state = newState; - } - - void restore() - { - if (!m_state->antiAliasClipPaths.isEmpty()) - applyAntiAliasedClipPaths(m_state->antiAliasClipPaths); - - m_state->~State(); - m_stateStack.pop_back(); - m_state = static_cast<State*>(m_stateStack.back()); - } - - void setFillColor(const Color& c) - { - m_state->fillColor = c.rgb(); - } - - void setStrokeColor(const Color& c) - { - m_state->strokeColor = c.rgb(); - } - - void setStrokeThickness(float f) - { - m_state->strokeThickness = f; - } - - void beginPath() - { - if (m_state->path) - m_state->path->reset(); - } - - void addPath(const SkPath& other) - { - if (!m_state->path) - m_state->path = new SkPath(other); - else - m_state->path->addPath(other); - } - - // May return null - SkPath* getPath() const - { - return m_state->path; - } - - void setupPaintCommon(SkPaint* paint) const - { - paint->setAntiAlias(m_state->useAA); - paint->setDither(true); - paint->setXfermodeMode(m_state->mode); - if (SkColorGetA(m_state->shadow.color) > 0) { - - // Currently, only GraphicsContexts associated with the - // HTMLCanvasElement have shadows ignore transforms set. This - // allows us to distinguish between CSS and Canvas shadows which - // have different rendering specifications. - SkScalar dy = m_state->shadow.dy; - uint32_t flags = SkBlurDrawLooper::kHighQuality_BlurFlag; - if (m_parentGfxCtx->shadowsIgnoreTransforms()) { - dy = -dy; - flags |= SkBlurDrawLooper::kIgnoreTransform_BlurFlag; - flags |= SkBlurDrawLooper::kOverrideColor_BlurFlag; - } - - SkDrawLooper* looper = new SkBlurDrawLooper(m_state->shadow.blur, - m_state->shadow.dx, - dy, - m_state->shadow.color, - flags); - paint->setLooper(looper)->unref(); - } - } - - void setupPaintFill(SkPaint* paint) const - { - this->setupPaintCommon(paint); - paint->setColor(m_state->applyAlpha(m_state->fillColor)); - } - - void setupPaintBitmap(SkPaint* paint) const - { - this->setupPaintCommon(paint); - // We only want the global alpha for bitmaps, - // so just give applyAlpha opaque black - paint->setColor(m_state->applyAlpha(0xFF000000)); - } - - // Sets up the paint for stroking. Returns true if the style is really - // just a dash of squares (the size of the paint's stroke-width. - bool setupPaintStroke(SkPaint* paint, SkRect* rect, bool isHLine = false) - { - this->setupPaintCommon(paint); - paint->setColor(m_state->applyAlpha(m_state->strokeColor)); - - float width = m_state->strokeThickness; - - // This allows dashing and dotting to work properly for hairline strokes - // FIXME: Should we only do this for dashed and dotted strokes? - if (!width) - width = 1; - - paint->setStyle(SkPaint::kStroke_Style); - paint->setStrokeWidth(SkFloatToScalar(width)); - paint->setStrokeCap(m_state->lineCap); - paint->setStrokeJoin(m_state->lineJoin); - paint->setStrokeMiter(SkFloatToScalar(m_state->miterLimit)); - - if (rect && (RoundToInt(width) & 1)) - rect->inset(-SK_ScalarHalf, -SK_ScalarHalf); - - SkPathEffect* pe = m_state->pathEffect; - if (pe) { - paint->setPathEffect(pe); - return false; - } - switch (m_parentGfxCtx->strokeStyle()) { - case NoStroke: - case SolidStroke: - width = 0; - break; - case DashedStroke: - width = m_state->dashRatio * width; - break; - // No break - case DottedStroke: - break; - } - - if (width > 0) { - // Return true if we're basically a dotted dash of squares - bool justSqrs = RoundToInt(width) == RoundToInt(paint->getStrokeWidth()); - - if (justSqrs || !isHLine || !setBitmapDash(paint, width)) { -#if 0 - // this is slow enough that we just skip it for now - // see http://b/issue?id=4163023 - SkScalar intervals[] = { width, width }; - pe = new SkDashPathEffect(intervals, 2, 0); - paint->setPathEffect(pe)->unref(); -#endif - } - return justSqrs; - } - return false; - } - - void clipPathAntiAliased(const SkPath& clipPath) - { - // If we are currently tracking any anti-alias clip paths, then we already - // have a layer in place and don't need to add another. - bool haveLayerOutstanding = m_state->antiAliasClipPaths.size(); - - // See comments in applyAntiAliasedClipPaths about how this works. - m_state->antiAliasClipPaths.append(clipPath); - if (!haveLayerOutstanding) { - SkRect bounds = clipPath.getBounds(); - if (m_platformGfxCtx && m_platformGfxCtx->mCanvas) - m_platformGfxCtx->mCanvas->saveLayerAlpha(&bounds, 255, - static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag - | SkCanvas::kFullColorLayer_SaveFlag - | SkCanvas::kClipToLayer_SaveFlag)); - else - ASSERT(0); - } - } - - void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths) - { - // Anti-aliased clipping: - // - // Refer to PlatformContextSkia.cpp's applyAntiAliasedClipPaths() for more details - SkPaint paint; - paint.setXfermodeMode(SkXfermode::kClear_Mode); - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kFill_Style); - - if (m_platformGfxCtx && m_platformGfxCtx->mCanvas) { - for (size_t i = paths.size() - 1; i < paths.size(); --i) { - paths[i].setFillType(SkPath::kInverseWinding_FillType); - m_platformGfxCtx->mCanvas->drawPath(paths[i], paint); - } - m_platformGfxCtx->mCanvas->restore(); - } else - ASSERT(0); - } - - PlatformGraphicsContext* getPlatformGfxCtx() - { - return m_platformGfxCtx; - } - - State* getState() - { - return m_state; - } -private: - State* m_state; - GraphicsContext* m_parentGfxCtx; // Back-ptr to our parent - PlatformGraphicsContext* m_platformGfxCtx; - SkDeque m_stateStack; - // Not supported yet - State& operator=(const State&); -}; - -static SkShader::TileMode SpreadMethod2TileMode(GradientSpreadMethod sm) -{ - SkShader::TileMode mode = SkShader::kClamp_TileMode; - - switch (sm) { - case SpreadMethodPad: - mode = SkShader::kClamp_TileMode; - break; - case SpreadMethodReflect: - mode = SkShader::kMirror_TileMode; - break; - case SpreadMethodRepeat: - mode = SkShader::kRepeat_TileMode; - break; - } - return mode; -} - -static void extactShader(SkPaint* paint, Pattern* pat, Gradient* grad) -{ - if (pat) { - // platformPattern() returns a cached obj - paint->setShader(pat->platformPattern(AffineTransform())); - } else if (grad) { - // grad->getShader() returns a cached obj - GradientSpreadMethod sm = grad->spreadMethod(); - paint->setShader(grad->getShader(SpreadMethod2TileMode(sm))); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////// - -GraphicsContext* GraphicsContext::createOffscreenContext(int width, int height) -{ - PlatformGraphicsContext* pgc = new PlatformGraphicsContext(); - - SkBitmap bitmap; - - bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); - bitmap.allocPixels(); - bitmap.eraseColor(0); - pgc->mCanvas->setBitmapDevice(bitmap); - - GraphicsContext* ctx = new GraphicsContext(pgc); - return ctx; -} - -//////////////////////////////////////////////////////////////////////////////////////////////// - -void GraphicsContext::platformInit(PlatformGraphicsContext* gc) -{ - m_data = new GraphicsContextPlatformPrivate(this, gc); - setPaintingDisabled(!gc || !gc->mCanvas); -} - -void GraphicsContext::platformDestroy() -{ - delete m_data; -} - -void GraphicsContext::savePlatformState() -{ - // Save our private State - m_data->save(); - // Save our native canvas - GC2CANVAS(this)->save(); -} - -void GraphicsContext::restorePlatformState() -{ - // Restore our private State - m_data->restore(); - // Restore our native canvas - GC2CANVAS(this)->restore(); -} - -bool GraphicsContext::willFill() const -{ - return m_data->getState()->fillColor; -} - -bool GraphicsContext::willStroke() const -{ - return m_data->getState()->strokeColor; -} - -const SkPath* GraphicsContext::getCurrPath() const -{ - return m_data->getState()->path; -} - -// Draws a filled rectangle with a stroked border. -void GraphicsContext::drawRect(const IntRect& rect) -{ - if (paintingDisabled()) - return; - - SkPaint paint; - SkRect r(rect); - - if (fillColor().alpha()) { - m_data->setupPaintFill(&paint); - GC2CANVAS(this)->drawRect(r, paint); - } - - // According to GraphicsContext.h, stroking inside drawRect always means - // a stroke of 1 inside the rect. - if (strokeStyle() != NoStroke && strokeColor().alpha()) { - paint.reset(); - m_data->setupPaintStroke(&paint, &r); - paint.setPathEffect(0); // No dashing please - paint.setStrokeWidth(SK_Scalar1); // Always just 1.0 width - r.inset(SK_ScalarHalf, SK_ScalarHalf); // Ensure we're "inside" - GC2CANVAS(this)->drawRect(r, paint); - } -} - -// This is only used to draw borders. -void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) -{ - if (paintingDisabled()) - return; - - StrokeStyle style = strokeStyle(); - if (style == NoStroke) - return; - - SkPaint paint; - SkCanvas* canvas = GC2CANVAS(this); - const int idx = SkAbs32(point2.x() - point1.x()); - const int idy = SkAbs32(point2.y() - point1.y()); - - // Special-case horizontal and vertical lines that are really just dots - if (m_data->setupPaintStroke(&paint, 0, !idy) && (!idx || !idy)) { - const SkScalar diameter = paint.getStrokeWidth(); - const SkScalar radius = SkScalarHalf(diameter); - SkScalar x = SkIntToScalar(SkMin32(point1.x(), point2.x())); - SkScalar y = SkIntToScalar(SkMin32(point1.y(), point2.y())); - SkScalar dx, dy; - int count; - SkRect bounds; - - if (!idy) { // Horizontal - bounds.set(x, y - radius, x + SkIntToScalar(idx), y + radius); - x += radius; - dx = diameter * 2; - dy = 0; - count = idx; - } else { // Vertical - bounds.set(x - radius, y, x + radius, y + SkIntToScalar(idy)); - y += radius; - dx = 0; - dy = diameter * 2; - count = idy; - } - - // The actual count is the number of ONs we hit alternating - // ON(diameter), OFF(diameter), ... - { - SkScalar width = SkScalarDiv(SkIntToScalar(count), diameter); - // Now compute the number of cells (ON and OFF) - count = SkScalarRound(width); - // Now compute the number of ONs - count = (count + 1) >> 1; - } - - SkAutoMalloc storage(count * sizeof(SkPoint)); - SkPoint* verts = (SkPoint*)storage.get(); - // Now build the array of vertices to past to drawPoints - for (int i = 0; i < count; i++) { - verts[i].set(x, y); - x += dx; - y += dy; - } - - paint.setStyle(SkPaint::kFill_Style); - paint.setPathEffect(0); - - // Clipping to bounds is not required for correctness, but it does - // allow us to reject the entire array of points if we are completely - // offscreen. This is common in a webpage for android, where most of - // the content is clipped out. If drawPoints took an (optional) bounds - // parameter, that might even be better, as we would *just* use it for - // culling, and not both wacking the canvas' save/restore stack. - canvas->save(SkCanvas::kClip_SaveFlag); - canvas->clipRect(bounds); - canvas->drawPoints(SkCanvas::kPoints_PointMode, count, verts, paint); - canvas->restore(); - } else { - SkPoint pts[2] = { point1, point2 }; - canvas->drawLine(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, paint); - } -} - -static void setrectForUnderline(SkRect* r, GraphicsContext* context, const IntPoint& point, int yOffset, int width) -{ - float lineThickness = context->strokeThickness(); -#if 0 - if (lineThickness < 1) // Do we really need/want this? - lineThickness = 1; -#endif - r->fLeft = SkIntToScalar(point.x()); - r->fTop = SkIntToScalar(point.y() + yOffset); - r->fRight = r->fLeft + SkIntToScalar(width); - r->fBottom = r->fTop + SkFloatToScalar(lineThickness); -} - -void GraphicsContext::drawLineForText(IntPoint const& pt, int width, bool) -{ - if (paintingDisabled()) - return; - - SkRect r; - setrectForUnderline(&r, this, pt, 0, width); - - SkPaint paint; - paint.setAntiAlias(true); - paint.setColor(this->strokeColor().rgb()); - - GC2CANVAS(this)->drawRect(r, paint); -} - -// TODO: Should we draw different based on TextCheckingLineStyle? -void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, TextCheckingLineStyle) -{ - if (paintingDisabled()) - return; - - SkRect r; - setrectForUnderline(&r, this, pt, 0, width); - - SkPaint paint; - paint.setAntiAlias(true); - paint.setColor(SK_ColorRED); // Is this specified somewhere? - - GC2CANVAS(this)->drawRect(r, paint); -} - -// This method is only used to draw the little circles used in lists. -void GraphicsContext::drawEllipse(const IntRect& rect) -{ - if (paintingDisabled()) - return; - - SkPaint paint; - SkRect oval(rect); - - if (fillColor().rgb() & 0xFF000000) { - m_data->setupPaintFill(&paint); - GC2CANVAS(this)->drawOval(oval, paint); - } - if (strokeStyle() != NoStroke) { - paint.reset(); - m_data->setupPaintStroke(&paint, &oval); - GC2CANVAS(this)->drawOval(oval, paint); - } -} - -static inline int fastMod(int value, int max) -{ - int sign = SkExtractSign(value); - - value = SkApplySign(value, sign); - if (value >= max) - value %= max; - return SkApplySign(value, sign); -} - -void GraphicsContext::strokeArc(const IntRect& r, int startAngle, int angleSpan) -{ - if (paintingDisabled()) - return; - - SkPath path; - SkPaint paint; - SkRect oval(r); - - if (strokeStyle() == NoStroke) { - m_data->setupPaintFill(&paint); // We want the fill color - paint.setStyle(SkPaint::kStroke_Style); - paint.setStrokeWidth(SkFloatToScalar(this->strokeThickness())); - } else - m_data->setupPaintStroke(&paint, 0); - - // We do this before converting to scalar, so we don't overflow SkFixed - startAngle = fastMod(startAngle, 360); - angleSpan = fastMod(angleSpan, 360); - - path.addArc(oval, SkIntToScalar(-startAngle), SkIntToScalar(-angleSpan)); - GC2CANVAS(this)->drawPath(path, paint); -} - -void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias) -{ - if (paintingDisabled()) - return; - - if (numPoints <= 1) - return; - - SkPaint paint; - SkPath path; - - path.incReserve(numPoints); - path.moveTo(SkFloatToScalar(points[0].x()), SkFloatToScalar(points[0].y())); - for (size_t i = 1; i < numPoints; i++) - path.lineTo(SkFloatToScalar(points[i].x()), SkFloatToScalar(points[i].y())); - - if (GC2CANVAS(this)->quickReject(path, shouldAntialias ? - SkCanvas::kAA_EdgeType : SkCanvas::kBW_EdgeType)) { - return; - } - - if (fillColor().rgb() & 0xFF000000) { - m_data->setupPaintFill(&paint); - paint.setAntiAlias(shouldAntialias); - GC2CANVAS(this)->drawPath(path, paint); - } - - if (strokeStyle() != NoStroke) { - paint.reset(); - m_data->setupPaintStroke(&paint, 0); - paint.setAntiAlias(shouldAntialias); - GC2CANVAS(this)->drawPath(path, paint); - } -} - -void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, - const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace) -{ - if (paintingDisabled()) - return; - - SkPaint paint; - SkPath path; - SkScalar radii[8]; - - radii[0] = SkIntToScalar(topLeft.width()); - radii[1] = SkIntToScalar(topLeft.height()); - radii[2] = SkIntToScalar(topRight.width()); - radii[3] = SkIntToScalar(topRight.height()); - radii[4] = SkIntToScalar(bottomRight.width()); - radii[5] = SkIntToScalar(bottomRight.height()); - radii[6] = SkIntToScalar(bottomLeft.width()); - radii[7] = SkIntToScalar(bottomLeft.height()); - path.addRoundRect(rect, radii); - - m_data->setupPaintFill(&paint); - GC2CANVAS(this)->drawPath(path, paint); -} - -void GraphicsContext::fillRect(const FloatRect& rect) -{ - SkPaint paint; - - m_data->setupPaintFill(&paint); - - extactShader(&paint, - m_state.fillPattern.get(), - m_state.fillGradient.get()); - - GC2CANVAS(this)->drawRect(rect, paint); -} - -void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace) -{ - if (paintingDisabled()) - return; - - if (color.rgb() & 0xFF000000) { - SkPaint paint; - - m_data->setupPaintCommon(&paint); - paint.setColor(color.rgb()); // Punch in the specified color - paint.setShader(0); // In case we had one set - - // Sometimes we record and draw portions of the page, using clips - // for each portion. The problem with this is that webkit, sometimes, - // sees that we're only recording a portion, and they adjust some of - // their rectangle coordinates accordingly (e.g. - // RenderBoxModelObject::paintFillLayerExtended() which calls - // rect.intersect(paintInfo.rect) and then draws the bg with that - // rect. The result is that we end up drawing rects that are meant to - // seam together (one for each portion), but if the rects have - // fractional coordinates (e.g. we are zoomed by a fractional amount) - // we will double-draw those edges, resulting in visual cracks or - // artifacts. - - // The fix seems to be to just turn off antialasing for rects (this - // entry-point in GraphicsContext seems to have been sufficient, - // though perhaps we'll find we need to do this as well in fillRect(r) - // as well.) Currently setupPaintCommon() enables antialiasing. - - // Since we never show the page rotated at a funny angle, disabling - // antialiasing seems to have no real down-side, and it does fix the - // bug when we're zoomed (and drawing portions that need to seam). - paint.setAntiAlias(false); - - GC2CANVAS(this)->drawRect(rect, paint); - } -} - -void GraphicsContext::clip(const FloatRect& rect) -{ - if (paintingDisabled()) - return; - - GC2CANVAS(this)->clipRect(rect); -} - -void GraphicsContext::clip(const Path& path) -{ - if (paintingDisabled()) - return; - - m_data->clipPathAntiAliased(*path.platformPath()); -} - -void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) -{ - if (paintingDisabled()) - return; - - SkPath path; - SkRect r(rect); - - path.addOval(r, SkPath::kCW_Direction); - // Only perform the inset if we won't invert r - if (2 * thickness < rect.width() && 2 * thickness < rect.height()) { - // Adding one to the thickness doesn't make the border too thick as - // it's painted over afterwards. But without this adjustment the - // border appears a little anemic after anti-aliasing. - r.inset(SkIntToScalar(thickness + 1), SkIntToScalar(thickness + 1)); - path.addOval(r, SkPath::kCCW_Direction); - } - m_data->clipPathAntiAliased(path); -} - -void GraphicsContext::canvasClip(const Path& path) -{ - clip(path); -} - -void GraphicsContext::clipOut(const IntRect& r) -{ - if (paintingDisabled()) - return; - - GC2CANVAS(this)->clipRect(r, SkRegion::kDifference_Op); -} - -#if ENABLE(SVG) -void GraphicsContext::clipPath(const Path& pathToClip, WindRule clipRule) -{ - if (paintingDisabled()) - return; - - // FIXME: Be smarter about this. - beginPath(); - addPath(pathToClip); - - const SkPath* oldPath = m_data->getPath(); - SkPath path(*oldPath); - path.setFillType(clipRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType); - GC2CANVAS(this)->clipPath(path); -} -#endif - -void GraphicsContext::clipOut(const Path& p) -{ - if (paintingDisabled()) - return; - - GC2CANVAS(this)->clipPath(*p.platformPath(), SkRegion::kDifference_Op); -} - -////////////////////////////////////////////////////////////////////////////////////////////////// - -#if SVG_SUPPORT -KRenderingDeviceContext* GraphicsContext::createRenderingDeviceContext() -{ - return new KRenderingDeviceContextQuartz(platformContext()); -} -#endif - -// These are the flags we need when we call saveLayer for transparency. -// Since it does not appear that webkit intends this to also save/restore -// the matrix or clip, I do not give those flags (for performance) -#define TRANSPARENCY_SAVEFLAGS \ - (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | \ - SkCanvas::kFullColorLayer_SaveFlag) - -void GraphicsContext::beginTransparencyLayer(float opacity) -{ - if (paintingDisabled()) - return; - - SkCanvas* canvas = GC2CANVAS(this); - canvas->saveLayerAlpha(0, (int)(opacity * 255), TRANSPARENCY_SAVEFLAGS); -} - -void GraphicsContext::endTransparencyLayer() -{ - if (paintingDisabled()) - return; - - GC2CANVAS(this)->restore(); -} - -/////////////////////////////////////////////////////////////////////////// - -void GraphicsContext::setupBitmapPaint(SkPaint* paint) -{ - m_data->setupPaintBitmap(paint); -} - -void GraphicsContext::setupFillPaint(SkPaint* paint) -{ - m_data->setupPaintFill(paint); -} - -void GraphicsContext::setupStrokePaint(SkPaint* paint) -{ - m_data->setupPaintStroke(paint, 0); -} - -bool GraphicsContext::setupShadowPaint(SkPaint* paint, SkPoint* offset) -{ - return m_data->getState()->setupShadowPaint(this, paint, offset); -} - -void GraphicsContext::setPlatformStrokeColor(const Color& c, ColorSpace) -{ - m_data->setStrokeColor(c); -} - -void GraphicsContext::setPlatformStrokeThickness(float f) -{ - m_data->setStrokeThickness(f); -} - -void GraphicsContext::setPlatformFillColor(const Color& c, ColorSpace) -{ - m_data->setFillColor(c); -} - -void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const Color& color, ColorSpace) -{ - if (paintingDisabled()) - return; - - if (blur <= 0) - this->clearPlatformShadow(); - - SkColor c; - if (color.isValid()) - c = color.rgb(); - else - c = SkColorSetARGB(0xFF / 3, 0, 0, 0); // "std" Apple shadow color - m_data->getState()->setShadow(blur, size.width(), size.height(), c); -} - -void GraphicsContext::clearPlatformShadow() -{ - if (paintingDisabled()) - return; - - m_data->getState()->setShadow(0, 0, 0, 0); -} - -/////////////////////////////////////////////////////////////////////////////// - -void GraphicsContext::drawFocusRing(const Vector<IntRect>&, int, int, const Color&) -{ - // Do nothing, since we draw the focus ring independently. -} - -void GraphicsContext::drawFocusRing(const Path&, int, int, const Color&) -{ - // Do nothing, since we draw the focus ring independently. -} - -PlatformGraphicsContext* GraphicsContext::platformContext() const -{ - ASSERT(!paintingDisabled()); - return m_data->getPlatformGfxCtx(); -} - -void GraphicsContext::setMiterLimit(float limit) -{ - m_data->getState()->miterLimit = limit; -} - -void GraphicsContext::setAlpha(float alpha) -{ - m_data->getState()->alpha = alpha; -} - -void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op) -{ - m_data->getState()->mode = WebCoreCompositeToSkiaComposite(op); -} - -void GraphicsContext::clearRect(const FloatRect& rect) -{ - if (paintingDisabled()) - return; - - SkPaint paint; - - m_data->setupPaintFill(&paint); - paint.setXfermodeMode(SkXfermode::kClear_Mode); - GC2CANVAS(this)->drawRect(rect, paint); -} - -void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) -{ - if (paintingDisabled()) - return; - - SkPaint paint; - - m_data->setupPaintStroke(&paint, 0); - paint.setStrokeWidth(SkFloatToScalar(lineWidth)); - GC2CANVAS(this)->drawRect(rect, paint); -} - -void GraphicsContext::setLineCap(LineCap cap) -{ - switch (cap) { - case ButtCap: - m_data->getState()->lineCap = SkPaint::kButt_Cap; - break; - case RoundCap: - m_data->getState()->lineCap = SkPaint::kRound_Cap; - break; - case SquareCap: - m_data->getState()->lineCap = SkPaint::kSquare_Cap; - break; - default: - SkDEBUGF(("GraphicsContext::setLineCap: unknown LineCap %d\n", cap)); - break; - } -} - -#if ENABLE(SVG) -void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset) -{ - if (paintingDisabled()) - return; - - size_t dashLength = dashes.size(); - if (!dashLength) - return; - - size_t count = !(dashLength % 2) ? dashLength : dashLength * 2; - SkScalar* intervals = new SkScalar[count]; - - for (unsigned int i = 0; i < count; i++) - intervals[i] = SkFloatToScalar(dashes[i % dashLength]); - SkPathEffect **effectPtr = &m_data->getState()->pathEffect; - SkSafeUnref(*effectPtr); - *effectPtr = new SkDashPathEffect(intervals, count, SkFloatToScalar(dashOffset)); - - delete[] intervals; -} -#endif - -void GraphicsContext::setLineJoin(LineJoin join) -{ - switch (join) { - case MiterJoin: - m_data->getState()->lineJoin = SkPaint::kMiter_Join; - break; - case RoundJoin: - m_data->getState()->lineJoin = SkPaint::kRound_Join; - break; - case BevelJoin: - m_data->getState()->lineJoin = SkPaint::kBevel_Join; - break; - default: - SkDEBUGF(("GraphicsContext::setLineJoin: unknown LineJoin %d\n", join)); - break; - } -} - -void GraphicsContext::scale(const FloatSize& size) -{ - if (paintingDisabled()) - return; - GC2CANVAS(this)->scale(SkFloatToScalar(size.width()), SkFloatToScalar(size.height())); -} - -void GraphicsContext::rotate(float angleInRadians) -{ - if (paintingDisabled()) - return; - GC2CANVAS(this)->rotate(SkFloatToScalar(angleInRadians * (180.0f / 3.14159265f))); -} - -void GraphicsContext::translate(float x, float y) -{ - if (paintingDisabled()) - return; - GC2CANVAS(this)->translate(SkFloatToScalar(x), SkFloatToScalar(y)); -} - -void GraphicsContext::concatCTM(const AffineTransform& affine) -{ - if (paintingDisabled()) - return; - GC2CANVAS(this)->concat(affine); -} - -// This is intended to round the rect to device pixels (through the CTM) -// and then invert the result back into source space, with the hope that when -// it is drawn (through the matrix), it will land in the "right" place (i.e. -// on pixel boundaries). - -// For android, we record this geometry once and then draw it though various -// scale factors as the user zooms, without re-recording. Thus this routine -// should just leave the original geometry alone. - -// If we instead draw into bitmap tiles, we should then perform this -// transform -> round -> inverse step. - -FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) -{ - return rect; -} - -////////////////////////////////////////////////////////////////////////////////////////////////// - -void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) -{ -// Appears to be PDF specific, so we ignore it -#if 0 -if (paintingDisabled()) - return; - -CFURLRef urlRef = link.createCFURL(); -if (urlRef) { - CGContextRef context = platformContext(); - - // Get the bounding box to handle clipping. - CGRect box = CGContextGetClipBoundingBox(context); - - IntRect intBox((int)box.origin.x, (int)box.origin.y, (int)box.size.width, (int)box.size.height); - IntRect rect = destRect; - rect.intersect(intBox); - - CGPDFContextSetURLForRect(context, urlRef, - CGRectApplyAffineTransform(rect, CGContextGetCTM(context))); - - CFRelease(urlRef); -} -#endif -} - -void GraphicsContext::setPlatformShouldAntialias(bool useAA) -{ - if (paintingDisabled()) - return; - m_data->getState()->useAA = useAA; -} - -AffineTransform GraphicsContext::getCTM() const -{ - const SkMatrix& m = GC2CANVAS(this)->getTotalMatrix(); - return AffineTransform(SkScalarToDouble(m.getScaleX()), // a - SkScalarToDouble(m.getSkewY()), // b - SkScalarToDouble(m.getSkewX()), // c - SkScalarToDouble(m.getScaleY()), // d - SkScalarToDouble(m.getTranslateX()), // e - SkScalarToDouble(m.getTranslateY())); // f -} - -/////////////////////////////////////////////////////////////////////////////// - -void GraphicsContext::beginPath() -{ - m_data->beginPath(); -} - -void GraphicsContext::addPath(const Path& p) -{ - m_data->addPath(*p.platformPath()); -} - -void GraphicsContext::fillPath(const Path& pathToFill) -{ - // FIXME: Be smarter about this. - beginPath(); - addPath(pathToFill); - - SkPath* path = m_data->getPath(); - if (paintingDisabled() || !path) - return; - - switch (this->fillRule()) { - case RULE_NONZERO: - path->setFillType(SkPath::kWinding_FillType); - break; - case RULE_EVENODD: - path->setFillType(SkPath::kEvenOdd_FillType); - break; - } - - SkPaint paint; - m_data->setupPaintFill(&paint); - - extactShader(&paint, - m_state.fillPattern.get(), - m_state.fillGradient.get()); - - GC2CANVAS(this)->drawPath(*path, paint); -} - -void GraphicsContext::strokePath(const Path& pathToStroke) -{ - // FIXME: Be smarter about this. - beginPath(); - addPath(pathToStroke); - - const SkPath* path = m_data->getPath(); - if (paintingDisabled() || !path) - return; - - SkPaint paint; - m_data->setupPaintStroke(&paint, 0); - - extactShader(&paint, - m_state.strokePattern.get(), - m_state.strokeGradient.get()); - - GC2CANVAS(this)->drawPath(*path, paint); -} - -InterpolationQuality GraphicsContext::imageInterpolationQuality() const -{ - notImplemented(); - return InterpolationDefault; -} - -void GraphicsContext::setImageInterpolationQuality(InterpolationQuality mode) -{ -#if 0 - enum InterpolationQuality { - InterpolationDefault, - InterpolationNone, - InterpolationLow, - InterpolationMedium, - InterpolationHigh - }; -#endif - // TODO: record this, so we can know when to use bitmap-filtering when we draw - // ... not sure how meaningful this will be given our playback model. - - // Certainly safe to do nothing for the present. -} - -void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias) -{ - if (paintingDisabled()) - return; - - if (numPoints <= 1) - return; - - // FIXME: IMPLEMENT! -} - -} // namespace WebCore - -/////////////////////////////////////////////////////////////////////////////// - -SkCanvas* android_gc2canvas(WebCore::GraphicsContext* gc) -{ - return gc->platformContext()->mCanvas; -} diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp deleted file mode 100644 index e8120f9..0000000 --- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp +++ /dev/null @@ -1,989 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "config.h" -#include "GraphicsLayerAndroid.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "AndroidAnimation.h" -#include "Animation.h" -#include "FloatRect.h" -#include "GraphicsContext.h" -#include "Image.h" -#include "Length.h" -#include "MediaLayer.h" -#include "PlatformBridge.h" -#include "PlatformGraphicsContext.h" -#include "RenderLayerBacking.h" -#include "RenderView.h" -#include "RotateTransformOperation.h" -#include "ScaleTransformOperation.h" -#include "ScrollableLayerAndroid.h" -#include "SkCanvas.h" -#include "SkLayer.h" -#include "TransformationMatrix.h" -#include "TranslateTransformOperation.h" - -#include <cutils/log.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/CString.h> - -#undef LOG -#define LOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__) -#define MLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__) -#define TLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__) - -#undef LOG -#define LOG(...) -#undef MLOG -#define MLOG(...) -#undef TLOG -#define TLOG(...) -#undef LAYER_DEBUG - -using namespace std; - -static bool gPaused; -static double gPausedDelay; - -namespace WebCore { - -static int gDebugGraphicsLayerAndroidInstances = 0; -inline int GraphicsLayerAndroid::instancesCount() -{ - return gDebugGraphicsLayerAndroidInstances; -} - -static String propertyIdToString(AnimatedPropertyID property) -{ - switch (property) { - case AnimatedPropertyWebkitTransform: - return "transform"; - case AnimatedPropertyOpacity: - return "opacity"; - case AnimatedPropertyBackgroundColor: - return "backgroundColor"; - case AnimatedPropertyInvalid: - ASSERT_NOT_REACHED(); - } - ASSERT_NOT_REACHED(); - return ""; -} - -PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client) -{ - return new GraphicsLayerAndroid(client); -} - -SkLength convertLength(Length len) -{ - SkLength length; - length.type = SkLength::Undefined; - length.value = 0; - if (len.type() == WebCore::Percent) { - length.type = SkLength::Percent; - length.value = len.percent(); - } - if (len.type() == WebCore::Fixed) { - length.type = SkLength::Fixed; - length.value = len.value(); - } - return length; -} - -static RenderLayer* renderLayerFromClient(GraphicsLayerClient* client) -{ - if (client) - return static_cast<RenderLayerBacking*>(client)->owningLayer(); - return 0; -} - -GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) : - GraphicsLayer(client), - m_needsSyncChildren(false), - m_needsSyncMask(false), - m_needsRepaint(false), - m_needsNotifyClient(false), - m_haveContents(false), - m_haveImage(false), - m_newImage(false), - m_imageRef(0), - m_foregroundLayer(0), - m_foregroundClipLayer(0) -{ - RenderLayer* renderLayer = renderLayerFromClient(m_client); - m_contentLayer = new LayerAndroid(renderLayer); - gDebugGraphicsLayerAndroidInstances++; -} - -GraphicsLayerAndroid::~GraphicsLayerAndroid() -{ - m_contentLayer->unref(); - SkSafeUnref(m_foregroundLayer); - SkSafeUnref(m_foregroundClipLayer); - gDebugGraphicsLayerAndroidInstances--; -} - -void GraphicsLayerAndroid::setName(const String& name) -{ - GraphicsLayer::setName(name); -} - -NativeLayer GraphicsLayerAndroid::nativeLayer() const -{ - LOG("(%x) nativeLayer", this); - return 0; -} - -bool GraphicsLayerAndroid::setChildren(const Vector<GraphicsLayer*>& children) -{ - bool childrenChanged = GraphicsLayer::setChildren(children); - if (childrenChanged) { - m_needsSyncChildren = true; - askForSync(); - } - - return childrenChanged; -} - -void GraphicsLayerAndroid::addChild(GraphicsLayer* childLayer) -{ -#ifndef NDEBUG - const String& name = childLayer->name(); - LOG("(%x) addChild: %x (%s)", this, childLayer, name.latin1().data()); -#endif - GraphicsLayer::addChild(childLayer); - m_needsSyncChildren = true; - askForSync(); -} - -void GraphicsLayerAndroid::addChildAtIndex(GraphicsLayer* childLayer, int index) -{ - LOG("(%x) addChild %x AtIndex %d", this, childLayer, index); - GraphicsLayer::addChildAtIndex(childLayer, index); - m_needsSyncChildren = true; - askForSync(); -} - -void GraphicsLayerAndroid::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling) -{ - LOG("(%x) addChild %x Below %x", this, childLayer, sibling); - GraphicsLayer::addChildBelow(childLayer, sibling); - m_needsSyncChildren = true; - askForSync(); -} - -void GraphicsLayerAndroid::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling) -{ - LOG("(%x) addChild %x Above %x", this, childLayer, sibling); - GraphicsLayer::addChildAbove(childLayer, sibling); - m_needsSyncChildren = true; - askForSync(); -} - -bool GraphicsLayerAndroid::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild) -{ - LOG("(%x) replaceChild %x by %x", this, oldChild, newChild); - bool ret = GraphicsLayer::replaceChild(oldChild, newChild); - if (ret) { - m_needsSyncChildren = true; - askForSync(); - } - return ret; -} - -void GraphicsLayerAndroid::removeFromParent() -{ - LOG("(%x) removeFromParent()", this); - GraphicsLayerAndroid* parent = static_cast<GraphicsLayerAndroid*>(m_parent); - GraphicsLayer::removeFromParent(); - // Update the parent's children. - if (parent) { - parent->m_needsSyncChildren = true; - askForSync(); - } -} - -void GraphicsLayerAndroid::updateFixedPosition() -{ - if (!m_client) - return; - - RenderLayer* renderLayer = renderLayerFromClient(m_client); - RenderView* view = static_cast<RenderView*>(renderLayer->renderer()); - - // We will need the Iframe flag in the LayerAndroid tree for fixed position - if (view && view->isRenderIFrame()) - m_contentLayer->setIsIframe(true); - // If we are a fixed position layer, just set it - if (view->isPositioned() && view->style()->position() == FixedPosition) { - // We need to get the passed CSS properties for the element - SkLength left, top, right, bottom; - left = convertLength(view->style()->left()); - top = convertLength(view->style()->top()); - right = convertLength(view->style()->right()); - bottom = convertLength(view->style()->bottom()); - - // We also need to get the margin... - SkLength marginLeft, marginTop, marginRight, marginBottom; - marginLeft = convertLength(view->style()->marginLeft()); - marginTop = convertLength(view->style()->marginTop()); - marginRight = convertLength(view->style()->marginRight()); - marginBottom = convertLength(view->style()->marginBottom()); - - // The layer can be bigger than the element we want to draw; - // not only that, the layout rect of the element might also be - // different from the visible rect of that element (i.e. the element - // has a CSS shadow property -- the shadow is "outside" the element). - // We thus need to: - // 1/ get the size of the element (w,h), using the layoutOverflow rect - // 2/ pass the current offset of the painting relative to the layer - int w = view->rightLayoutOverflow() - view->leftLayoutOverflow(); - int h = view->bottomLayoutOverflow() - view->topLayoutOverflow(); - int paintingOffsetX = - offsetFromRenderer().width(); - int paintingOffsetY = - offsetFromRenderer().height(); - - SkRect viewRect; - viewRect.set(paintingOffsetX, paintingOffsetY, paintingOffsetX + w, paintingOffsetY + h); - IntPoint renderLayerPos(renderLayer->x(), renderLayer->y()); - m_contentLayer->setFixedPosition(left, top, right, bottom, - marginLeft, marginTop, - marginRight, marginBottom, - renderLayerPos, - viewRect); - } -} - -void GraphicsLayerAndroid::setPosition(const FloatPoint& point) -{ - if (point == m_position) - return; - - FloatPoint pos(point); -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - // Add the scroll position back in. When scrolling a layer, all the children - // are positioned based on the content scroll. Adding the scroll position - // back in allows the children to draw based on 0,0. - RenderLayer* layer = renderLayerFromClient(m_client); - if (layer && layer->parent() && layer->parent()->hasOverflowScroll()) - pos += layer->parent()->scrolledContentOffset(); -#endif - - GraphicsLayer::setPosition(pos); - -#ifdef LAYER_DEBUG_2 - LOG("(%x) setPosition(%.2f,%.2f) pos(%.2f, %.2f) anchor(%.2f,%.2f) size(%.2f, %.2f)", - this, point.x(), point.y(), m_position.x(), m_position.y(), - m_anchorPoint.x(), m_anchorPoint.y(), m_size.width(), m_size.height()); -#endif - m_contentLayer->setPosition(pos.x(), pos.y()); - askForSync(); -} - -void GraphicsLayerAndroid::setPreserves3D(bool preserves3D) -{ - if (preserves3D == m_preserves3D) - return; - - GraphicsLayer::setPreserves3D(preserves3D); - m_contentLayer->setPreserves3D(preserves3D); - askForSync(); -} - -void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point) -{ - if (point == m_anchorPoint) - return; - GraphicsLayer::setAnchorPoint(point); - m_contentLayer->setAnchorPoint(point.x(), point.y()); - m_contentLayer->setAnchorPointZ(point.z()); - askForSync(); -} - -void GraphicsLayerAndroid::setSize(const FloatSize& size) -{ - if (size == m_size) - return; - MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height()); - GraphicsLayer::setSize(size); - - // If it is a media layer the size may have changed as a result of the media - // element (e.g. plugin) gaining focus. Therefore, we must sync the size of - // the focus' outline so that our UI thread can draw accordingly. - if (m_contentLayer->isMedia() && m_client) { - RenderLayer* layer = renderLayerFromClient(m_client); - RenderBox* box = layer->renderBox(); - int outline = box->view()->maximalOutlineSize(); - static_cast<MediaLayer*>(m_contentLayer)->setOutlineSize(outline); - LOG("Media Outline: %d %p %p %p", outline, m_client, layer, box); - LOG("Media Size: %g,%g", size.width(), size.height()); - } - - m_contentLayer->setSize(size.width(), size.height()); - askForSync(); -} - -void GraphicsLayerAndroid::setBackfaceVisibility(bool b) -{ - GraphicsLayer::setBackfaceVisibility(b); - m_contentLayer->setBackfaceVisibility(b); - askForSync(); -} - -void GraphicsLayerAndroid::setTransform(const TransformationMatrix& t) -{ - if (t == m_transform) - return; - - GraphicsLayer::setTransform(t); - m_contentLayer->setTransform(t); - askForSync(); -} - -void GraphicsLayerAndroid::setChildrenTransform(const TransformationMatrix& t) -{ - if (t == m_childrenTransform) - return; - LOG("(%x) setChildrenTransform", this); - - GraphicsLayer::setChildrenTransform(t); - m_contentLayer->setChildrenTransform(t); - for (unsigned int i = 0; i < m_children.size(); i++) { - GraphicsLayer* layer = m_children[i]; - layer->setTransform(t); - if (layer->children().size()) - layer->setChildrenTransform(t); - } - askForSync(); -} - -void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer) -{ - if (layer == m_maskLayer) - return; - - GraphicsLayer::setMaskLayer(layer); - m_needsSyncMask = true; - askForSync(); -} - -void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds) -{ - if (masksToBounds == m_masksToBounds) - return; - GraphicsLayer::setMasksToBounds(masksToBounds); - m_needsSyncMask = true; - askForSync(); -} - -void GraphicsLayerAndroid::setDrawsContent(bool drawsContent) -{ - if (drawsContent == m_drawsContent) - return; - GraphicsLayer::setDrawsContent(drawsContent); - if (m_drawsContent) { - m_haveContents = true; - setNeedsDisplay(); - } - askForSync(); -} - -void GraphicsLayerAndroid::setBackgroundColor(const Color& color) -{ - if (color == m_backgroundColor) - return; - LOG("(%x) setBackgroundColor", this); - GraphicsLayer::setBackgroundColor(color); - SkColor c = SkColorSetARGB(color.alpha(), color.red(), color.green(), color.blue()); - m_contentLayer->setBackgroundColor(c); - m_haveContents = true; - askForSync(); -} - -void GraphicsLayerAndroid::clearBackgroundColor() -{ - LOG("(%x) clearBackgroundColor", this); - GraphicsLayer::clearBackgroundColor(); - askForSync(); -} - -void GraphicsLayerAndroid::setContentsOpaque(bool opaque) -{ - if (opaque == m_contentsOpaque) - return; - LOG("(%x) setContentsOpaque (%d)", this, opaque); - GraphicsLayer::setContentsOpaque(opaque); - m_haveContents = true; - askForSync(); -} - -void GraphicsLayerAndroid::setOpacity(float opacity) -{ - LOG("(%x) setOpacity: %.2f", this, opacity); - float clampedOpacity = max(0.0f, min(opacity, 1.0f)); - - if (clampedOpacity == m_opacity) - return; - - MLOG("(%x) setFinalOpacity: %.2f=>%.2f (%.2f)", this, - opacity, clampedOpacity, m_opacity); - GraphicsLayer::setOpacity(clampedOpacity); - m_contentLayer->setOpacity(clampedOpacity); - askForSync(); -} - -void GraphicsLayerAndroid::setNeedsDisplay() -{ - LOG("(%x) setNeedsDisplay()", this); - FloatRect rect(0, 0, m_size.width(), m_size.height()); - setNeedsDisplayInRect(rect); -} - -// Helper to set and clear the painting phase as well as auto restore the -// original phase. -class PaintingPhase { -public: - PaintingPhase(GraphicsLayer* layer) - : m_layer(layer) - , m_originalPhase(layer->paintingPhase()) {} - - ~PaintingPhase() - { - m_layer->setPaintingPhase(m_originalPhase); - } - - void set(GraphicsLayerPaintingPhase phase) - { - m_layer->setPaintingPhase(phase); - } - - void clear(GraphicsLayerPaintingPhase phase) - { - m_layer->setPaintingPhase( - (GraphicsLayerPaintingPhase) (m_originalPhase & ~phase)); - } -private: - GraphicsLayer* m_layer; - GraphicsLayerPaintingPhase m_originalPhase; -}; - -void GraphicsLayerAndroid::updateScrollingLayers() -{ -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - RenderLayer* layer = renderLayerFromClient(m_client); - if (!layer || !m_haveContents) - return; - bool hasOverflowScroll = m_foregroundLayer || m_contentLayer->contentIsScrollable(); - bool layerNeedsOverflow = layer->hasOverflowScroll(); - bool iframeNeedsOverflow = layer->isRootLayer() && - layer->renderer()->frame()->ownerRenderer() && - layer->renderer()->frame()->view()->hasOverflowScroll(); - - if (hasOverflowScroll && (layerNeedsOverflow || iframeNeedsOverflow)) { - // Already has overflow layers. - return; - } - if (!hasOverflowScroll && !layerNeedsOverflow && !iframeNeedsOverflow) { - // Does not need overflow layers. - return; - } - if (layerNeedsOverflow || iframeNeedsOverflow) { - ASSERT(!hasOverflowScroll); - if (layerNeedsOverflow) { - ASSERT(!m_foregroundLayer && !m_foregroundClipLayer); - m_foregroundLayer = new ScrollableLayerAndroid(layer); - m_foregroundClipLayer = new LayerAndroid(layer); - m_foregroundClipLayer->setMasksToBounds(true); - m_foregroundClipLayer->addChild(m_foregroundLayer); - m_contentLayer->addChild(m_foregroundClipLayer); - } else { - ASSERT(iframeNeedsOverflow && !m_contentLayer->contentIsScrollable()); - // No need to copy the children as they will be removed and synced. - m_contentLayer->removeChildren(); - // Replace the content layer with a scrollable layer. - LayerAndroid* layer = new ScrollableLayerAndroid(*m_contentLayer); - m_contentLayer->unref(); - m_contentLayer = layer; - if (m_parent) { - // The content layer has changed so the parent needs to sync - // children. - static_cast<GraphicsLayerAndroid*>(m_parent)->m_needsSyncChildren = true; - } - } - // Need to rebuild our children based on the new structure. - m_needsSyncChildren = true; - } else { - ASSERT(hasOverflowScroll && !layerNeedsOverflow && !iframeNeedsOverflow); - ASSERT(m_contentLayer); - // Remove the foreground layers. - if (m_foregroundLayer) { - m_foregroundLayer->unref(); - m_foregroundLayer = 0; - m_foregroundClipLayer->unref(); - m_foregroundClipLayer = 0; - } - // No need to copy over children. - m_contentLayer->removeChildren(); - LayerAndroid* layer = new LayerAndroid(*m_contentLayer); - m_contentLayer->unref(); - m_contentLayer = layer; - if (m_parent) { - // The content layer has changed so the parent needs to sync - // children. - static_cast<GraphicsLayerAndroid*>(m_parent)->m_needsSyncChildren = true; - } - // Children are all re-parented. - m_needsSyncChildren = true; - } -#endif -} - -bool GraphicsLayerAndroid::repaint() -{ - LOG("(%x) repaint(), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ", - this, gPaused, m_needsRepaint, m_haveContents); - - if (!gPaused && m_haveContents && m_needsRepaint && !m_haveImage) { - // with SkPicture, we request the entire layer's content. - IntRect layerBounds(0, 0, m_size.width(), m_size.height()); - - RenderLayer* layer = renderLayerFromClient(m_client); - if (m_foregroundLayer) { - PaintingPhase phase(this); - // Paint the background into a separate context. - phase.set(GraphicsLayerPaintBackground); - if (!paintContext(m_contentLayer->recordContext(), layerBounds)) - return false; - - // Construct the foreground layer and draw. - RenderBox* box = layer->renderBox(); - int outline = box->view()->maximalOutlineSize(); - IntRect contentsRect(0, 0, - box->borderLeft() + box->borderRight() + layer->scrollWidth(), - box->borderTop() + box->borderBottom() + layer->scrollHeight()); - contentsRect.inflate(outline); - // Update the foreground layer size. - m_foregroundLayer->setSize(contentsRect.width(), contentsRect.height()); - // Paint everything else into the main recording canvas. - phase.clear(GraphicsLayerPaintBackground); - - // Paint at 0,0. - IntSize scroll = layer->scrolledContentOffset(); - layer->scrollToOffset(0, 0, true, false); - // At this point, it doesn't matter if painting failed. - (void) paintContext(m_foregroundLayer->recordContext(), contentsRect); - layer->scrollToOffset(scroll.width(), scroll.height(), true, false); - - // Construct the clip layer for masking the contents. - IntRect clip = layer->renderer()->absoluteBoundingBoxRect(); - // absoluteBoundingBoxRect does not include the outline so we need - // to offset the position. - int x = box->borderLeft() + outline; - int y = box->borderTop() + outline; - int width = clip.width() - box->borderLeft() - box->borderRight(); - int height = clip.height() - box->borderTop() - box->borderBottom(); - m_foregroundClipLayer->setPosition(x, y); - m_foregroundClipLayer->setSize(width, height); - - // Need to offset the foreground layer by the clip layer in order - // for the contents to be in the correct position. - m_foregroundLayer->setPosition(-x, -y); - // Set the scrollable bounds of the layer. - m_foregroundLayer->setScrollLimits(-x, -y, m_size.width(), m_size.height()); - m_foregroundLayer->needsRepaint(); - } else { - // If there is no contents clip, we can draw everything into one - // picture. - if (!paintContext(m_contentLayer->recordContext(), layerBounds)) - return false; - // Check for a scrollable iframe and report the scrolling - // limits based on the view size. - if (m_contentLayer->contentIsScrollable()) { - FrameView* view = layer->renderer()->frame()->view(); - static_cast<ScrollableLayerAndroid*>(m_contentLayer)->setScrollLimits( - m_position.x(), m_position.y(), view->layoutWidth(), view->layoutHeight()); - } - } - - LOG("(%x) repaint() on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!", - this, m_size.width(), m_size.height(), - m_contentLayer->getPosition().fX, - m_contentLayer->getPosition().fY, - m_contentLayer->getSize().width(), - m_contentLayer->getSize().height()); - - m_contentLayer->needsRepaint(); - m_needsRepaint = false; - m_invalidatedRects.clear(); - - return true; - } - if (m_needsRepaint && m_haveImage && m_newImage) { - // We need to tell the GL thread that we will need to repaint the - // texture. Only do so if we effectively have a new image! - m_contentLayer->needsRepaint(); - m_newImage = false; - m_needsRepaint = false; - return true; - } - return false; -} - -bool GraphicsLayerAndroid::paintContext(SkPicture* context, - const IntRect& rect) -{ - SkAutoPictureRecord arp(context, rect.width(), rect.height()); - SkCanvas* canvas = arp.getRecordingCanvas(); - - if (!canvas) - return false; - - PlatformGraphicsContext platformContext(canvas, 0); - GraphicsContext graphicsContext(&platformContext); - - paintGraphicsLayerContents(graphicsContext, rect); - return true; -} - -void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect) -{ - for (unsigned int i = 0; i < m_children.size(); i++) { - GraphicsLayer* layer = m_children[i]; - if (layer) { - FloatRect childrenRect = m_transform.mapRect(rect); - layer->setNeedsDisplayInRect(childrenRect); - } - } - - if (!m_haveImage && !drawsContent()) { - LOG("(%x) setNeedsDisplay(%.2f,%.2f,%.2f,%.2f) doesn't have content, bypass...", - this, rect.x(), rect.y(), rect.width(), rect.height()); - return; - } - - bool addInval = true; - const size_t maxDirtyRects = 8; - for (size_t i = 0; i < m_invalidatedRects.size(); ++i) { - if (m_invalidatedRects[i].contains(rect)) { - addInval = false; - break; - } - } - -#ifdef LAYER_DEBUG - LOG("(%x) layer %d setNeedsDisplayInRect(%d) - (%.2f, %.2f, %.2f, %.2f)", this, - m_contentLayer->uniqueId(), m_needsRepaint, rect.x(), rect.y(), rect.width(), rect.height()); -#endif - - if (addInval) { - if (m_invalidatedRects.size() < maxDirtyRects) - m_invalidatedRects.append(rect); - else - m_invalidatedRects[0].unite(rect); - } - - m_needsRepaint = true; - askForSync(); -} - -void GraphicsLayerAndroid::pauseDisplay(bool state) -{ - gPaused = state; - if (gPaused) - gPausedDelay = WTF::currentTime() + 1; -} - -bool GraphicsLayerAndroid::addAnimation(const KeyframeValueList& valueList, - const IntSize& boxSize, - const Animation* anim, - const String& keyframesName, - double beginTime) -{ - if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2) - return false; - - bool createdAnimations = false; - if (valueList.property() == AnimatedPropertyWebkitTransform) { - createdAnimations = createTransformAnimationsFromKeyframes(valueList, - anim, - keyframesName, - beginTime, - boxSize); - } else { - createdAnimations = createAnimationFromKeyframes(valueList, - anim, - keyframesName, - beginTime); - } - if (createdAnimations) - askForSync(); - return createdAnimations; -} - -bool GraphicsLayerAndroid::createAnimationFromKeyframes(const KeyframeValueList& valueList, - const Animation* animation, const String& keyframesName, double beginTime) -{ - bool isKeyframe = valueList.size() > 2; - TLOG("createAnimationFromKeyframes(%d), name(%s) beginTime(%.2f)", - isKeyframe, keyframesName.latin1().data(), beginTime); - - switch (valueList.property()) { - case AnimatedPropertyInvalid: break; - case AnimatedPropertyWebkitTransform: break; - case AnimatedPropertyBackgroundColor: break; - case AnimatedPropertyOpacity: { - MLOG("ANIMATEDPROPERTYOPACITY"); - - KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyOpacity); - for (unsigned int i = 0; i < valueList.size(); i++) { - FloatAnimationValue* originalValue = (FloatAnimationValue*)valueList.at(i); - PassRefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction())); - FloatAnimationValue* value = new FloatAnimationValue(originalValue->keyTime(), - originalValue->value(), - timingFunction); - operationsList->insert(value); - } - - RefPtr<AndroidOpacityAnimation> anim = AndroidOpacityAnimation::create(animation, - operationsList, - beginTime); - if (keyframesName.isEmpty()) - anim->setName(propertyIdToString(valueList.property())); - else - anim->setName(keyframesName); - - m_contentLayer->addAnimation(anim.release()); - needsNotifyClient(); - return true; - } break; - } - return false; -} - -void GraphicsLayerAndroid::needsNotifyClient() -{ - m_needsNotifyClient = true; - askForSync(); -} - -bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, - const Animation* animation, - const String& keyframesName, - double beginTime, - const IntSize& boxSize) -{ - ASSERT(valueList.property() == AnimatedPropertyWebkitTransform); - TLOG("createTransformAnimationFromKeyframes, name(%s) beginTime(%.2f)", - keyframesName.latin1().data(), beginTime); - - KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyWebkitTransform); - for (unsigned int i = 0; i < valueList.size(); i++) { - TransformAnimationValue* originalValue = (TransformAnimationValue*)valueList.at(i); - PassRefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction())); - TransformAnimationValue* value = new TransformAnimationValue(originalValue->keyTime(), - originalValue->value(), - timingFunction); - operationsList->insert(value); - } - - RefPtr<AndroidTransformAnimation> anim = AndroidTransformAnimation::create(animation, - operationsList, - beginTime); - - if (keyframesName.isEmpty()) - anim->setName(propertyIdToString(valueList.property())); - else - anim->setName(keyframesName); - - - m_contentLayer->addAnimation(anim.release()); - - needsNotifyClient(); - return true; -} - -void GraphicsLayerAndroid::removeAnimationsForProperty(AnimatedPropertyID anID) -{ - TLOG("NRO removeAnimationsForProperty(%d)", anID); - m_contentLayer->removeAnimationsForProperty(anID); - askForSync(); -} - -void GraphicsLayerAndroid::removeAnimationsForKeyframes(const String& keyframesName) -{ - TLOG("NRO removeAnimationsForKeyframes(%s)", keyframesName.latin1().data()); - m_contentLayer->removeAnimationsForKeyframes(keyframesName); - askForSync(); -} - -void GraphicsLayerAndroid::pauseAnimation(const String& keyframesName) -{ - TLOG("NRO pauseAnimation(%s)", keyframesName.latin1().data()); -} - -void GraphicsLayerAndroid::suspendAnimations(double time) -{ - TLOG("NRO suspendAnimations(%.2f)", time); -} - -void GraphicsLayerAndroid::resumeAnimations() -{ - TLOG("NRO resumeAnimations()"); -} - -void GraphicsLayerAndroid::setContentsToImage(Image* image) -{ - TLOG("(%x) setContentsToImage", this, image); - if (image) { - m_haveContents = true; - m_haveImage = true; - // Only pass the new image if it's a different one - if (image->nativeImageForCurrentFrame() != m_imageRef) { - m_newImage = true; - m_contentLayer->setContentsImage(image->nativeImageForCurrentFrame()); - // remember the passed image. - m_imageRef = image->nativeImageForCurrentFrame(); - setNeedsDisplay(); - askForSync(); - } - } -} - -void GraphicsLayerAndroid::setContentsToMedia(PlatformLayer* mediaLayer) -{ - // Only fullscreen video on Android, so media doesn't get it's own layer. - // We might still have other layers though. - if (m_contentLayer != mediaLayer && mediaLayer) { - - // TODO add a copy method to LayerAndroid to sync everything - // copy data from the original content layer to the new one - mediaLayer->setPosition(m_contentLayer->getPosition().fX, - m_contentLayer->getPosition().fY); - mediaLayer->setSize(m_contentLayer->getWidth(), m_contentLayer->getHeight()); - mediaLayer->setDrawTransform(m_contentLayer->drawTransform()); - - mediaLayer->ref(); - m_contentLayer->unref(); - m_contentLayer = mediaLayer; - - // If the parent exists then notify it to re-sync it's children - if (m_parent) { - GraphicsLayerAndroid* parent = static_cast<GraphicsLayerAndroid*>(m_parent); - parent->m_needsSyncChildren = true; - } - m_needsSyncChildren = true; - - setNeedsDisplay(); - askForSync(); - } -} - -PlatformLayer* GraphicsLayerAndroid::platformLayer() const -{ - LOG("platformLayer"); - return m_contentLayer; -} - -#ifndef NDEBUG -void GraphicsLayerAndroid::setDebugBackgroundColor(const Color& color) -{ -} - -void GraphicsLayerAndroid::setDebugBorder(const Color& color, float borderWidth) -{ -} -#endif - -void GraphicsLayerAndroid::setZPosition(float position) -{ - if (position == m_zPosition) - return; - LOG("(%x) setZPosition: %.2f", this, position); - GraphicsLayer::setZPosition(position); - askForSync(); -} - -void GraphicsLayerAndroid::askForSync() -{ - if (!m_client) - return; - - if (m_client) - m_client->notifySyncRequired(this); -} - -void GraphicsLayerAndroid::syncChildren() -{ - if (m_needsSyncChildren) { - m_contentLayer->removeChildren(); - LayerAndroid* layer = m_contentLayer; - if (m_foregroundClipLayer) { - m_contentLayer->addChild(m_foregroundClipLayer); - // Use the scrollable content layer as the parent of the children so - // that they move with the content. - layer = m_foregroundLayer; - layer->removeChildren(); - } - for (unsigned int i = 0; i < m_children.size(); i++) - layer->addChild(m_children[i]->platformLayer()); - m_needsSyncChildren = false; - } -} - -void GraphicsLayerAndroid::syncMask() -{ - if (m_needsSyncMask) { - if (m_maskLayer) { - LayerAndroid* mask = m_maskLayer->platformLayer(); - m_contentLayer->setMaskLayer(mask); - } else - m_contentLayer->setMaskLayer(0); - - m_contentLayer->setMasksToBounds(m_masksToBounds); - m_needsSyncMask = false; - } -} - -void GraphicsLayerAndroid::syncCompositingState() -{ - for (unsigned int i = 0; i < m_children.size(); i++) - m_children[i]->syncCompositingState(); - - updateScrollingLayers(); - updateFixedPosition(); - syncChildren(); - syncMask(); - - if (!gPaused || WTF::currentTime() >= gPausedDelay) - repaint(); -} - -void GraphicsLayerAndroid::notifyClientAnimationStarted() -{ - for (unsigned int i = 0; i < m_children.size(); i++) - static_cast<GraphicsLayerAndroid*>(m_children[i])->notifyClientAnimationStarted(); - - if (m_needsNotifyClient) { - if (client()) - client()->notifyAnimationStarted(this, WTF::currentTime()); - m_needsNotifyClient = false; - } -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h deleted file mode 100644 index 10db5a1..0000000 --- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef GraphicsLayerAndroid_h -#define GraphicsLayerAndroid_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "FloatRect.h" -#include "Frame.h" -#include "GraphicsLayer.h" -#include "GraphicsLayerClient.h" -#include "LayerAndroid.h" -#include "RefPtr.h" -#include "SkBitmapRef.h" -#include "Vector.h" - -class FloatPoint3D; -class Image; -class SkBitmapRef; - -namespace WebCore { - -class ScrollableLayerAndroid; - -class GraphicsLayerAndroid : public GraphicsLayer { -public: - - GraphicsLayerAndroid(GraphicsLayerClient*); - virtual ~GraphicsLayerAndroid(); - - virtual void setName(const String&); - - // for hosting this GraphicsLayer in a native layer hierarchy - virtual NativeLayer nativeLayer() const; - - virtual bool setChildren(const Vector<GraphicsLayer*>&); - virtual void addChild(GraphicsLayer*); - virtual void addChildAtIndex(GraphicsLayer*, int index); - virtual void addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling); - virtual void addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling); - virtual bool replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild); - - virtual void removeFromParent(); - - virtual void setPosition(const FloatPoint&); - virtual void setPreserves3D(bool b); - virtual void setAnchorPoint(const FloatPoint3D&); - virtual void setSize(const FloatSize&); - - virtual void setBackfaceVisibility(bool b); - virtual void setTransform(const TransformationMatrix&); - - virtual void setChildrenTransform(const TransformationMatrix&); - - virtual void setMaskLayer(GraphicsLayer*); - virtual void setMasksToBounds(bool); - virtual void setDrawsContent(bool); - - virtual void setBackgroundColor(const Color&); - virtual void clearBackgroundColor(); - - virtual void setContentsOpaque(bool); - - virtual void setOpacity(float); - - virtual void setNeedsDisplay(); - virtual void setNeedsDisplayInRect(const FloatRect&); - - virtual bool addAnimation(const KeyframeValueList& valueList, - const IntSize& boxSize, - const Animation* anim, - const String& keyframesName, - double beginTime); - bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, - const Animation*, - const String& keyframesName, - double beginTime, - const IntSize& boxSize); - bool createAnimationFromKeyframes(const KeyframeValueList&, - const Animation*, - const String& keyframesName, - double beginTime); - - virtual void removeAnimationsForProperty(AnimatedPropertyID); - virtual void removeAnimationsForKeyframes(const String& keyframesName); - virtual void pauseAnimation(const String& keyframesName); - - virtual void suspendAnimations(double time); - virtual void resumeAnimations(); - - virtual void setContentsToImage(Image*); - virtual void setContentsToMedia(PlatformLayer*); - virtual PlatformLayer* platformLayer() const; - - void pauseDisplay(bool state); - -#ifndef NDEBUG - virtual void setDebugBackgroundColor(const Color&); - virtual void setDebugBorder(const Color&, float borderWidth); -#endif - - virtual void setZPosition(float); - - virtual void syncCompositingState(); - void notifyClientAnimationStarted(); - - LayerAndroid* contentLayer() { return m_contentLayer; } - - static int instancesCount(); - -private: - - void askForSync(); - void syncPositionState(); - void syncChildren(); - void syncMask(); - - void updateFixedPosition(); - void updateScrollingLayers(); - - // with SkPicture, we always repaint the entire layer's content. - bool repaint(); - void needsNotifyClient(); - - bool paintContext(SkPicture* context, const IntRect& rect); - - bool m_needsSyncChildren; - bool m_needsSyncMask; - bool m_needsRepaint; - bool m_needsNotifyClient; - - bool m_haveContents; - bool m_haveImage; - bool m_newImage; - SkBitmapRef* m_imageRef; // only used to remember previously passed images - - Vector<FloatRect> m_invalidatedRects; - - LayerAndroid* m_contentLayer; - ScrollableLayerAndroid* m_foregroundLayer; - LayerAndroid* m_foregroundClipLayer; -}; - -} // namespace WebCore - - -#endif // USE(ACCELERATED_COMPOSITING) - -#endif // GraphicsLayerAndroid_h diff --git a/WebCore/platform/graphics/android/HarfbuzzSkia.cpp b/WebCore/platform/graphics/android/HarfbuzzSkia.cpp deleted file mode 100644 index 81841f2..0000000 --- a/WebCore/platform/graphics/android/HarfbuzzSkia.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * Copyright 2010, 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "FontPlatformData.h" -#include "wtf/OwnArrayPtr.h" - -#include "SkFontHost.h" -#include "SkPaint.h" -#include "SkPath.h" -#include "SkPoint.h" -#include "SkRect.h" - -extern "C" { -#include "harfbuzz-shaper.h" -} - -// This file implements the callbacks which Harfbuzz requires by using Skia -// calls. See the Harfbuzz source for references about what these callbacks do. - -namespace WebCore { - -static HB_Fixed SkiaScalarToHarfbuzzFixed(SkScalar value) -{ - // HB_Fixed is a 26.6 fixed point format. - return value * 64; -} - -static HB_Bool stringToGlyphs(HB_Font hbFont, const HB_UChar16* characters, hb_uint32 length, HB_Glyph* glyphs, hb_uint32* glyphsSize, HB_Bool isRTL) -{ - FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); - SkPaint paint; - - font->setupPaint(&paint); - paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - int numGlyphs = paint.textToGlyphs(characters, length * sizeof(uint16_t), reinterpret_cast<uint16_t*>(glyphs)); - - // HB_Glyph is 32-bit, but Skia outputs only 16-bit numbers. So our - // |glyphs| array needs to be converted. - for (int i = numGlyphs - 1; i >= 0; --i) { - uint16_t value; - // We use a memcpy to avoid breaking strict aliasing rules. - memcpy(&value, reinterpret_cast<char*>(glyphs) + sizeof(uint16_t) * i, sizeof(value)); - glyphs[i] = value; - } - - *glyphsSize = numGlyphs; - return 1; -} - -static void glyphsToAdvances(HB_Font hbFont, const HB_Glyph* glyphs, hb_uint32 numGlyphs, HB_Fixed* advances, int flags) -{ - FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); - SkPaint paint; - - font->setupPaint(&paint); - paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); - - OwnArrayPtr<uint16_t> glyphs16(new uint16_t[numGlyphs]); - if (!glyphs16.get()) - return; - for (unsigned i = 0; i < numGlyphs; ++i) - glyphs16[i] = glyphs[i]; - paint.getTextWidths(glyphs16.get(), numGlyphs * sizeof(uint16_t), reinterpret_cast<SkScalar*>(advances)); - - // The |advances| values which Skia outputs are SkScalars, which are floats - // in Chromium. However, Harfbuzz wants them in 26.6 fixed point format. - // These two formats are both 32-bits long. - for (unsigned i = 0; i < numGlyphs; ++i) { - float value; - // We use a memcpy to avoid breaking strict aliasing rules. - memcpy(&value, reinterpret_cast<char*>(advances) + sizeof(float) * i, sizeof(value)); - advances[i] = SkiaScalarToHarfbuzzFixed(value); - } -} - -static HB_Bool canRender(HB_Font hbFont, const HB_UChar16* characters, hb_uint32 length) -{ - FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); - SkPaint paint; - - font->setupPaint(&paint); - paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - - OwnArrayPtr<uint16_t> glyphs16(new uint16_t[length]); - glyphs16.get(); - int numGlyphs = paint.textToGlyphs(characters, length * sizeof(uint16_t), glyphs16.get()); - - for (int i = 0; i < numGlyphs; ++i) { - if (!glyphs16[i]) - return false; - } - - return true; -} - -static HB_Error getOutlinePoint(HB_Font hbFont, HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed* xPos, HB_Fixed* yPos, hb_uint32* resultingNumPoints) -{ - FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); - SkPaint paint; - - if (flags & HB_ShaperFlag_UseDesignMetrics) - return HB_Err_Invalid_Argument; // This is requesting pre-hinted positions. We can't support this. - - font->setupPaint(&paint); - paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); - uint16_t glyph16 = glyph; - SkPath path; - paint.getTextPath(&glyph16, sizeof(glyph16), 0, 0, &path); - uint32_t numPoints = path.getPoints(0, 0); - if (point >= numPoints) - return HB_Err_Invalid_SubTable; - SkPoint* points = reinterpret_cast<SkPoint*>(fastMalloc(sizeof(SkPoint) * (point + 1))); - if (!points) - return HB_Err_Invalid_SubTable; - // Skia does let us get a single point from the path. - path.getPoints(points, point + 1); - *xPos = SkiaScalarToHarfbuzzFixed(points[point].fX); - *yPos = SkiaScalarToHarfbuzzFixed(points[point].fY); - *resultingNumPoints = numPoints; - fastFree(points); - - return HB_Err_Ok; -} - -static void getGlyphMetrics(HB_Font hbFont, HB_Glyph glyph, HB_GlyphMetrics* metrics) -{ - FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); - SkPaint paint; - - font->setupPaint(&paint); - paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); - uint16_t glyph16 = glyph; - SkScalar width; - SkRect bounds; - paint.getTextWidths(&glyph16, sizeof(glyph16), &width, &bounds); - - metrics->x = SkiaScalarToHarfbuzzFixed(bounds.fLeft); - metrics->y = SkiaScalarToHarfbuzzFixed(bounds.fTop); - metrics->width = SkiaScalarToHarfbuzzFixed(bounds.width()); - metrics->height = SkiaScalarToHarfbuzzFixed(bounds.height()); - - metrics->xOffset = SkiaScalarToHarfbuzzFixed(width); - // We can't actually get the |y| correct because Skia doesn't export - // the vertical advance. However, nor we do ever render vertical text at - // the moment so it's unimportant. - metrics->yOffset = 0; -} - -static HB_Fixed getFontMetric(HB_Font hbFont, HB_FontMetric metric) -{ - FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); - SkPaint paint; - - font->setupPaint(&paint); - SkPaint::FontMetrics skiaMetrics; - paint.getFontMetrics(&skiaMetrics); - - switch (metric) { - case HB_FontAscent: - return SkiaScalarToHarfbuzzFixed(-skiaMetrics.fAscent); - // We don't support getting the rest of the metrics and Harfbuzz doesn't seem to need them. - default: - return 0; - } -} - -HB_FontClass harfbuzzSkiaClass = { - stringToGlyphs, - glyphsToAdvances, - canRender, - getOutlinePoint, - getGlyphMetrics, - getFontMetric, -}; - -HB_Error harfbuzzSkiaGetTable(void* voidface, const HB_Tag tag, HB_Byte* buffer, HB_UInt* len) -{ - FontPlatformData* font = reinterpret_cast<FontPlatformData*>(voidface); - - const size_t tableSize = SkFontHost::GetTableSize(font->uniqueID(), tag); - if (!tableSize) - return HB_Err_Invalid_Argument; - // If Harfbuzz specified a NULL buffer then it's asking for the size of the table. - if (!buffer) { - *len = tableSize; - return HB_Err_Ok; - } - - if (*len < tableSize) - return HB_Err_Invalid_Argument; - SkFontHost::GetTableData(font->uniqueID(), tag, 0, tableSize, buffer); - return HB_Err_Ok; -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/android/HarfbuzzSkia.h b/WebCore/platform/graphics/android/HarfbuzzSkia.h deleted file mode 100644 index d26bbe2..0000000 --- a/WebCore/platform/graphics/android/HarfbuzzSkia.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * Copyright 2010, 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 HarfbuzzSkia_h -#define HarfbuzzSkia_h - -extern "C" { -#include "harfbuzz-shaper.h" -#include "harfbuzz-unicode.h" -} - -namespace WebCore { - HB_Error harfbuzzSkiaGetTable(void* voidface, const HB_Tag, HB_Byte* buffer, HB_UInt* len); - extern const HB_FontClass harfbuzzSkiaClass; -} // namespace WebCore - -#endif diff --git a/WebCore/platform/graphics/android/ImageAndroid.cpp b/WebCore/platform/graphics/android/ImageAndroid.cpp deleted file mode 100644 index 01fe272..0000000 --- a/WebCore/platform/graphics/android/ImageAndroid.cpp +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * Copyright (C) 2004, 2005, 2006 Apple Computer, 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "TransformationMatrix.h" -#include "BitmapImage.h" -#include "Image.h" -#include "FloatRect.h" -#include "GraphicsContext.h" -#include "PlatformGraphicsContext.h" -#include "PlatformString.h" -#include "SharedBuffer.h" - -#include "android_graphics.h" -#include "SkBitmapRef.h" -#include "SkCanvas.h" -#include "SkColorPriv.h" -#include "SkImageDecoder.h" -#include "SkShader.h" -#include "SkString.h" -#include "SkTemplates.h" -#include "SkiaUtils.h" - -#include <utils/AssetManager.h> - -//#define TRACE_SUBSAMPLED_BITMAPS -//#define TRACE_SKIPPED_BITMAPS - -android::AssetManager* globalAssetManager() { - static android::AssetManager* gGlobalAssetMgr; - if (!gGlobalAssetMgr) { - gGlobalAssetMgr = new android::AssetManager(); - gGlobalAssetMgr->addDefaultAssets(); - } - return gGlobalAssetMgr; -} - -namespace WebCore { - -bool FrameData::clear(bool clearMetadata) -{ - if (clearMetadata) - m_haveMetadata = false; - - if (m_frame) { - m_frame->unref(); - m_frame = 0; - return true; - } - return false; -} - -BitmapImage::BitmapImage(SkBitmapRef* ref, ImageObserver* observer) - : Image(observer) - , m_currentFrame(0) - , m_frames(0) - , m_frameTimer(0) - , m_repetitionCount(0) - , m_repetitionCountStatus(Unknown) - , m_repetitionsComplete(0) - , m_isSolidColor(false) - , m_animationFinished(true) - , m_allDataReceived(true) - , m_haveSize(true) - , m_sizeAvailable(true) - , m_decodedSize(0) - , m_haveFrameCount(true) - , m_frameCount(1) -{ - initPlatformData(); - - m_size = IntSize(ref->bitmap().width(), ref->bitmap().height()); - - m_frames.grow(1); - m_frames[0].m_frame = ref; - m_frames[0].m_hasAlpha = !ref->bitmap().isOpaque(); - checkForSolidColor(); - ref->ref(); -} - - -void BitmapImage::initPlatformData() -{ - m_source.clearURL(); -} - -void BitmapImage::invalidatePlatformData() -{ -} - -void BitmapImage::checkForSolidColor() -{ - m_checkedForSolidColor = true; - m_isSolidColor = false; - if (frameCount() == 1) { - SkBitmapRef* ref = frameAtIndex(0); - if (!ref) { - return; // keep solid == false - } - - const SkBitmap& bm = ref->bitmap(); - if (bm.width() != 1 || bm.height() != 1) { - return; // keep solid == false - } - - SkAutoLockPixels alp(bm); - if (!bm.readyToDraw()) { - return; // keep solid == false - } - - SkPMColor color; - switch (bm.getConfig()) { - case SkBitmap::kARGB_8888_Config: - color = *bm.getAddr32(0, 0); - break; - case SkBitmap::kRGB_565_Config: - color = SkPixel16ToPixel32(*bm.getAddr16(0, 0)); - break; - case SkBitmap::kIndex8_Config: { - SkColorTable* ctable = bm.getColorTable(); - if (!ctable) { - return; - } - color = (*ctable)[*bm.getAddr8(0, 0)]; - break; - } - default: - return; // keep solid == false - } - m_isSolidColor = true; - m_solidColor = SkPMColorToWebCoreColor(color); - } -} - -static void round(SkIRect* dst, const WebCore::FloatRect& src) -{ - dst->set(SkScalarRound(SkFloatToScalar(src.x())), - SkScalarRound(SkFloatToScalar(src.y())), - SkScalarRound(SkFloatToScalar((src.x() + src.width()))), - SkScalarRound(SkFloatToScalar((src.y() + src.height())))); -} - -static void round_scaled(SkIRect* dst, const WebCore::FloatRect& src, - float sx, float sy) -{ - dst->set(SkScalarRound(SkFloatToScalar(src.x() * sx)), - SkScalarRound(SkFloatToScalar(src.y() * sy)), - SkScalarRound(SkFloatToScalar((src.x() + src.width()) * sx)), - SkScalarRound(SkFloatToScalar((src.y() + src.height()) * sy))); -} - -static inline void fixPaintForBitmapsThatMaySeam(SkPaint* paint) { - /* Bitmaps may be drawn to seem next to other images. If we are drawn - zoomed, or at fractional coordinates, we may see cracks/edges if - we antialias, because that will cause us to draw the same pixels - more than once (e.g. from the left and right bitmaps that share - an edge). - - Disabling antialiasing fixes this, and since so far we are never - rotated at non-multiple-of-90 angles, this seems to do no harm - */ - paint->setAntiAlias(false); -} - -void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, - const FloatRect& srcRect, ColorSpace, - CompositeOperator compositeOp) -{ - startAnimation(); - - SkBitmapRef* image = this->nativeImageForCurrentFrame(); - if (!image) { // If it's too early we won't have an image yet. - return; - } - - // in case we get called with an incomplete bitmap - const SkBitmap& bitmap = image->bitmap(); - if (bitmap.getPixels() == NULL && bitmap.pixelRef() == NULL) { -#ifdef TRACE_SKIPPED_BITMAPS - SkDebugf("----- skip bitmapimage: [%d %d] pixels %p pixelref %p\n", - bitmap.width(), bitmap.height(), - bitmap.getPixels(), bitmap.pixelRef()); -#endif - return; - } - - SkIRect srcR; - SkRect dstR(dstRect); - float invScaleX = (float)bitmap.width() / image->origWidth(); - float invScaleY = (float)bitmap.height() / image->origHeight(); - - round_scaled(&srcR, srcRect, invScaleX, invScaleY); - if (srcR.isEmpty() || dstR.isEmpty()) { -#ifdef TRACE_SKIPPED_BITMAPS - SkDebugf("----- skip bitmapimage: [%d %d] src-empty %d dst-empty %d\n", - bitmap.width(), bitmap.height(), - srcR.isEmpty(), dstR.isEmpty()); -#endif - return; - } - - SkCanvas* canvas = ctxt->platformContext()->mCanvas; - SkPaint paint; - - ctxt->setupBitmapPaint(&paint); // need global alpha among other things - paint.setFilterBitmap(true); - paint.setXfermodeMode(WebCoreCompositeToSkiaComposite(compositeOp)); - fixPaintForBitmapsThatMaySeam(&paint); - canvas->drawBitmapRect(bitmap, &srcR, dstR, &paint); - -#ifdef TRACE_SUBSAMPLED_BITMAPS - if (bitmap.width() != image->origWidth() || - bitmap.height() != image->origHeight()) { - SkDebugf("--- BitmapImage::draw [%d %d] orig [%d %d]\n", - bitmap.width(), bitmap.height(), - image->origWidth(), image->origHeight()); - } -#endif -} - -void BitmapImage::setURL(const String& str) -{ - m_source.setURL(str); -} - -/////////////////////////////////////////////////////////////////////////////// - -void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& srcRect, - const AffineTransform& patternTransform, - const FloatPoint& phase, ColorSpace, - CompositeOperator compositeOp, const FloatRect& destRect) -{ - SkBitmapRef* image = this->nativeImageForCurrentFrame(); - if (!image) { // If it's too early we won't have an image yet. - return; - } - - // in case we get called with an incomplete bitmap - const SkBitmap& origBitmap = image->bitmap(); - if (origBitmap.getPixels() == NULL && origBitmap.pixelRef() == NULL) { - return; - } - - SkRect dstR(destRect); - if (dstR.isEmpty()) { - return; - } - - SkIRect srcR; - // we may have to scale if the image has been subsampled (so save RAM) - bool imageIsSubSampled = image->origWidth() != origBitmap.width() || - image->origHeight() != origBitmap.height(); - float scaleX = 1; - float scaleY = 1; - if (imageIsSubSampled) { - scaleX = (float)image->origWidth() / origBitmap.width(); - scaleY = (float)image->origHeight() / origBitmap.height(); -// SkDebugf("----- subsampled %g %g\n", scaleX, scaleY); - round_scaled(&srcR, srcRect, 1 / scaleX, 1 / scaleY); - } else { - round(&srcR, srcRect); - } - - // now extract the proper subset of the src image - SkBitmap bitmap; - if (!origBitmap.extractSubset(&bitmap, srcR)) { - SkDebugf("--- Image::drawPattern calling extractSubset failed\n"); - return; - } - - SkCanvas* canvas = ctxt->platformContext()->mCanvas; - SkPaint paint; - ctxt->setupBitmapPaint(&paint); // need global alpha among other things - - SkShader* shader = SkShader::CreateBitmapShader(bitmap, - SkShader::kRepeat_TileMode, - SkShader::kRepeat_TileMode); - paint.setShader(shader)->unref(); - // now paint is the only owner of shader - paint.setXfermodeMode(WebCoreCompositeToSkiaComposite(compositeOp)); - paint.setFilterBitmap(true); - fixPaintForBitmapsThatMaySeam(&paint); - - SkMatrix matrix(patternTransform); - - if (imageIsSubSampled) { - matrix.preScale(SkFloatToScalar(scaleX), SkFloatToScalar(scaleY)); - } - // We also need to translate it such that the origin of the pattern is the - // origin of the destination rect, which is what WebKit expects. Skia uses - // the coordinate system origin as the base for the patter. If WebKit wants - // a shifted image, it will shift it from there using the patternTransform. - float tx = phase.x() + srcRect.x() * patternTransform.a(); - float ty = phase.y() + srcRect.y() * patternTransform.d(); - matrix.postTranslate(SkFloatToScalar(tx), SkFloatToScalar(ty)); - shader->setLocalMatrix(matrix); -#if 0 - SkDebugf("--- drawPattern: src [%g %g %g %g] dst [%g %g %g %g] transform [%g %g %g %g %g %g] matrix [%g %g %g %g %g %g]\n", - srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), - destRect.x(), destRect.y(), destRect.width(), destRect.height(), - patternTransform.a(), patternTransform.b(), patternTransform.c(), - patternTransform.d(), patternTransform.e(), patternTransform.f(), - matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); -#endif - canvas->drawRect(dstR, paint); - -#ifdef TRACE_SUBSAMPLED_BITMAPS - if (bitmap.width() != image->origWidth() || - bitmap.height() != image->origHeight()) { - SkDebugf("--- Image::drawPattern [%d %d] orig [%d %d] dst [%g %g]\n", - bitmap.width(), bitmap.height(), - image->origWidth(), image->origHeight(), - SkScalarToFloat(dstR.width()), SkScalarToFloat(dstR.height())); - } -#endif -} - -// missingImage, textAreaResizeCorner -PassRefPtr<Image> Image::loadPlatformResource(const char *name) -{ - android::AssetManager* am = globalAssetManager(); - - SkString path("webkit/"); - path.append(name); - path.append(".png"); - - android::Asset* a = am->open(path.c_str(), - android::Asset::ACCESS_BUFFER); - if (a == NULL) { - SkDebugf("---------------- failed to open image asset %s\n", name); - return NULL; - } - - SkAutoTDelete<android::Asset> ad(a); - - SkBitmap bm; - if (SkImageDecoder::DecodeMemory(a->getBuffer(false), a->getLength(), &bm)) { - SkBitmapRef* ref = new SkBitmapRef(bm); - // create will call ref(), so we need aur() to release ours upon return - SkAutoUnref aur(ref); - return BitmapImage::create(ref, 0); - } - return Image::nullImage(); -} - -} // namespace diff --git a/WebCore/platform/graphics/android/ImageBufferAndroid.cpp b/WebCore/platform/graphics/android/ImageBufferAndroid.cpp deleted file mode 100644 index c7adb25..0000000 --- a/WebCore/platform/graphics/android/ImageBufferAndroid.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "ImageBuffer.h" - -#include "Base64.h" -#include "BitmapImage.h" -#include "ColorSpace.h" -#include "ImageData.h" -#include "GraphicsContext.h" -#include "NotImplemented.h" -#include "PlatformGraphicsContext.h" -#include "SkBitmapRef.h" -#include "SkCanvas.h" -#include "SkColorPriv.h" -#include "SkDevice.h" -#include "SkImageEncoder.h" -#include "SkStream.h" -#include "SkUnPreMultiply.h" -#include "android_graphics.h" - -using namespace std; - -namespace WebCore { - -ImageBufferData::ImageBufferData(const IntSize&) -{ -} - -ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode, bool& success) - : m_data(size) - , m_size(size) -{ - m_context.set(GraphicsContext::createOffscreenContext(size.width(), size.height())); - success = true; -} - -ImageBuffer::~ImageBuffer() -{ -} - -GraphicsContext* ImageBuffer::context() const -{ - return m_context.get(); -} - -bool ImageBuffer::drawsUsingCopy() const -{ - return true; -} - -PassRefPtr<Image> ImageBuffer::copyImage() const -{ - ASSERT(context()); - SkCanvas* canvas = context()->platformContext()->mCanvas; - SkDevice* device = canvas->getDevice(); - const SkBitmap& orig = device->accessBitmap(false); - - SkBitmap copy; - orig.copyTo(©, orig.config()); - - SkBitmapRef* ref = new SkBitmapRef(copy); - RefPtr<Image> image = BitmapImage::create(ref, 0); - ref->unref(); - return image; -} - -void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const -{ - SkDebugf("xxxxxxxxxxxxxxxxxx clip not implemented\n"); -} - -void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, bool useLowQualityScale) -{ - RefPtr<Image> imageCopy = copyImage(); - context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale); -} - -void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) -{ - RefPtr<Image> imageCopy = copyImage(); - imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect); -} - -PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const -{ - GraphicsContext* gc = this->context(); - if (!gc) { - return 0; - } - - const SkBitmap& src = android_gc2canvas(gc)->getDevice()->accessBitmap(false); - SkAutoLockPixels alp(src); - if (!src.getPixels()) { - return 0; - } - - // ! Can't use PassRefPtr<>, otherwise the second access will cause crash. - RefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); - unsigned char* data = result->data()->data()->data(); - - if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height()) - memset(data, 0, result->data()->length()); - - int originx = rect.x(); - int destx = 0; - if (originx < 0) { - destx = -originx; - originx = 0; - } - int endx = rect.x() + rect.width(); - if (endx > m_size.width()) - endx = m_size.width(); - int numColumns = endx - originx; - - int originy = rect.y(); - int desty = 0; - if (originy < 0) { - desty = -originy; - originy = 0; - } - int endy = rect.y() + rect.height(); - if (endy > m_size.height()) - endy = m_size.height(); - int numRows = endy - originy; - - unsigned srcPixelsPerRow = src.rowBytesAsPixels(); - unsigned destBytesPerRow = 4 * rect.width(); - - const SkPMColor* srcRows = src.getAddr32(originx, originy); - unsigned char* destRows = data + desty * destBytesPerRow + destx * 4; - for (int y = 0; y < numRows; ++y) { - for (int x = 0; x < numColumns; x++) { - // ugh, it appears they want unpremultiplied pixels - SkColor c = SkUnPreMultiply::PMColorToColor(srcRows[x]); - int basex = x * 4; - destRows[basex + 0] = SkColorGetR(c); - destRows[basex + 1] = SkColorGetG(c); - destRows[basex + 2] = SkColorGetB(c); - destRows[basex + 3] = SkColorGetA(c); - } - srcRows += srcPixelsPerRow; - destRows += destBytesPerRow; - } - return result; -} - -void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) -{ - GraphicsContext* gc = this->context(); - if (!gc) { - return; - } - - const SkBitmap& dst = android_gc2canvas(gc)->getDevice()->accessBitmap(true); - SkAutoLockPixels alp(dst); - if (!dst.getPixels()) { - return; - } - - ASSERT(sourceRect.width() > 0); - ASSERT(sourceRect.height() > 0); - - int originx = sourceRect.x(); - int destx = destPoint.x() + sourceRect.x(); - ASSERT(destx >= 0); - ASSERT(destx < m_size.width()); - ASSERT(originx >= 0); - ASSERT(originx <= sourceRect.right()); - - int endx = destPoint.x() + sourceRect.right(); - ASSERT(endx <= m_size.width()); - - int numColumns = endx - destx; - - int originy = sourceRect.y(); - int desty = destPoint.y() + sourceRect.y(); - ASSERT(desty >= 0); - ASSERT(desty < m_size.height()); - ASSERT(originy >= 0); - ASSERT(originy <= sourceRect.bottom()); - - int endy = destPoint.y() + sourceRect.bottom(); - ASSERT(endy <= m_size.height()); - int numRows = endy - desty; - - unsigned srcBytesPerRow = 4 * source->width(); - unsigned dstPixelsPerRow = dst.rowBytesAsPixels(); - - unsigned char* srcRows = source->data()->data()->data() + originy * srcBytesPerRow + originx * 4; - SkPMColor* dstRows = dst.getAddr32(destx, desty); - for (int y = 0; y < numRows; ++y) { - for (int x = 0; x < numColumns; x++) { - int basex = x * 4; - dstRows[x] = SkPackARGB32(srcRows[basex + 3], - srcRows[basex + 0], - srcRows[basex + 1], - srcRows[basex + 2]); - } - dstRows += dstPixelsPerRow; - srcRows += srcBytesPerRow; - } -} - - -String ImageBuffer::toDataURL(const String&, const double*) const -{ - // Encode the image into a vector. - SkDynamicMemoryWStream pngStream; - const SkBitmap& dst = android_gc2canvas(context())->getDevice()->accessBitmap(true); - SkImageEncoder::EncodeStream(&pngStream, dst, SkImageEncoder::kPNG_Type, 100); - - // Convert it into base64. - Vector<char> pngEncodedData; - pngEncodedData.append(pngStream.getStream(), pngStream.getOffset()); - Vector<char> base64EncodedData; - base64Encode(pngEncodedData, base64EncodedData); - // Append with a \0 so that it's a valid string. - base64EncodedData.append('\0'); - - // And the resulting string. - return String::format("data:image/png;base64,%s", base64EncodedData.data()); -} - -void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookupTable) -{ - notImplemented(); -} - -} diff --git a/WebCore/platform/graphics/android/ImageBufferData.h b/WebCore/platform/graphics/android/ImageBufferData.h deleted file mode 100644 index 269b365..0000000 --- a/WebCore/platform/graphics/android/ImageBufferData.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 ImageBufferData_h -#define ImageBufferData_h - -namespace WebCore { - -class IntSize; - -class ImageBufferData { -public: - ImageBufferData(const IntSize&); -}; - -} // namespace WebCore - -#endif // ImageBufferData_h diff --git a/WebCore/platform/graphics/android/ImageSourceAndroid.cpp b/WebCore/platform/graphics/android/ImageSourceAndroid.cpp deleted file mode 100644 index 982302c..0000000 --- a/WebCore/platform/graphics/android/ImageSourceAndroid.cpp +++ /dev/null @@ -1,505 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "BitmapAllocatorAndroid.h" -#include "ImageSource.h" -#include "IntSize.h" -#include "NotImplemented.h" -#include "SharedBuffer.h" -#include "PlatformString.h" - -#include "SkBitmapRef.h" -#include "SkImageDecoder.h" -#include "SkImageRef.h" -#include "SkStream.h" -#include "SkTemplates.h" - -#ifdef ANDROID_ANIMATED_GIF - #include "EmojiFont.h" - #include "GIFImageDecoder.h" - - using namespace android; -#endif - -// TODO: We should make use of some of the common code in platform/graphics/ImageSource.cpp. - -SkPixelRef* SkCreateRLEPixelRef(const SkBitmap& src); - -//#define TRACE_SUBSAMPLE_BITMAPS -//#define TRACE_RLE_BITMAPS - - -// flag to tell us when we're on a large-ram device (e.g. >= 256M) -#ifdef ANDROID_LARGE_MEMORY_DEVICE - // don't use RLE for images smaller than this, since they incur a drawing cost - // (and don't work as patterns yet) we only want to use RLE when we must - #define MIN_RLE_ALLOC_SIZE (8*1024*1024) - - // see dox for computeMaxBitmapSizeForCache() - #define MAX_SIZE_BEFORE_SUBSAMPLE (32*1024*1024) - - // preserve quality for 24/32bit src - static const SkBitmap::Config gPrefConfigTable[6] = { - SkBitmap::kIndex8_Config, // src: index, opaque - SkBitmap::kIndex8_Config, // src: index, alpha - SkBitmap::kRGB_565_Config, // src: 16bit, opaque - SkBitmap::kARGB_8888_Config, // src: 16bit, alpha (promote to 32bit) - SkBitmap::kARGB_8888_Config, // src: 32bit, opaque - SkBitmap::kARGB_8888_Config, // src: 32bit, alpha - }; -#else - #define MIN_RLE_ALLOC_SIZE (2*1024*1024) - #define MAX_SIZE_BEFORE_SUBSAMPLE (2*1024*1024) - - // tries to minimize memory usage (i.e. demote opaque 32bit -> 16bit) - static const SkBitmap::Config gPrefConfigTable[6] = { - SkBitmap::kIndex8_Config, // src: index, opaque - SkBitmap::kIndex8_Config, // src: index, alpha - SkBitmap::kRGB_565_Config, // src: 16bit, opaque - SkBitmap::kARGB_8888_Config, // src: 16bit, alpha (promote to 32bit) - SkBitmap::kRGB_565_Config, // src: 32bit, opaque (demote to 16bit) - SkBitmap::kARGB_8888_Config, // src: 32bit, alpha - }; -#endif - -/* Images larger than this should be subsampled. Using ashmem, the decoded - pixels will be purged as needed, so this value can be pretty large. Making - it too small hurts image quality (e.g. abc.com background). 2Meg works for - the sites I've tested, but if we hit important sites that need more, we - should try increasing it and see if it has negative impact on performance - (i.e. we end up thrashing because we need to keep decoding images that have - been purged. - - Perhaps this value should be some fraction of the available RAM... -*/ -size_t computeMaxBitmapSizeForCache() { - return MAX_SIZE_BEFORE_SUBSAMPLE; -} - -/* 8bit images larger than this should be recompressed in RLE, to reduce - on the imageref cache. - - Downside: performance, since we have to decode/encode - and then rle-decode when we draw. -*/ -static bool shouldReencodeAsRLE(const SkBitmap& bm) { - const SkBitmap::Config c = bm.config(); - return (SkBitmap::kIndex8_Config == c || SkBitmap::kA8_Config == c) - && - bm.width() >= 64 // narrower than this won't compress well in RLE - && - bm.getSize() > MIN_RLE_ALLOC_SIZE; -} - -/////////////////////////////////////////////////////////////////////////////// - -class PrivateAndroidImageSourceRec : public SkBitmapRef { -public: - PrivateAndroidImageSourceRec(const SkBitmap& bm, int origWidth, - int origHeight, int sampleSize) - : SkBitmapRef(bm), fSampleSize(sampleSize), fAllDataReceived(false) { - this->setOrigSize(origWidth, origHeight); - } - - int fSampleSize; - bool fAllDataReceived; -}; - -namespace WebCore { - -ImageSource::ImageSource(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption) - : m_alphaOption(alphaOption) - , m_gammaAndColorProfileOption(gammaAndColorProfileOption) -{ - m_decoder.m_image = NULL; -#ifdef ANDROID_ANIMATED_GIF - m_decoder.m_gifDecoder = 0; -#endif -} - -ImageSource::~ImageSource() { - delete m_decoder.m_image; -#ifdef ANDROID_ANIMATED_GIF - delete m_decoder.m_gifDecoder; -#endif -} - -bool ImageSource::initialized() const { - return -#ifdef ANDROID_ANIMATED_GIF - m_decoder.m_gifDecoder || -#endif - m_decoder.m_image != NULL; -} - -static int computeSampleSize(const SkBitmap& bitmap) { - const size_t maxSize = computeMaxBitmapSizeForCache(); - size_t size = bitmap.getSize(); - int sampleSize = 1; - - while (size > maxSize) { - sampleSize <<= 1; - size >>= 2; - } - -#ifdef TRACE_SUBSAMPLE_BITMAPS - if (sampleSize > 1) { - SkDebugf("------- bitmap [%d %d] config=%d origSize=%d predictSize=%d sampleSize=%d\n", - bitmap.width(), bitmap.height(), bitmap.config(), - bitmap.getSize(), size, sampleSize); - } -#endif - return sampleSize; -} - -static SkPixelRef* convertToRLE(SkBitmap* bm, const void* data, size_t len) { - if (!shouldReencodeAsRLE(*bm)) { - return NULL; - } - - SkBitmap tmp; - - if (!SkImageDecoder::DecodeMemory(data, len, &tmp) || !tmp.getPixels()) { - return NULL; - } - - SkPixelRef* ref = SkCreateRLEPixelRef(tmp); - if (NULL == ref) { - return NULL; - } - -#ifdef TRACE_RLE_BITMAPS - SkDebugf("---- reencode bitmap as RLE: [%d %d] encodeSize=%d\n", - tmp.width(), tmp.height(), len); -#endif - - bm->setConfig(SkBitmap::kRLE_Index8_Config, tmp.width(), tmp.height()); - return ref; -} - -void ImageSource::clearURL() -{ - m_decoder.m_url.reset(); -} - -void ImageSource::setURL(const String& url) -{ - if (url.startsWith("data:")) { - clearURL(); - } else { - m_decoder.m_url.setUTF16(url.characters(), url.length()); - } -} - -#ifdef ANDROID_ANIMATED_GIF -// we only animate small GIFs for now, to save memory -// also, we only support this in Japan, hence the Emoji check -static bool should_use_animated_gif(int width, int height) { -#ifdef ANDROID_LARGE_MEMORY_DEVICE - return true; -#else - return EmojiFont::IsAvailable() && - width <= 32 && height <= 32; -#endif -} -#endif - -void ImageSource::setData(SharedBuffer* data, bool allDataReceived) -{ -#ifdef ANDROID_ANIMATED_GIF - // This is only necessary if we allow ourselves to partially decode GIF - bool disabledAnimatedGif = false; - if (m_decoder.m_gifDecoder - && !m_decoder.m_gifDecoder->failed()) { - m_decoder.m_gifDecoder->setData(data, allDataReceived); - if (!allDataReceived || m_decoder.m_gifDecoder->frameCount() != 1) - return; - disabledAnimatedGif = true; - delete m_decoder.m_gifDecoder; - m_decoder.m_gifDecoder = 0; - } -#endif - if (NULL == m_decoder.m_image -#ifdef ANDROID_ANIMATED_GIF - && !m_decoder.m_gifDecoder -#endif - ) { - SkBitmap tmp; - - SkMemoryStream stream(data->data(), data->size(), false); - SkImageDecoder* codec = SkImageDecoder::Factory(&stream); - if (!codec) - return; - - SkAutoTDelete<SkImageDecoder> ad(codec); - codec->setPrefConfigTable(gPrefConfigTable); - if (!codec->decode(&stream, &tmp, SkImageDecoder::kDecodeBounds_Mode)) - return; - - int origW = tmp.width(); - int origH = tmp.height(); - -#ifdef ANDROID_ANIMATED_GIF - // First, check to see if this is an animated GIF - const Vector<char>& buffer = data->buffer(); - const char* contents = buffer.data(); - if (buffer.size() > 3 && strncmp(contents, "GIF8", 4) == 0 - && should_use_animated_gif(origW, origH) - && !disabledAnimatedGif) { - // This means we are looking at a GIF, so create special - // GIF Decoder - // Need to wait for all data received if we are assigning an - // allocator (which we are not at the moment). - if (!m_decoder.m_gifDecoder /*&& allDataReceived*/) - m_decoder.m_gifDecoder = new GIFImageDecoder(m_alphaOption, m_gammaAndColorProfileOption); - int frameCount = 0; - if (!m_decoder.m_gifDecoder->failed()) { - m_decoder.m_gifDecoder->setData(data, allDataReceived); - if (!allDataReceived) - return; - frameCount = m_decoder.m_gifDecoder->frameCount(); - } - if (frameCount != 1) - return; - delete m_decoder.m_gifDecoder; - m_decoder.m_gifDecoder = 0; - } -#endif - - int sampleSize = computeSampleSize(tmp); - if (sampleSize > 1) { - codec->setSampleSize(sampleSize); - stream.rewind(); - if (!codec->decode(&stream, &tmp, - SkImageDecoder::kDecodeBounds_Mode)) { - return; - } - } - - m_decoder.m_image = new PrivateAndroidImageSourceRec(tmp, origW, origH, - sampleSize); - -// SkDebugf("----- started: [%d %d] %s\n", origW, origH, m_decoder.m_url.c_str()); - } - - PrivateAndroidImageSourceRec* decoder = m_decoder.m_image; - if (allDataReceived && decoder && !decoder->fAllDataReceived) { - decoder->fAllDataReceived = true; - - SkBitmap* bm = &decoder->bitmap(); - SkPixelRef* ref = convertToRLE(bm, data->data(), data->size()); - - if (ref) { - bm->setPixelRef(ref)->unref(); - } else { - BitmapAllocatorAndroid alloc(data, decoder->fSampleSize); - if (!alloc.allocPixelRef(bm, NULL)) { - return; - } - ref = bm->pixelRef(); - } - - // we promise to never change the pixels (makes picture recording fast) - ref->setImmutable(); - // give it the URL if we have one - ref->setURI(m_decoder.m_url); - } -} - -bool ImageSource::isSizeAvailable() -{ - return -#ifdef ANDROID_ANIMATED_GIF - (m_decoder.m_gifDecoder - && m_decoder.m_gifDecoder->isSizeAvailable()) || -#endif - m_decoder.m_image != NULL; -} - -IntSize ImageSource::size() const -{ -#ifdef ANDROID_ANIMATED_GIF - if (m_decoder.m_gifDecoder) - return m_decoder.m_gifDecoder->size(); -#endif - if (m_decoder.m_image) { - return IntSize(m_decoder.m_image->origWidth(), m_decoder.m_image->origHeight()); - } - return IntSize(0, 0); -} - -int ImageSource::repetitionCount() -{ -#ifdef ANDROID_ANIMATED_GIF - if (m_decoder.m_gifDecoder) - return m_decoder.m_gifDecoder->repetitionCount(); - if (!m_decoder.m_image) return 0; -#endif - return 1; - // A property with value 0 means loop forever. -} - -size_t ImageSource::frameCount() const -{ -#ifdef ANDROID_ANIMATED_GIF - if (m_decoder.m_gifDecoder) { - return m_decoder.m_gifDecoder->failed() ? 0 - : m_decoder.m_gifDecoder->frameCount(); - } -#endif - // i.e. 0 frames if we're not decoded, or 1 frame if we are - return m_decoder.m_image != NULL; -} - -SkBitmapRef* ImageSource::createFrameAtIndex(size_t index) -{ -#ifdef ANDROID_ANIMATED_GIF - if (m_decoder.m_gifDecoder) { - RGBA32Buffer* buffer = - m_decoder.m_gifDecoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) - return 0; - SkBitmap& bitmap = buffer->bitmap(); - SkPixelRef* pixelRef = bitmap.pixelRef(); - if (pixelRef) - pixelRef->setURI(m_decoder.m_url); - return new SkBitmapRef(bitmap); - } -#else - SkASSERT(index == 0); -#endif - SkASSERT(m_decoder.m_image != NULL); - m_decoder.m_image->ref(); - return m_decoder.m_image; -} - -float ImageSource::frameDurationAtIndex(size_t index) -{ - float duration = 0; -#ifdef ANDROID_ANIMATED_GIF - if (m_decoder.m_gifDecoder) { - RGBA32Buffer* buffer - = m_decoder.m_gifDecoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) - return 0; - duration = buffer->duration() / 1000.0f; - } -#else - SkASSERT(index == 0); -#endif - - // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. - // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify - // a duration of <= 10 ms. See gfxImageFrame::GetTimeout in Gecko or Radar 4051389 for more. - if (duration <= 0.010f) - duration = 0.100f; - return duration; -} - -bool ImageSource::frameHasAlphaAtIndex(size_t index) -{ -#ifdef ANDROID_ANIMATED_GIF - if (m_decoder.m_gifDecoder) { - if (!m_decoder.m_gifDecoder->supportsAlpha()) - return false; - - RGBA32Buffer* buffer = - m_decoder.m_gifDecoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) - return false; - - return buffer->hasAlpha(); - } -#else - SkASSERT(0 == index); -#endif - - if (NULL == m_decoder.m_image) - return true; // if we're not sure, assume the worse-case - const PrivateAndroidImageSourceRec& decoder = *m_decoder.m_image; - // if we're 16bit, we know even without all the data available - if (decoder.bitmap().getConfig() == SkBitmap::kRGB_565_Config) - return false; - - if (!decoder.fAllDataReceived) - return true; // if we're not sure, assume the worse-case - - return !decoder.bitmap().isOpaque(); -} - -bool ImageSource::frameIsCompleteAtIndex(size_t index) -{ -#ifdef ANDROID_ANIMATED_GIF - if (m_decoder.m_gifDecoder) { - RGBA32Buffer* buffer = - m_decoder.m_gifDecoder->frameBufferAtIndex(index); - return buffer && buffer->status() == RGBA32Buffer::FrameComplete; - } -#else - SkASSERT(0 == index); -#endif - return m_decoder.m_image && m_decoder.m_image->fAllDataReceived; -} - -void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived) -{ -#ifdef ANDROID_ANIMATED_GIF - if (!destroyAll) { - if (m_decoder.m_gifDecoder) - m_decoder.m_gifDecoder->clearFrameBufferCache(clearBeforeFrame); - return; - } - - delete m_decoder.m_gifDecoder; - m_decoder.m_gifDecoder = 0; - if (data) - setData(data, allDataReceived); -#endif - // do nothing, since the cache is managed elsewhere -} - -IntSize ImageSource::frameSizeAtIndex(size_t index) const -{ - // for now, all (1) of our frames are the same size - return this->size(); -} - -String ImageSource::filenameExtension() const -{ - // FIXME: need to add virtual to our decoders to return "jpg/png/gif/..." -#ifdef ANDROID_ANIMATED_GIF - if (m_decoder.m_gifDecoder) - return m_decoder.m_gifDecoder->filenameExtension(); -#endif - return String(); -} - -bool ImageSource::getHotSpot(IntPoint&) const -{ - return false; -} - -} diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp deleted file mode 100644 index 7bef420..0000000 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ /dev/null @@ -1,1402 +0,0 @@ -#include "config.h" -#include "LayerAndroid.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "AndroidAnimation.h" -#include "ClassTracker.h" -#include "DrawExtra.h" -#include "GLUtils.h" -#include "MediaLayer.h" -#include "PaintLayerOperation.h" -#include "ParseCanvas.h" -#include "SkBitmapRef.h" -#include "SkBounder.h" -#include "SkDrawFilter.h" -#include "SkPaint.h" -#include "SkPicture.h" -#include "TilesManager.h" -#include <wtf/CurrentTime.h> - -#define LAYER_DEBUG // Add diagonals for debugging -#undef LAYER_DEBUG - -#include <cutils/log.h> -#include <wtf/text/CString.h> -#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "LayerAndroid", __VA_ARGS__) - -#ifdef DEBUG - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "LayerAndroid", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -namespace WebCore { - -static int gUniqueId; - -class OpacityDrawFilter : public SkDrawFilter { - public: - OpacityDrawFilter(int opacity) : m_opacity(opacity) { } - virtual void filter(SkPaint* paint, Type) - { - paint->setAlpha(m_opacity); - } - private: - int m_opacity; -}; - -/////////////////////////////////////////////////////////////////////////////// - -LayerAndroid::LayerAndroid(RenderLayer* owner) : SkLayer(), - m_haveClip(false), - m_isFixed(false), - m_isIframe(false), - m_backfaceVisibility(true), - m_visible(true), - m_preserves3D(false), - m_anchorPointZ(0), - m_recordingPicture(0), - m_contentsImage(0), - m_extra(0), - m_uniqueId(++gUniqueId), - m_drawingTexture(0), - m_reservedTexture(0), - m_pictureUsed(0), - m_requestSent(false), - m_scale(1), - m_lastComputeTextureSize(0), - m_owningLayer(owner) -{ - m_backgroundColor = 0; - - m_preserves3D = false; - m_dirty = false; - m_iframeOffset.set(0,0); -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("LayerAndroid"); -#endif -} - -LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer), - m_haveClip(layer.m_haveClip), - m_isIframe(layer.m_isIframe), - m_contentsImage(0), - m_extra(0), // deliberately not copied - m_uniqueId(layer.m_uniqueId), - m_drawingTexture(0), - m_reservedTexture(0), - m_requestSent(false), - m_owningLayer(layer.m_owningLayer) -{ - m_isFixed = layer.m_isFixed; - copyBitmap(layer.m_contentsImage); - m_renderLayerPos = layer.m_renderLayerPos; - m_transform = layer.m_transform; - m_backfaceVisibility = layer.m_backfaceVisibility; - m_visible = layer.m_visible; - m_backgroundColor = layer.m_backgroundColor; - - m_fixedLeft = layer.m_fixedLeft; - m_fixedTop = layer.m_fixedTop; - m_fixedRight = layer.m_fixedRight; - m_fixedBottom = layer.m_fixedBottom; - m_fixedMarginLeft = layer.m_fixedMarginLeft; - m_fixedMarginTop = layer.m_fixedMarginTop; - m_fixedMarginRight = layer.m_fixedMarginRight; - m_fixedMarginBottom = layer.m_fixedMarginBottom; - m_fixedRect = layer.m_fixedRect; - m_iframeOffset = layer.m_iframeOffset; - m_recordingPicture = layer.m_recordingPicture; - SkSafeRef(m_recordingPicture); - - m_preserves3D = layer.m_preserves3D; - m_anchorPointZ = layer.m_anchorPointZ; - m_drawTransform = layer.m_drawTransform; - m_childrenTransform = layer.m_childrenTransform; - m_dirty = layer.m_dirty; - m_pictureUsed = layer.m_pictureUsed; - m_scale = layer.m_scale; - m_lastComputeTextureSize = 0; - - for (int i = 0; i < layer.countChildren(); i++) - addChild(layer.getChild(i)->copy())->unref(); - - KeyframesMap::const_iterator end = layer.m_animations.end(); - for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) { - pair<String, int> key((it->second)->name(), (it->second)->type()); - m_animations.add(key, (it->second)->copy()); - } - -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("LayerAndroid"); -#endif -} - -LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(), - m_haveClip(false), - m_isFixed(false), - m_isIframe(false), - m_recordingPicture(picture), - m_contentsImage(0), - m_extra(0), - m_uniqueId(-1), - m_drawingTexture(0), - m_reservedTexture(0), - m_requestSent(false), - m_scale(1), - m_lastComputeTextureSize(0), - m_owningLayer(0) -{ - m_backgroundColor = 0; - m_dirty = false; - SkSafeRef(m_recordingPicture); - m_iframeOffset.set(0,0); -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("LayerAndroid"); -#endif -} - -bool LayerAndroid::removeTexture(BackedDoubleBufferedTexture* aTexture) -{ - LayerTexture* texture = static_cast<LayerTexture*>(aTexture); - android::AutoMutex lock(m_atomicSync); - - bool textureReleased = true; - if (!texture) { // remove ourself from both textures - if (m_drawingTexture) - textureReleased &= m_drawingTexture->release(this); - if (m_reservedTexture && - m_reservedTexture != m_drawingTexture) - textureReleased &= m_reservedTexture->release(this); - } else { - if (m_drawingTexture && m_drawingTexture == texture) - textureReleased &= m_drawingTexture->release(this); - if (m_reservedTexture && - m_reservedTexture == texture && - m_reservedTexture != m_drawingTexture) - textureReleased &= m_reservedTexture->release(this); - } - if (m_drawingTexture && - ((m_drawingTexture->owner() != this) || - (m_drawingTexture->delayedReleaseOwner() == this))) - m_drawingTexture = 0; - if (m_reservedTexture && - ((m_reservedTexture->owner() != this) || - (m_reservedTexture->delayedReleaseOwner() == this))) - m_reservedTexture = 0; - return textureReleased; -} - -LayerAndroid::~LayerAndroid() -{ - removeTexture(0); - removeChildren(); - delete m_extra; - delete m_contentsImage; - SkSafeUnref(m_recordingPicture); - m_animations.clear(); -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("LayerAndroid"); -#endif -} - -static int gDebugNbAnims = 0; - -bool LayerAndroid::evaluateAnimations() -{ - double time = WTF::currentTime(); - gDebugNbAnims = 0; - return evaluateAnimations(time); -} - -bool LayerAndroid::hasAnimations() const -{ - for (int i = 0; i < countChildren(); i++) { - if (getChild(i)->hasAnimations()) - return true; - } - return !!m_animations.size(); -} - -bool LayerAndroid::evaluateAnimations(double time) -{ - bool hasRunningAnimations = false; - for (int i = 0; i < countChildren(); i++) { - if (getChild(i)->evaluateAnimations(time)) - hasRunningAnimations = true; - } - - m_hasRunningAnimations = false; - int nbAnims = 0; - KeyframesMap::const_iterator end = m_animations.end(); - for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) { - gDebugNbAnims++; - nbAnims++; - LayerAndroid* currentLayer = const_cast<LayerAndroid*>(this); - if (!(it->second)->finished() && - (it->second)->evaluate(currentLayer, time)) - m_hasRunningAnimations = true; - } - - return hasRunningAnimations || m_hasRunningAnimations; -} - -void LayerAndroid::addDirtyArea(GLWebViewState* glWebViewState) -{ - IntSize layerSize(getSize().width(), getSize().height()); - - FloatRect area = TilesManager::instance()->shader()->rectInInvScreenCoord(drawTransform(), layerSize); - FloatRect clip = TilesManager::instance()->shader()->convertScreenCoordToInvScreenCoord(m_clippingRect); - - area.intersect(clip); - IntRect dirtyArea(area.x(), area.y(), area.width(), area.height()); - glWebViewState->addDirtyArea(dirtyArea); -} - -void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> prpAnim) -{ - RefPtr<AndroidAnimation> anim = prpAnim; - pair<String, int> key(anim->name(), anim->type()); - removeAnimationsForProperty(anim->type()); - m_animations.add(key, anim); -} - -void LayerAndroid::removeAnimationsForProperty(AnimatedPropertyID property) -{ - KeyframesMap::const_iterator end = m_animations.end(); - Vector<pair<String, int> > toDelete; - for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) { - if ((it->second)->type() == property) - toDelete.append(it->first); - } - - for (unsigned int i = 0; i < toDelete.size(); i++) - m_animations.remove(toDelete[i]); -} - -void LayerAndroid::removeAnimationsForKeyframes(const String& name) -{ - KeyframesMap::const_iterator end = m_animations.end(); - Vector<pair<String, int> > toDelete; - for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) { - if ((it->second)->name() == name) - toDelete.append(it->first); - } - - for (unsigned int i = 0; i < toDelete.size(); i++) - m_animations.remove(toDelete[i]); -} - -// We only use the bounding rect of the layer as mask... -// TODO: use a real mask? -void LayerAndroid::setMaskLayer(LayerAndroid* layer) -{ - if (layer) - m_haveClip = true; -} - -void LayerAndroid::setBackgroundColor(SkColor color) -{ - m_backgroundColor = color; -} - -static int gDebugChildLevel; - -FloatPoint LayerAndroid::translation() const -{ - TransformationMatrix::DecomposedType tDecomp; - m_transform.decompose(tDecomp); - FloatPoint p(tDecomp.translateX, tDecomp.translateY); - return p; -} - -SkRect LayerAndroid::bounds() const -{ - SkRect rect; - bounds(&rect); - return rect; -} - -void LayerAndroid::bounds(SkRect* rect) const -{ - const SkPoint& pos = this->getPosition(); - const SkSize& size = this->getSize(); - - // The returned rect has the translation applied - // FIXME: apply the full transform to the rect, - // and fix the text selection accordingly - FloatPoint p(pos.fX, pos.fY); - p = m_transform.mapPoint(p); - rect->fLeft = p.x(); - rect->fTop = p.y(); - rect->fRight = p.x() + size.width(); - rect->fBottom = p.y() + size.height(); -} - -static bool boundsIsUnique(const SkTDArray<SkRect>& region, - const SkRect& local) -{ - for (int i = 0; i < region.count(); i++) { - if (region[i].contains(local)) - return false; - } - return true; -} - -void LayerAndroid::clipArea(SkTDArray<SkRect>* region) const -{ - SkRect local; - local.set(0, 0, std::numeric_limits<float>::max(), - std::numeric_limits<float>::max()); - clipInner(region, local); -} - -void LayerAndroid::clipInner(SkTDArray<SkRect>* region, - const SkRect& local) const -{ - SkRect localBounds; - bounds(&localBounds); - localBounds.intersect(local); - if (localBounds.isEmpty()) - return; - if (m_recordingPicture && boundsIsUnique(*region, localBounds)) - *region->append() = localBounds; - for (int i = 0; i < countChildren(); i++) - getChild(i)->clipInner(region, m_haveClip ? localBounds : local); -} - -class FindCheck : public SkBounder { -public: - FindCheck() - : m_drew(false) - , m_drewText(false) - { - } - - bool drew() const { return m_drew; } - bool drewText() const { return m_drewText; } - void reset() { m_drew = m_drewText = false; } - -protected: - virtual bool onIRect(const SkIRect& ) - { - m_drew = true; - return false; - } - - virtual bool onIRectGlyph(const SkIRect& , const SkBounder::GlyphRec& ) - { - m_drew = m_drewText = true; - return false; - } - - bool m_drew; - bool m_drewText; -}; - -class FindCanvas : public ParseCanvas { -public: - void draw(SkPicture* picture, SkScalar offsetX, SkScalar offsetY) - { - save(); - translate(-offsetX, -offsetY); - picture->draw(this); - restore(); - } -}; - -class LayerAndroid::FindState { -public: - static const int TOUCH_SLOP = 10; - - FindState(int x, int y) - : m_x(x) - , m_y(y) - , m_bestX(x) - , m_bestY(y) - , m_best(0) - { - m_bitmap.setConfig(SkBitmap::kARGB_8888_Config, TOUCH_SLOP * 2, - TOUCH_SLOP * 2); - m_checker.setBounder(&m_findCheck); - m_checker.setBitmapDevice(m_bitmap); - } - - const LayerAndroid* best() const { return m_best; } - int bestX() const { return m_bestX; } - int bestY() const { return m_bestY; } - - bool drew(SkPicture* picture, const SkRect& localBounds) - { - m_findCheck.reset(); - SkScalar localX = SkIntToScalar(m_x - TOUCH_SLOP) - localBounds.fLeft; - SkScalar localY = SkIntToScalar(m_y - TOUCH_SLOP) - localBounds.fTop; - m_checker.draw(picture, localX, localY); - return m_findCheck.drew(); - } - - bool drewText() { return m_findCheck.drewText(); } - - void setBest(const LayerAndroid* best, int x, int y) - { - m_best = best; - m_bestX = x; - m_bestY = y; - } - int x() const { return m_x; } - int y() const { return m_y; } - - void setLocation(int x, int y) - { - m_x = x; - m_y = y; - } - -protected: - int m_x; - int m_y; - int m_bestX; - int m_bestY; - const LayerAndroid* m_best; - FindCheck m_findCheck; - SkBitmap m_bitmap; - FindCanvas m_checker; -}; - -void LayerAndroid::findInner(LayerAndroid::FindState& state) const -{ - int x = state.x(); - int y = state.y(); - SkRect localBounds; - bounds(&localBounds); - if (!localBounds.contains(x, y)) - return; - // Move into local coordinates. - state.setLocation(x - localBounds.fLeft, y - localBounds.fTop); - for (int i = 0; i < countChildren(); i++) - getChild(i)->findInner(state); - // Move back into the parent coordinates. - int testX = state.x(); - int testY = state.y(); - state.setLocation(x + localBounds.fLeft, y + localBounds.fTop); - if (!m_recordingPicture) - return; - if (!contentIsScrollable() && !state.drew(m_recordingPicture, localBounds)) - return; - state.setBest(this, testX, testY); // set last match (presumably on top) -} - -const LayerAndroid* LayerAndroid::find(int* xPtr, int* yPtr, SkPicture* root) const -{ - FindState state(*xPtr, *yPtr); - SkRect rootBounds; - rootBounds.setEmpty(); - if (root && state.drew(root, rootBounds) && state.drewText()) - return 0; // use the root picture only if it contains the text - findInner(state); - *xPtr = state.bestX(); - *yPtr = state.bestY(); - return state.best(); -} - -/////////////////////////////////////////////////////////////////////////////// - -void LayerAndroid::updateFixedLayersPositions(SkRect viewport, LayerAndroid* parentIframeLayer) -{ - // If this is an iframe, accumulate the offset from the parent with - // current position, and change the parent pointer. - if (m_isIframe) { - // If this is the top level, take the current position - SkPoint parentOffset; - parentOffset.set(0,0); - if (parentIframeLayer) - parentOffset = parentIframeLayer->getPosition(); - - m_iframeOffset = parentOffset + getPosition(); - - parentIframeLayer = this; - } - - if (m_isFixed) { - // So if this is a fixed layer inside a iframe, use the iframe offset - // and the iframe's size as the viewport and pass to the children - if (parentIframeLayer) { - viewport = SkRect::MakeXYWH(parentIframeLayer->m_iframeOffset.fX, - parentIframeLayer->m_iframeOffset.fY, - parentIframeLayer->getSize().width(), - parentIframeLayer->getSize().height()); - } - float w = viewport.width(); - float h = viewport.height(); - float dx = viewport.fLeft; - float dy = viewport.fTop; - float x = dx; - float y = dy; - - // It turns out that when it is 'auto', the webkit computation will - // take one more factor into account, that is the original render - // layer's X,Y, such that it will align well with the parent's layer. - if (!(m_fixedLeft.defined() || m_fixedRight.defined())) - x += m_renderLayerPos.x(); - - if (!(m_fixedTop.defined() || m_fixedBottom.defined())) - y += m_renderLayerPos.y(); - - if (m_fixedLeft.defined() || !m_fixedRight.defined()) - x += m_fixedMarginLeft.calcFloatValue(w) + m_fixedLeft.calcFloatValue(w) - m_fixedRect.fLeft; - else - x += w - m_fixedMarginRight.calcFloatValue(w) - m_fixedRight.calcFloatValue(w) - m_fixedRect.fRight; - - if (m_fixedTop.defined() || !m_fixedBottom.defined()) - y += m_fixedMarginTop.calcFloatValue(h) + m_fixedTop.calcFloatValue(h) - m_fixedRect.fTop; - else - y += h - m_fixedMarginBottom.calcFloatValue(h) - m_fixedBottom.calcFloatValue(h) - m_fixedRect.fBottom; - - this->setPosition(x, y); - } - - int count = this->countChildren(); - for (int i = 0; i < count; i++) - this->getChild(i)->updateFixedLayersPositions(viewport, parentIframeLayer); -} - -void LayerAndroid::updatePositions() -{ - // apply the viewport to us - if (!m_isFixed) { - // turn our fields into a matrix. - // - // TODO: this should happen in the caller, and we should remove these - // fields from our subclass - SkMatrix matrix; - GLUtils::toSkMatrix(matrix, m_transform); - this->setMatrix(matrix); - } - - // now apply it to our children - int count = this->countChildren(); - for (int i = 0; i < count; i++) - this->getChild(i)->updatePositions(); -} - -void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix, - const FloatRect& clipping, float opacity) -{ - IntSize layerSize(getSize().width(), getSize().height()); - FloatPoint anchorPoint(getAnchorPoint().fX, getAnchorPoint().fY); - FloatPoint position(getPosition().fX, getPosition().fY); - float centerOffsetX = (0.5f - anchorPoint.x()) * layerSize.width(); - float centerOffsetY = (0.5f - anchorPoint.y()) * layerSize.height(); - float originX = anchorPoint.x() * layerSize.width(); - float originY = anchorPoint.y() * layerSize.height(); - TransformationMatrix localMatrix; - if (!m_isFixed) - localMatrix = parentMatrix; - localMatrix.translate3d(originX + position.x(), - originY + position.y(), - anchorPointZ()); - localMatrix.multLeft(m_transform); - localMatrix.translate3d(-originX, - -originY, - -anchorPointZ()); - - setDrawTransform(localMatrix); - m_zValue = TilesManager::instance()->shader()->zValue(drawTransform(), getSize().width(), getSize().height()); - - opacity *= getOpacity(); - setDrawOpacity(opacity); - - if (m_haveClip) { - // The clipping rect calculation and intersetion will be done in Screen Coord now. - FloatRect clip = - TilesManager::instance()->shader()->rectInScreenCoord(drawTransform(), layerSize); - clip.intersect(clipping); - setDrawClip(clip); - } else { - setDrawClip(clipping); - } - - if (!m_backfaceVisibility - && drawTransform().inverse().m33() < 0) { - setVisible(false); - return; - } else { - setVisible(true); - } - - int count = this->countChildren(); - if (!count) - return; - - // Flatten to 2D if the layer doesn't preserve 3D. - if (!preserves3D()) { - localMatrix.setM13(0); - localMatrix.setM23(0); - localMatrix.setM31(0); - localMatrix.setM32(0); - localMatrix.setM33(1); - localMatrix.setM34(0); - localMatrix.setM43(0); - } - - // now apply it to our children - - if (!m_childrenTransform.isIdentity()) { - localMatrix.translate(getSize().width() * 0.5f, getSize().height() * 0.5f); - localMatrix.multLeft(m_childrenTransform); - localMatrix.translate(-getSize().width() * 0.5f, -getSize().height() * 0.5f); - } - for (int i = 0; i < count; i++) - this->getChild(i)->updateGLPositions(localMatrix, drawClip(), opacity); -} - -void LayerAndroid::copyBitmap(SkBitmap* bitmap) -{ - if (!bitmap) - return; - - delete m_contentsImage; - m_contentsImage = new SkBitmap(); - SkBitmap::Config config = bitmap->config(); - int w = bitmap->width(); - int h = bitmap->height(); - m_contentsImage->setConfig(config, w, h); - bitmap->copyTo(m_contentsImage, config); -} - -void LayerAndroid::setContentsImage(SkBitmapRef* img) -{ - copyBitmap(&img->bitmap()); -} - -bool LayerAndroid::needsTexture() -{ - return m_contentsImage || (prepareContext() - && m_recordingPicture->width() && m_recordingPicture->height()); -} - -IntRect LayerAndroid::clippedRect() const -{ - IntRect r(0, 0, getWidth(), getHeight()); - IntRect tr = drawTransform().mapRect(r); - IntRect cr = TilesManager::instance()->shader()->clippedRectWithViewport(tr); - IntRect rect = drawTransform().inverse().mapRect(cr); - return rect; -} - -bool LayerAndroid::outsideViewport() -{ - return m_layerTextureRect.width() == 0 && - m_layerTextureRect.height() == 0; -} - -int LayerAndroid::fullTextureSize() const -{ - return getWidth() * m_scale * getHeight() * m_scale * 4; -} - -int LayerAndroid::clippedTextureSize() const -{ - IntRect cr = clippedRect(); - return cr.width() * cr.height() * 4; -} - -int LayerAndroid::countTextureSize() -{ - int size = clippedTextureSize(); - int count = this->countChildren(); - for (int i = 0; i < count; i++) - size += getChild(i)->countTextureSize(); - return size; -} - -int LayerAndroid::nbLayers() -{ - int nb = 1; - int count = this->countChildren(); - for (int i = 0; i < count; i++) - nb += getChild(i)->nbLayers(); - return nb; -} - -void LayerAndroid::collect(Vector<LayerAndroid*>& layers, int& size) -{ - m_layerTextureRect = clippedRect(); - if (!outsideViewport()) { - layers.append(this); - size += fullTextureSize(); - } - int count = this->countChildren(); - for (int i = 0; i < count; i++) - getChild(i)->collect(layers, size); -} - -static inline bool compareLayerFullSize(const LayerAndroid* a, const LayerAndroid* b) -{ - const int sizeA = a->fullTextureSize(); - const int sizeB = b->fullTextureSize(); - return sizeA > sizeB; -} - -void LayerAndroid::computeTextureSize(double time) -{ - if (m_lastComputeTextureSize + s_computeTextureDelay > time) - return; - m_lastComputeTextureSize = time; - - // First, we collect the layers, computing m_layerTextureRect - // as being clipped against the viewport - Vector <LayerAndroid*> layers; - int total = 0; - collect(layers, total); - - // Then we sort them by the size the full texture would need - std::stable_sort(layers.begin(), layers.end(), compareLayerFullSize); - - // Now, let's determinate which layer can use a full texture - int max = TilesManager::instance()->maxLayersAllocation(); - int maxLayerSize = TilesManager::instance()->maxLayerAllocation(); - XLOG("*** layers sorted by size ***"); - XLOG("total memory needed: %d bytes (%d Mb), max %d Mb", - total, total / 1024 / 1024, max / 1024 / 1024); - for (unsigned int i = 0; i < layers.size(); i++) { - LayerAndroid* layer = layers[i]; - bool clipped = true; - // If we are under the maximum, and the layer inspected - // needs a texture less than the maxLayerSize, use the full texture. - if ((total < max) && - (layer->fullTextureSize() < maxLayerSize) && - (layer->getWidth() * m_scale < TilesManager::instance()->getMaxTextureSize()) && - (layer->getHeight() * m_scale < TilesManager::instance()->getMaxTextureSize())) { - IntRect full(0, 0, layer->getWidth(), layer->getHeight()); - layer->m_layerTextureRect = full; - clipped = false; - } else { - // Otherwise, the layer is clipped; update the total - total -= layer->fullTextureSize(); - total += layer->clippedTextureSize(); - } - XLOG("Layer %d (%.2f, %.2f) %d bytes (clipped: %s)", - layer->uniqueId(), layer->getWidth(), layer->getHeight(), - layer->fullTextureSize(), - clipped ? "YES" : "NO"); - } - XLOG("total memory used after clipping: %d bytes (%d Mb), max %d Mb", - total, total / 1024 / 1024, max / 1024 / 1024); - XLOG("*** end of sorted layers ***"); -} - -void LayerAndroid::showLayers(int indent) -{ - IntRect cr = clippedRect(); - int size = cr.width() * cr.height() * 4; - - char space[256]; - int p = 0; - for (; p < indent; p++) - space[p] = ' '; - space[p] = '\0'; - - bool outside = outsideViewport(); - if (needsTexture() && !outside) { - XLOGC("%s Layer %d (%.2f, %.2f), cropped to (%d, %d, %d, %d), using %d Mb", - space, uniqueId(), getWidth(), getHeight(), - cr.x(), cr.y(), cr.width(), cr.height(), size / 1024 / 1024); - } else if (needsTexture() && outside) { - XLOGC("%s Layer %d is outside the viewport", space, uniqueId()); - } else { - XLOGC("%s Layer %d has no texture", space, uniqueId()); - } - - int count = this->countChildren(); - for (int i = 0; i < count; i++) - getChild(i)->showLayers(indent + 1); -} - -void LayerAndroid::reserveGLTextures() -{ - int count = this->countChildren(); - for (int i = 0; i < count; i++) - this->getChild(i)->reserveGLTextures(); - - if (!needsTexture()) - return; - - if (outsideViewport()) - return; - - LayerTexture* reservedTexture = 0; - reservedTexture = TilesManager::instance()->getExistingTextureForLayer( - this, m_layerTextureRect); - - // If we do not have a drawing texture (i.e. new LayerAndroid tree), - // we get any one available. - if (!m_drawingTexture) { - LayerTexture* texture = reservedTexture; - m_drawingTexture = - TilesManager::instance()->getExistingTextureForLayer( - this, m_layerTextureRect, true, texture); - - if (!m_drawingTexture) - m_drawingTexture = reservedTexture; - } - - // SMP flush - android::AutoMutex lock(m_atomicSync); - // we set the reservedTexture if it's different from the drawing texture - if (m_reservedTexture != reservedTexture && - ((reservedTexture != m_drawingTexture) || - (m_reservedTexture == 0 && m_drawingTexture == 0))) { - // Call release on the reserved texture if it is not the same as the - // drawing texture. - if (m_reservedTexture && (m_reservedTexture != m_drawingTexture)) - m_reservedTexture->release(this); - m_reservedTexture = reservedTexture; - } -} - -void LayerAndroid::createGLTextures() -{ - int count = this->countChildren(); - for (int i = 0; i < count; i++) - this->getChild(i)->createGLTextures(); - - if (!needsTexture()) - return; - - if (outsideViewport()) - return; - - if (m_drawingTexture && !needsScheduleRepaint(m_drawingTexture)) - return; - - LayerTexture* reservedTexture = m_reservedTexture; - if (!reservedTexture) - reservedTexture = TilesManager::instance()->createTextureForLayer(this, m_layerTextureRect); - - if (!reservedTexture) - return; - - // SMP flush - m_atomicSync.lock(); - m_reservedTexture = reservedTexture; - m_atomicSync.unlock(); - - if (reservedTexture && - reservedTexture->ready() && - (reservedTexture != m_drawingTexture)) { - if (m_drawingTexture) { - TilesManager::instance()->removeOperationsForTexture(m_drawingTexture); - m_drawingTexture->release(this); - } - m_drawingTexture = reservedTexture; - } - - if (!needsScheduleRepaint(reservedTexture)) - return; - - m_atomicSync.lock(); - if (!m_requestSent) { - m_requestSent = true; - m_atomicSync.unlock(); - XLOG("We schedule a paint for layer %d (%x), because m_dirty %d, using texture %x (%d, %d)", - uniqueId(), this, m_dirty, m_reservedTexture, - m_reservedTexture->rect().width(), m_reservedTexture->rect().height()); - PaintLayerOperation* operation = new PaintLayerOperation(this); - TilesManager::instance()->scheduleOperation(operation); - } else { - XLOG("We don't schedule a paint for layer %d (%x), because we already sent a request", - uniqueId(), this); - m_atomicSync.unlock(); - } -} - -bool LayerAndroid::needsScheduleRepaint(LayerTexture* texture) -{ - if (!texture) - return false; - - if (!texture->ready()) { - m_dirty = true; - return true; - } - - TextureInfo* textureInfo = texture->consumerLock(); - if (!texture->readyFor(this) || - (texture->rect() != m_layerTextureRect)) - m_dirty = true; - texture->consumerRelease(); - - return m_dirty; -} - -static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b) -{ - return a->zValue() > b->zValue(); -} - -bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) -{ - TilesManager::instance()->shader()->clip(m_clippingRect); - if (!m_visible) - return false; - - if (m_drawingTexture) { - TextureInfo* textureInfo = m_drawingTexture->consumerLock(); - bool ready = m_drawingTexture->readyFor(this); - if (textureInfo && (!m_contentsImage || (ready && m_contentsImage))) { - SkRect bounds; - bounds.set(m_drawingTexture->rect()); - XLOG("LayerAndroid %d %x (%.2f, %.2f) drawGL (texture %x, %d, %d, %d, %d)", - uniqueId(), this, getWidth(), getHeight(), - m_drawingTexture, bounds.x(), bounds.y(), - bounds.width(), bounds.height()); - //TODO determine when drawing if the alpha value is used. - TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), bounds, - textureInfo->m_textureId, - m_drawOpacity, true); - } - if (!ready) - m_dirty = true; - m_drawingTexture->consumerRelease(); - } else if (needsTexture()) { - m_dirty = true; - } - - // When the layer is dirty, the UI thread should be notified to redraw. - bool askPaint = drawChildrenGL(glWebViewState, matrix); - m_atomicSync.lock(); - askPaint |= m_dirty; - if ((m_dirty && needsTexture()) || m_hasRunningAnimations || drawTransform().hasPerspective()) - addDirtyArea(glWebViewState); - - m_atomicSync.unlock(); - return askPaint; -} - - -bool LayerAndroid::drawChildrenGL(GLWebViewState* glWebViewState, SkMatrix& matrix) -{ - bool askPaint = false; - int count = this->countChildren(); - if (count > 0) { - Vector <LayerAndroid*> sublayers; - for (int i = 0; i < count; i++) - sublayers.append(this->getChild(i)); - - // now we sort for the transparency - std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ); - for (int i = 0; i < count; i++) { - LayerAndroid* layer = sublayers[i]; - askPaint |= layer->drawGL(glWebViewState, matrix); - } - } - - return askPaint; -} - -void LayerAndroid::setScale(float scale) -{ - int count = this->countChildren(); - for (int i = 0; i < count; i++) - this->getChild(i)->setScale(scale); - - android::AutoMutex lock(m_atomicSync); - m_scale = scale; -} - -// This is called from the texture generation thread -void LayerAndroid::paintBitmapGL() -{ - // We acquire the values below atomically. This ensures that we are reading - // values correctly across cores. Further, once we have these values they - // can be updated by other threads without consequence. - m_atomicSync.lock(); - LayerTexture* texture = m_reservedTexture; - - if (!texture) { - m_atomicSync.unlock(); - XLOG("Layer %d doesn't have a texture!", uniqueId()); - return; - } - - XLOG("LayerAndroid %d paintBitmapGL, texture used %x (%d, %d)", uniqueId(), texture, - texture->rect().width(), texture->rect().height()); - - // We need to mark the texture as busy before relinquishing the lock - // -- so that TilesManager::cleanupLayersTextures() can check if the texture - // is used before trying to destroy it - // If LayerAndroid::removeTexture() is called before us, we'd have bailed - // out early as texture would have been null; if it is called after us, we'd - // have marked the texture has being busy, and the texture will not be - // destroyed immediately. - texture->producerAcquireContext(); - TextureInfo* textureInfo = texture->producerLock(); - m_atomicSync.unlock(); - - // at this point we can safely check the ownership (if the texture got - // transferred to another BaseTile under us) - if (texture->owner() != this) { - texture->producerRelease(); - return; - } - - XLOG("LayerAndroid %d %x (%.2f, %.2f) paintBitmapGL WE ARE PAINTING", uniqueId(), this, getWidth(), getHeight()); - SkCanvas* canvas = texture->canvas(); - float scale = texture->scale(); - - IntRect textureRect = texture->rect(); - canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode); - - if (m_contentsImage) { - contentDraw(canvas); - } else { - SkPicture picture; - SkCanvas* nCanvas = picture.beginRecording(textureRect.width(), - textureRect.height()); - nCanvas->scale(scale, scale); - nCanvas->translate(-textureRect.x(), -textureRect.y()); - contentDraw(nCanvas); - picture.endRecording(); - picture.draw(canvas); - } - extraDraw(canvas); - - m_atomicSync.lock(); - texture->setTextureInfoFor(this); - - m_dirty = false; - m_requestSent = false; - - XLOG("LayerAndroid %d paintBitmapGL PAINTING DONE, updating the texture", uniqueId()); - texture->producerUpdate(textureInfo); - - m_atomicSync.unlock(); - - XLOG("LayerAndroid %d paintBitmapGL UPDATING DONE", uniqueId()); -} - -void LayerAndroid::extraDraw(SkCanvas* canvas) -{ - m_atomicSync.lock(); - if (m_extra) - canvas->drawPicture(*m_extra); - m_atomicSync.unlock(); -} - -void LayerAndroid::contentDraw(SkCanvas* canvas) -{ - if (m_contentsImage) { - SkRect dest; - dest.set(0, 0, getSize().width(), getSize().height()); - canvas->drawBitmapRect(*m_contentsImage, 0, dest); - } else { - canvas->drawPicture(*m_recordingPicture); - } - - if (TilesManager::instance()->getShowVisualIndicator()) { - float w = getSize().width(); - float h = getSize().height(); - SkPaint paint; - paint.setARGB(128, 255, 0, 0); - canvas->drawLine(0, 0, w, h, paint); - canvas->drawLine(0, h, w, 0, paint); - paint.setARGB(128, 0, 255, 0); - canvas->drawLine(0, 0, 0, h, paint); - canvas->drawLine(0, h, w, h, paint); - canvas->drawLine(w, h, w, 0, paint); - canvas->drawLine(w, 0, 0, 0, paint); - - if (m_isFixed) { - SkPaint paint; - paint.setARGB(80, 255, 0, 0); - canvas->drawRect(m_fixedRect, paint); - } - } -} - -void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity) -{ - if (m_haveClip) { - SkRect r; - r.set(0, 0, getSize().width(), getSize().height()); - canvas->clipRect(r); - return; - } - - if (!prepareContext()) - return; - - // we just have this save/restore for opacity... - SkAutoCanvasRestore restore(canvas, true); - - int canvasOpacity = SkScalarRound(opacity * 255); - if (canvasOpacity < 255) - canvas->setDrawFilter(new OpacityDrawFilter(canvasOpacity)); - - contentDraw(canvas); -} - -SkPicture* LayerAndroid::recordContext() -{ - if (prepareContext(true)) - return m_recordingPicture; - return 0; -} - -bool LayerAndroid::prepareContext(bool force) -{ - if (masksToBounds()) - return false; - - if (force || !m_recordingPicture || - (m_recordingPicture && - ((m_recordingPicture->width() != (int) getSize().width()) || - (m_recordingPicture->height() != (int) getSize().height())))) { - SkSafeUnref(m_recordingPicture); - m_recordingPicture = new SkPicture(); - } - - return m_recordingPicture; -} - -SkRect LayerAndroid::subtractLayers(const SkRect& visibleRect) const -{ - SkRect result; - if (m_recordingPicture) { - SkRect globalRect = bounds(); - globalRect.offset(-getPosition()); // localToGlobal adds in position - SkMatrix globalMatrix; - localToGlobal(&globalMatrix); - globalMatrix.mapRect(&globalRect); - SkIRect roundedGlobal; - globalRect.round(&roundedGlobal); - SkIRect iVisibleRect; - visibleRect.round(&iVisibleRect); - SkRegion visRegion(iVisibleRect); - visRegion.op(roundedGlobal, SkRegion::kDifference_Op); - result.set(visRegion.getBounds()); -#if DEBUG_NAV_UI - SkDebugf("%s visibleRect=(%g,%g,r=%g,b=%g) globalRect=(%g,%g,r=%g,b=%g)" - "result=(%g,%g,r=%g,b=%g)", __FUNCTION__, - visibleRect.fLeft, visibleRect.fTop, - visibleRect.fRight, visibleRect.fBottom, - globalRect.fLeft, globalRect.fTop, - globalRect.fRight, globalRect.fBottom, - result.fLeft, result.fTop, result.fRight, result.fBottom); -#endif - } else - result = visibleRect; - for (int i = 0; i < countChildren(); i++) - result = getChild(i)->subtractLayers(result); - return result; -} - -// Debug tools : dump the layers tree in a file. -// The format is simple: -// properties have the form: key = value; -// all statements are finished with a semi-colon. -// value can be: -// - int -// - float -// - array of elements -// - composed type -// a composed type enclose properties in { and } -// an array enclose composed types in { }, separated with a comma. -// exemple: -// { -// x = 3; -// y = 4; -// value = { -// x = 3; -// y = 4; -// }; -// anarray = [ -// { x = 3; }, -// { y = 4; } -// ]; -// } - -void lwrite(FILE* file, const char* str) -{ - fwrite(str, sizeof(char), strlen(str), file); -} - -void writeIndent(FILE* file, int indentLevel) -{ - if (indentLevel) - fprintf(file, "%*s", indentLevel*2, " "); -} - -void writeln(FILE* file, int indentLevel, const char* str) -{ - writeIndent(file, indentLevel); - lwrite(file, str); - lwrite(file, "\n"); -} - -void writeIntVal(FILE* file, int indentLevel, const char* str, int value) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = %d;\n", str, value); -} - -void writeHexVal(FILE* file, int indentLevel, const char* str, int value) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = %x;\n", str, value); -} - -void writeFloatVal(FILE* file, int indentLevel, const char* str, float value) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = %.3f;\n", str, value); -} - -void writePoint(FILE* file, int indentLevel, const char* str, SkPoint point) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = { x = %.3f; y = %.3f; };\n", str, point.fX, point.fY); -} - -void writeSize(FILE* file, int indentLevel, const char* str, SkSize size) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = { w = %.3f; h = %.3f; };\n", str, size.width(), size.height()); -} - -void writeRect(FILE* file, int indentLevel, const char* str, SkRect rect) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = { x = %.3f; y = %.3f; w = %.3f; h = %.3f; };\n", - str, rect.fLeft, rect.fTop, rect.width(), rect.height()); -} - -void writeLength(FILE* file, int indentLevel, const char* str, SkLength length) -{ - if (!length.defined()) - return; - writeIndent(file, indentLevel); - fprintf(file, "%s = { type = %d; value = %.2f; };\n", str, length.type, length.value); -} - -void writeMatrix(FILE* file, int indentLevel, const char* str, const TransformationMatrix& matrix) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = { (%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f)," - "(%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f) };\n", - str, - matrix.m11(), matrix.m12(), matrix.m13(), matrix.m14(), - matrix.m21(), matrix.m22(), matrix.m23(), matrix.m24(), - matrix.m31(), matrix.m32(), matrix.m33(), matrix.m34(), - matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44()); -} - -void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const -{ - writeln(file, indentLevel, "{"); - - writeHexVal(file, indentLevel + 1, "layer", (int)this); - writeIntVal(file, indentLevel + 1, "layerId", m_uniqueId); - writeIntVal(file, indentLevel + 1, "haveClip", m_haveClip); - writeIntVal(file, indentLevel + 1, "isFixed", m_isFixed); - writeIntVal(file, indentLevel + 1, "m_isIframe", m_isIframe); - writePoint(file, indentLevel + 1, "m_iframeOffset", m_iframeOffset); - - writeFloatVal(file, indentLevel + 1, "opacity", getOpacity()); - writeSize(file, indentLevel + 1, "size", getSize()); - writePoint(file, indentLevel + 1, "position", getPosition()); - writePoint(file, indentLevel + 1, "anchor", getAnchorPoint()); - - writeMatrix(file, indentLevel + 1, "drawMatrix", drawTransform()); - writeMatrix(file, indentLevel + 1, "transformMatrix", m_transform); - - if (m_isFixed) { - writeLength(file, indentLevel + 1, "fixedLeft", m_fixedLeft); - writeLength(file, indentLevel + 1, "fixedTop", m_fixedTop); - writeLength(file, indentLevel + 1, "fixedRight", m_fixedRight); - writeLength(file, indentLevel + 1, "fixedBottom", m_fixedBottom); - writeLength(file, indentLevel + 1, "fixedMarginLeft", m_fixedMarginLeft); - writeLength(file, indentLevel + 1, "fixedMarginTop", m_fixedMarginTop); - writeLength(file, indentLevel + 1, "fixedMarginRight", m_fixedMarginRight); - writeLength(file, indentLevel + 1, "fixedMarginBottom", m_fixedMarginBottom); - writeRect(file, indentLevel + 1, "fixedRect", m_fixedRect); - } - - if (m_recordingPicture) { - writeIntVal(file, indentLevel + 1, "m_recordingPicture.width", m_recordingPicture->width()); - writeIntVal(file, indentLevel + 1, "m_recordingPicture.height", m_recordingPicture->height()); - } - - if (countChildren()) { - writeln(file, indentLevel + 1, "children = ["); - for (int i = 0; i < countChildren(); i++) { - if (i > 0) - writeln(file, indentLevel + 1, ", "); - getChild(i)->dumpLayers(file, indentLevel + 1); - } - writeln(file, indentLevel + 1, "];"); - } - writeln(file, indentLevel, "}"); -} - -void LayerAndroid::dumpToLog() const -{ - FILE* file = fopen("/data/data/com.android.browser/layertmp", "w"); - dumpLayers(file, 0); - fclose(file); - file = fopen("/data/data/com.android.browser/layertmp", "r"); - char buffer[512]; - bzero(buffer, sizeof(buffer)); - while (fgets(buffer, sizeof(buffer), file)) - SkDebugf("%s", buffer); - fclose(file); -} - -LayerAndroid* LayerAndroid::findById(int match) -{ - if (m_uniqueId == match) - return this; - for (int i = 0; i < countChildren(); i++) { - LayerAndroid* result = getChild(i)->findById(match); - if (result) - return result; - } - return 0; -} - -void LayerAndroid::setExtra(DrawExtra* extra) -{ - for (int i = 0; i < countChildren(); i++) - getChild(i)->setExtra(extra); - - android::AutoMutex lock(m_atomicSync); - if (extra || (m_extra && !extra)) - m_dirty = true; - - delete m_extra; - m_extra = 0; - - if (!extra) - return; - - if (m_recordingPicture) { - IntRect dummy; // inval area, unused for now - m_extra = new SkPicture(); - SkCanvas* canvas = m_extra->beginRecording(m_recordingPicture->width(), - m_recordingPicture->height()); - extra->draw(canvas, this, &dummy); - m_extra->endRecording(); - } -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h deleted file mode 100644 index d4510c5..0000000 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LayerAndroid_h -#define LayerAndroid_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "FloatPoint.h" -#include "FloatPoint3D.h" -#include "FloatRect.h" -#include "GraphicsLayerClient.h" -#include "LayerTexture.h" -#include "RefPtr.h" -#include "SkColor.h" -#include "SkLayer.h" -#include "TextureOwner.h" -#include "TransformationMatrix.h" - -#include <wtf/HashMap.h> -#include <wtf/text/StringHash.h> - -#ifndef BZERO_DEFINED -#define BZERO_DEFINED -// http://www.opengroup.org/onlinepubs/000095399/functions/bzero.html -// For maximum portability, it is recommended to replace the function call to bzero() as follows: -#define bzero(b, len) (memset((b), '\0', (len)), (void) 0) -#endif - -class SkBitmapRef; -class SkCanvas; -class SkMatrix; -class SkPicture; - -namespace android { -class DrawExtra; -} - -using namespace android; - -struct SkLength { - enum SkLengthType { Undefined, Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic }; - SkLengthType type; - SkScalar value; - SkLength() - { - type = Undefined; - value = 0; - } - bool defined() const - { - if (type == Undefined) - return false; - return true; - } - float calcFloatValue(float max) const - { - switch (type) { - case Percent: - return (max * value) / 100.0f; - case Fixed: - return value; - default: - return value; - } - } -}; - -namespace WebCore { - -class AndroidAnimation; -class BackedDoubleBufferedTexture; -class LayerAndroidFindState; -class RenderLayer; -class TiledPage; - -class LayerAndroid : public SkLayer, public TextureOwner { - -public: - LayerAndroid(RenderLayer* owner); - LayerAndroid(const LayerAndroid& layer); - LayerAndroid(SkPicture*); - virtual ~LayerAndroid(); - - // TextureOwner methods - virtual bool removeTexture(BackedDoubleBufferedTexture* texture); - - LayerTexture* texture() { return m_reservedTexture; } - virtual TiledPage* page() { return 0; } - - void setBackfaceVisibility(bool value) { m_backfaceVisibility = value; } - void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; } - FloatPoint translation() const; - SkRect bounds() const; - IntRect clippedRect() const; - bool outsideViewport(); - - // Debug/info functions - int countTextureSize(); - int nbLayers(); - void showLayers(int indent = 0); - - // Texture size functions - void computeTextureSize(double time); - void collect(Vector<LayerAndroid*>& layers, - int& size); - int clippedTextureSize() const; - int fullTextureSize() const; - - // called on the root layer - void reserveGLTextures(); - void createGLTextures(); - - virtual bool needsTexture(); - bool needsScheduleRepaint(LayerTexture* texture); - - void setScale(float scale); - float getScale() { return m_scale; } - virtual bool drawGL(GLWebViewState*, SkMatrix&); - bool drawChildrenGL(GLWebViewState*, SkMatrix&); - virtual void paintBitmapGL(); - void updateGLPositions(const TransformationMatrix& parentMatrix, - const FloatRect& clip, float opacity); - void setDrawOpacity(float opacity) { m_drawOpacity = opacity; } - void setVisible(bool value) { m_visible = value; } - - bool preserves3D() { return m_preserves3D; } - void setPreserves3D(bool value) { m_preserves3D = value; } - void setAnchorPointZ(float z) { m_anchorPointZ = z; } - float anchorPointZ() { return m_anchorPointZ; } - void setDrawTransform(const TransformationMatrix& transform) { m_drawTransform = transform; } - const TransformationMatrix& drawTransform() const { return m_drawTransform; } - void setChildrenTransform(const TransformationMatrix& t) { m_childrenTransform = t; } - void setDrawClip(const FloatRect& rect) { m_clippingRect = rect; } - const FloatRect& drawClip() { return m_clippingRect; } - - void setFixedPosition(SkLength left, // CSS left property - SkLength top, // CSS top property - SkLength right, // CSS right property - SkLength bottom, // CSS bottom property - SkLength marginLeft, // CSS margin-left property - SkLength marginTop, // CSS margin-top property - SkLength marginRight, // CSS margin-right property - SkLength marginBottom, // CSS margin-bottom property - const IntPoint& renderLayerPos, // For undefined fixed position - SkRect viewRect) { // view rect, can be smaller than the layer's - m_fixedLeft = left; - m_fixedTop = top; - m_fixedRight = right; - m_fixedBottom = bottom; - m_fixedMarginLeft = marginLeft; - m_fixedMarginTop = marginTop; - m_fixedMarginRight = marginRight; - m_fixedMarginBottom = marginBottom; - m_fixedRect = viewRect; - m_isFixed = true; - m_renderLayerPos = renderLayerPos; - setInheritFromRootTransform(true); - } - - void setBackgroundColor(SkColor color); - void setMaskLayer(LayerAndroid*); - void setMasksToBounds(bool masksToBounds) - { - m_haveClip = masksToBounds; - } - bool masksToBounds() const { return m_haveClip; } - - SkPicture* recordContext(); - - void addAnimation(PassRefPtr<AndroidAnimation> anim); - void removeAnimationsForProperty(AnimatedPropertyID property); - void removeAnimationsForKeyframes(const String& name); - bool evaluateAnimations(); - bool evaluateAnimations(double time); - bool hasAnimations() const; - void addDirtyArea(GLWebViewState*); - - SkPicture* picture() const { return m_recordingPicture; } - - // remove layers bounds from visible rectangle to show what can be - // scrolled into view; returns original minus layer bounds in global space. - SkRect subtractLayers(const SkRect& visibleRect) const; - - void dumpLayers(FILE*, int indentLevel) const; - void dumpToLog() const; - - /** Call this with the current viewport (scrolling, zoom) to update - the position of the fixed layers. - - This call is recursive, so it should be called on the root of the - hierarchy. - */ - void updateFixedLayersPositions(SkRect viewPort, LayerAndroid* parentIframeLayer = 0); - - /** Call this to update the position attribute, so that later calls - like bounds() will report the corrected position. - - This call is recursive, so it should be called on the root of the - hierarchy. - */ - void updatePositions(); - - void clipArea(SkTDArray<SkRect>* region) const; - const LayerAndroid* find(int* xPtr, int* yPtr, SkPicture* root) const; - const LayerAndroid* findById(int uniqueID) const - { - return const_cast<LayerAndroid*>(this)->findById(uniqueID); - } - LayerAndroid* findById(int uniqueID); - LayerAndroid* getChild(int index) const - { - return static_cast<LayerAndroid*>(this->INHERITED::getChild(index)); - } - void setExtra(DrawExtra* extra); // does not assign ownership - int uniqueId() const { return m_uniqueId; } - bool isFixed() { return m_isFixed; } - - /** This sets a content image -- calling it means we will use - the image directly when drawing the layer instead of using - the content painted by WebKit. See comments below for - m_recordingPicture and m_contentsImage. - */ - void setContentsImage(SkBitmapRef* img); - bool hasContentsImage() { return m_contentsImage; } - void copyBitmap(SkBitmap*); - - void bounds(SkRect*) const; - - virtual bool contentIsScrollable() const { return false; } - virtual LayerAndroid* copy() const { return new LayerAndroid(*this); } - - void needsRepaint() { m_pictureUsed++; } - unsigned int pictureUsed() { return m_pictureUsed; } - void contentDraw(SkCanvas*); - void extraDraw(SkCanvas*); - - virtual bool isMedia() const { return false; } - virtual bool isVideo() const { return false; } - - RenderLayer* owningLayer() const { return m_owningLayer; } - - void setIsIframe(bool isIframe) { m_isIframe = isIframe; } - float zValue() const { return m_zValue; } - -protected: - virtual void onDraw(SkCanvas*, SkScalar opacity); - -private: - class FindState; -#if DUMP_NAV_CACHE - friend class CachedLayer::Debug; // debugging access only -#endif - - void findInner(FindState&) const; - bool prepareContext(bool force = false); - void clipInner(SkTDArray<SkRect>* region, const SkRect& local) const; - - bool m_haveClip; - bool m_isFixed; - bool m_backgroundColorSet; - bool m_isIframe; - - SkLength m_fixedLeft; - SkLength m_fixedTop; - SkLength m_fixedRight; - SkLength m_fixedBottom; - SkLength m_fixedMarginLeft; - SkLength m_fixedMarginTop; - SkLength m_fixedMarginRight; - SkLength m_fixedMarginBottom; - SkRect m_fixedRect; - - SkPoint m_iframeOffset; - // When fixed element is undefined or auto, the render layer's position - // is needed for offset computation - IntPoint m_renderLayerPos; - - TransformationMatrix m_transform; - float m_zValue; - bool m_backfaceVisibility; - bool m_visible; - - SkColor m_backgroundColor; - - bool m_preserves3D; - float m_anchorPointZ; - float m_drawOpacity; - TransformationMatrix m_drawTransform; - TransformationMatrix m_childrenTransform; - FloatRect m_clippingRect; - - // Note that m_recordingPicture and m_contentsImage are mutually exclusive; - // m_recordingPicture is used when WebKit is asked to paint the layer's - // content, while m_contentsImage contains an image that we directly - // composite, using the layer's dimensions as a destination rect. - // We do this as if the layer only contains an image, directly compositing - // it is a much faster method than using m_recordingPicture. - SkPicture* m_recordingPicture; - - SkBitmap* m_contentsImage; - - typedef HashMap<pair<String, int>, RefPtr<AndroidAnimation> > KeyframesMap; - KeyframesMap m_animations; - SkPicture* m_extra; - int m_uniqueId; - - // We have two textures pointers -- one if the texture we are currently - // using to draw (m_drawingTexture), the other one is the one we get - // from trying to reserve a texture from the TilesManager. Usually, they - // are identical, but in some cases they are not (different scaling - // resulting in the need for different geometry, at initilisation, and - // if the texture asked does not fit in memory) - LayerTexture* m_drawingTexture; - LayerTexture* m_reservedTexture; - - // rect used to query TilesManager for the right texture - IntRect m_layerTextureRect; - - // used to signal that the tile is out-of-date and needs to be redrawn - bool m_dirty; - unsigned int m_pictureUsed; - - // used to signal the framework we need a repaint - bool m_hasRunningAnimations; - - // painting request sent - bool m_requestSent; - - float m_scale; - - // We try to not always compute the texture size, as this is quite heavy - static const double s_computeTextureDelay = 0.2; // 200 ms - double m_lastComputeTextureSize; - - // This mutex serves two purposes. (1) It ensures that certain operations - // happen atomically and (2) it makes sure those operations are synchronized - // across all threads and cores. - android::Mutex m_atomicSync; - - RenderLayer* m_owningLayer; - - typedef SkLayer INHERITED; -}; - -} - -#else - -class SkPicture; - -namespace WebCore { - -class LayerAndroid { -public: - LayerAndroid(SkPicture* picture) : - m_recordingPicture(picture), // does not assign ownership - m_uniqueId(-1) - {} - SkPicture* picture() const { return m_recordingPicture; } - int uniqueId() const { return m_uniqueId; } -private: - SkPicture* m_recordingPicture; - int m_uniqueId; -}; - -} - -#endif // USE(ACCELERATED_COMPOSITING) - -#endif // LayerAndroid_h diff --git a/WebCore/platform/graphics/android/LayerTexture.cpp b/WebCore/platform/graphics/android/LayerTexture.cpp deleted file mode 100644 index f311f32..0000000 --- a/WebCore/platform/graphics/android/LayerTexture.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2011, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "LayerTexture.h" - -#include "LayerAndroid.h" - -namespace WebCore { - -unsigned int LayerTexture::pictureUsed() -{ - consumerLock(); - TextureTileInfo* info = m_texturesInfo.get(getReadableTexture()); - unsigned int pictureUsed = 0; - if (info) - pictureUsed = info->m_picture; - consumerRelease(); - return pictureUsed; -} - -void LayerTexture::setTextureInfoFor(LayerAndroid* layer) -{ - TextureTileInfo* textureInfo = m_texturesInfo.get(getWriteableTexture()); - if (!textureInfo) { - textureInfo = new TextureTileInfo(); - } - textureInfo->m_layerId = layer->uniqueId(); - textureInfo->m_picture = layer->pictureUsed(); - textureInfo->m_scale = layer->getScale(); - m_texturesInfo.set(getWriteableTexture(), textureInfo); - m_layerId = layer->uniqueId(); - m_scale = layer->getScale(); - if (!m_ready) - m_ready = true; -} - -bool LayerTexture::readyFor(LayerAndroid* layer) -{ - TextureTileInfo* info = m_texturesInfo.get(getReadableTexture()); - if (info && - info->m_layerId == layer->uniqueId() && - info->m_scale == layer->getScale() && - info->m_picture == layer->pictureUsed()) - return true; - return false; -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/android/LayerTexture.h b/WebCore/platform/graphics/android/LayerTexture.h deleted file mode 100644 index be3594f..0000000 --- a/WebCore/platform/graphics/android/LayerTexture.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 LayerTexture_h -#define LayerTexture_h - -#include "BackedDoubleBufferedTexture.h" -#include "ClassTracker.h" -#include "IntRect.h" - -namespace WebCore { - -class LayerTexture : public BackedDoubleBufferedTexture { - public: - LayerTexture(uint32_t w, uint32_t h, - SkBitmap::Config config = SkBitmap::kARGB_8888_Config) - : BackedDoubleBufferedTexture(w, h, 0, config) - , m_layerId(0) - , m_scale(1) - , m_ready(false) - { -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("LayerTexture"); -#endif - } - virtual ~LayerTexture() - { -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("LayerTexture"); -#endif - }; - - void setTextureInfoFor(LayerAndroid* layer); - bool readyFor(LayerAndroid* layer); - void setRect(const IntRect& r) { m_rect = r; } - IntRect& rect() { return m_rect; } - int id() { return m_layerId; } - float scale() { return m_scale; } - void setId(int id) { m_layerId = id; } - void setScale(float scale) { m_scale = scale; } - bool ready() { return m_ready; } - unsigned int pictureUsed(); - - private: - - IntRect m_rect; - int m_layerId; - float m_scale; - bool m_ready; -}; - -} // namespace WebCore - -#endif // LayerTexture_h diff --git a/WebCore/platform/graphics/android/MediaLayer.cpp b/WebCore/platform/graphics/android/MediaLayer.cpp deleted file mode 100644 index 1ba6d46..0000000 --- a/WebCore/platform/graphics/android/MediaLayer.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "config.h" -#include "MediaLayer.h" -#include "MediaTexture.h" -#include "TilesManager.h" - -#if USE(ACCELERATED_COMPOSITING) - -#define LAYER_DEBUG -#undef LAYER_DEBUG - -#ifdef DEBUG - -#include <cutils/log.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "MediaLayer", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -namespace WebCore { - -MediaLayer::MediaLayer(jobject weakWebViewRef) : LayerAndroid((RenderLayer*) NULL) -{ - m_bufferedTexture = new MediaTexture(EGL_NO_CONTEXT); - m_bufferedTexture->producerInc(); - m_videoTexture = new VideoTexture(weakWebViewRef); - m_videoTexture->incStrong(this); - - m_isCopy = false; - m_currentTextureInfo = 0; - m_isContentInverted = false; - m_outlineSize = 0; - XLOG("Creating Media Layer %p", this); - XLOG("producer: %d consumer: %d", m_bufferedTexture->getProducerCount(), - m_bufferedTexture->getConsumerCount()); -} - -MediaLayer::MediaLayer(const MediaLayer& layer) : LayerAndroid(layer) -{ - m_bufferedTexture = layer.getTexture(); - m_bufferedTexture->consumerInc(); - m_videoTexture = layer.m_videoTexture; - m_videoTexture->incStrong(this); - - m_isCopy = true; - m_currentTextureInfo = 0; - m_isContentInverted = layer.m_isContentInverted; - m_outlineSize = layer.m_outlineSize; - XLOG("Creating Media Layer Copy %p -> %p", &layer, this); - XLOG("producer: %d consumer: %d COPY", m_bufferedTexture->getProducerCount(), - m_bufferedTexture->getConsumerCount()); -} - -MediaLayer::~MediaLayer() -{ - XLOG("Deleting Media Layer"); - XLOG("producer: %d consumer: %d %s", m_bufferedTexture->getProducerCount(), - m_bufferedTexture->getConsumerCount(), (m_isCopy) ? "COPY" : ""); - - if (m_isCopy) - m_bufferedTexture->consumerDec(); - else - m_bufferedTexture->producerDec(); - m_videoTexture->decStrong(this); -} - -bool MediaLayer::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) -{ - TilesManager::instance()->shader()->clip(drawClip()); - - // when the plugin gains focus webkit applies an outline to the - // widget, which causes the layer to expand to accommodate the - // outline. Therefore, we shrink the rect by the outline's dimensions - // to ensure the plugin does not draw outside of its bounds. - SkRect mediaBounds; - mediaBounds.set(0, 0, getSize().width(), getSize().height()); - mediaBounds.inset(m_outlineSize, m_outlineSize); - - // check to see if we need to create a video texture - m_videoTexture->initNativeWindowIfNeeded(); - // draw any video content if present - m_videoTexture->drawVideo(drawTransform(), mediaBounds); - - // draw the primary content - if (m_bufferedTexture) { - TextureInfo* textureInfo = m_bufferedTexture->consumerLock(); - if (textureInfo && textureInfo->m_width != 0 && textureInfo->m_height != 0) { - // the layer's shader draws the content inverted so we must undo - // that change in the transformation matrix - TransformationMatrix m = drawTransform(); - if (!m_isContentInverted) { - m.flipY(); - m.translate(0, -getSize().height()); - } - - bool forceBlending = textureInfo->m_internalFormat == GL_RGBA || - textureInfo->m_internalFormat == GL_BGRA_EXT || - textureInfo->m_internalFormat == GL_ALPHA; - TilesManager::instance()->shader()->drawLayerQuad(m, mediaBounds, - textureInfo->m_textureId, - 1.0f, forceBlending); - } - m_bufferedTexture->consumerRelease(); - } - - return drawChildrenGL(glWebViewState, matrix); -} - -ANativeWindow* MediaLayer::acquireNativeWindowForVideo() -{ - return m_videoTexture->requestNewWindow(); -} - -void MediaLayer::setWindowDimensionsForVideo(const ANativeWindow* window, const SkRect& dimensions) -{ - if (window != m_videoTexture->getNativeWindow()) - return; - - //TODO validate that the dimensions do not exceed the plugin's bounds - m_videoTexture->setDimensions(dimensions); -} - -void MediaLayer::releaseNativeWindowForVideo(ANativeWindow* window) -{ - if (window == m_videoTexture->getNativeWindow()) - m_videoTexture->releaseNativeWindow(); -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/MediaLayer.h b/WebCore/platform/graphics/android/MediaLayer.h deleted file mode 100644 index 8a07134..0000000 --- a/WebCore/platform/graphics/android/MediaLayer.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MediaLayer_h -#define MediaLayer_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "MediaTexture.h" -#include "LayerAndroid.h" -#include <jni.h> - -namespace android { - class SurfaceTexture; -} - -namespace WebCore { - -class MediaLayer : public LayerAndroid { - -public: - MediaLayer(jobject weakWebViewRef); - MediaLayer(const MediaLayer& layer); - virtual ~MediaLayer(); - - virtual bool drawGL(GLWebViewState*, SkMatrix&); - virtual void paintBitmapGL() const { }; - virtual bool needsTexture() { return false; } - - virtual bool isMedia() const { return true; } - virtual LayerAndroid* copy() const { return new MediaLayer(*this); } - - MediaTexture* getTexture() const { return m_bufferedTexture; } - - void setCurrentTextureInfo(TextureInfo* info) { m_currentTextureInfo = info; } - TextureInfo* getCurrentTextureInfo() const { return m_currentTextureInfo; } - - void invertContents(bool invertContent) { m_isContentInverted = invertContent; } - void setOutlineSize(int size) { m_outlineSize = size; } - - // functions to manipulate secondary layers for video playback - ANativeWindow* acquireNativeWindowForVideo(); - void setWindowDimensionsForVideo(const ANativeWindow* window, const SkRect& dimensions); - void releaseNativeWindowForVideo(ANativeWindow* window); - -private: - bool m_isCopy; - - // Primary GL texture variables - MediaTexture* m_bufferedTexture; - TextureInfo* m_currentTextureInfo; - - bool m_isContentInverted; - int m_outlineSize; - - // Video texture variables - VideoTexture* m_videoTexture; -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) - -#endif // MediaLayer_h diff --git a/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h b/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h deleted file mode 100644 index 404ef08..0000000 --- a/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2009,2010 The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 MediaPlayerPrivateAndroid_h -#define MediaPlayerPrivateAndroid_h - -#if ENABLE(VIDEO) - -class SkBitmap; - -#include "MediaPlayerPrivate.h" -#include "TimeRanges.h" -#include "VideoLayerAndroid.h" - -namespace WebCore { - -class MediaPlayerPrivate : public MediaPlayerPrivateInterface { -public: - virtual ~MediaPlayerPrivate(); - - static void registerMediaEngine(MediaEngineRegistrar); - - virtual void load(const String& url) = 0; - virtual void cancelLoad() { } - - virtual void play() = 0; - virtual void pause(); - - virtual IntSize naturalSize() const { return m_naturalSize; } - - virtual bool supportsFullscreen() const = 0; - virtual bool hasAudio() const = 0; - virtual bool hasVideo() const = 0; - - virtual void setVisible(bool); - - virtual float duration() const { return m_duration; } - - virtual float currentTime() const { return m_currentTime; }; - virtual void seek(float time); - virtual bool seeking() const { return false; } - - virtual void setEndTime(float time) { } - - virtual void setRate(float) { } - virtual bool paused() const { return m_paused; } - - virtual void setVolume(float) { } - - virtual MediaPlayer::NetworkState networkState() const { return m_networkState; } - virtual MediaPlayer::ReadyState readyState() const { return m_readyState; } - - virtual float maxTimeSeekable() const { return 0; } - virtual PassRefPtr<TimeRanges> buffered() const { return TimeRanges::create(); } - - virtual int dataRate() const { return 0; } - - virtual bool totalBytesKnown() const { return totalBytes() > 0; } - virtual unsigned totalBytes() const { return 0; } - virtual unsigned bytesLoaded() const { return 0; } - - virtual void setSize(const IntSize&) { } - - virtual bool canLoadPoster() const { return false; } - virtual void setPoster(const String&) { } - virtual void prepareToPlay(); - - virtual void paint(GraphicsContext*, const IntRect&) { } - - virtual void onPrepared(int duration, int width, int height) { } - void onEnded(); - void onPaused(); - virtual void onPosterFetched(SkBitmap*) { } - void onBuffering(int percent); - void onTimeupdate(int position); - - // These following two functions are used to turn on inline video support - bool supportsAcceleratedRendering() const { return true; } - LayerAndroid* platformLayer() const - { - return m_videoLayer; - } - void onStopFullscreen(); - -protected: - // Android-specific methods and fields. - static MediaPlayerPrivateInterface* create(MediaPlayer* player); - static void getSupportedTypes(HashSet<String>&) { } - static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs); - - MediaPlayerPrivate(MediaPlayer *); - virtual void createJavaPlayerIfNeeded() { } - - MediaPlayer* m_player; - String m_url; - struct JavaGlue; - JavaGlue* m_glue; - - float m_duration; - float m_currentTime; - - bool m_paused; - MediaPlayer::ReadyState m_readyState; - MediaPlayer::NetworkState m_networkState; - - SkBitmap* m_poster; // not owned - String m_posterUrl; - - IntSize m_naturalSize; - bool m_naturalSizeUnknown; - - bool m_isVisible; - VideoLayerAndroid* m_videoLayer; -}; - -} // namespace WebCore - -#endif - -#endif // MediaPlayerPrivateAndroid_h diff --git a/WebCore/platform/graphics/android/MediaTexture.cpp b/WebCore/platform/graphics/android/MediaTexture.cpp deleted file mode 100644 index 14f0c20..0000000 --- a/WebCore/platform/graphics/android/MediaTexture.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "config.h" -#include "MediaTexture.h" -#include "TilesManager.h" -#include "GLUtils.h" -#include "VideoListener.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include <android/native_window.h> -#include <gui/SurfaceTexture.h> -#include <gui/SurfaceTextureClient.h> -#include <wtf/CurrentTime.h> -#include <JNIUtility.h> -#include "WebCoreJni.h" - -#define LAYER_DEBUG -#undef LAYER_DEBUG - -#ifdef DEBUG - -#include <cutils/log.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "MediaTexture", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -namespace WebCore { - -MediaTexture::MediaTexture(EGLContext sharedContext) : DoubleBufferedTexture(sharedContext) -{ - m_producerRefCount = 0; - m_consumerRefCount = 0; -} - -/* Increment the number of objects in the producer's thread that hold a reference - * to this object. In practice, there is often only one producer reference for - * the lifetime of the object. - */ -void MediaTexture::producerInc() -{ - android::Mutex::Autolock lock(m_mediaLock); - m_producerRefCount++; -} - -/* Decrement the number of objects in the producer's thread that are holding a - * reference to this object. When removing the last reference we must cleanup - * all GL objects that are associated with the producer's thread. There may not - * be a consumer reference as the object may not have synced to the UI thread, - * in which case the producer needs to handle the deletion of the object. - */ -void MediaTexture::producerDec() -{ - bool needsDeleted = false; - - m_mediaLock.lock(); - m_producerRefCount--; - if (m_producerRefCount == 0) { - producerDeleteTextures(); - if (m_consumerRefCount < 1) { - XLOG("INFO: This texture has not been synced to the UI thread"); - needsDeleted = true; - } - } - m_mediaLock.unlock(); - - if (needsDeleted) { - XLOG("Deleting MediaTexture Object"); - delete this; - } -} - -/* Increment the number of objects in the consumer's thread that hold a reference - * to this object. In practice, there can be multiple producer references as the - * consumer (i.e. UI) thread may have multiple copies of the layer tree. - */ -void MediaTexture::consumerInc() -{ - android::Mutex::Autolock lock(m_mediaLock); - m_consumerRefCount++; -} - -/* Decrement the number of objects in the consumer's thread that are holding a - * reference to this object. When removing the last reference we must delete - * this object and by extension cleanup all GL objects that are associated with - * the consumer's thread. At the time of deletion if there is a remaining - * producer reference we must cleanup the consumer GL objects in the event that - * this texture will not be re-synced with the UI thread. - */ -void MediaTexture::consumerDec() -{ - bool needsDeleted = false; - - m_mediaLock.lock(); - m_consumerRefCount--; - if (m_consumerRefCount == 0) { - consumerDeleteTextures(); - if (m_producerRefCount < 1) { - XLOG("WARNING: This texture still exists within webkit."); - needsDeleted = true; - } - } - m_mediaLock.unlock(); - - if (needsDeleted) { - XLOG("Deleting MediaTexture Object"); - delete this; - } -} - -VideoTexture::VideoTexture(jobject weakWebViewRef) : android::LightRefBase<VideoTexture>() -{ - m_weakWebViewRef = weakWebViewRef; - m_textureId = 0; - m_dimensions.setEmpty(); - m_newWindowRequest = false; - m_newWindowReady = false; - m_videoListener = new VideoListener(m_weakWebViewRef); -} - -VideoTexture::~VideoTexture() -{ - releaseNativeWindow(); - if (m_textureId) - glDeleteTextures(1, &m_textureId); - if (m_weakWebViewRef) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - env->DeleteWeakGlobalRef(m_weakWebViewRef); - } -} - -void VideoTexture::initNativeWindowIfNeeded() -{ - { - android::Mutex::Autolock lock(m_videoLock); - - if(!m_newWindowRequest) - return; - - // reuse an existing texture if possible - if (!m_textureId) - glGenTextures(1, &m_textureId); - - m_surfaceTexture = new android::SurfaceTexture(m_textureId); - m_surfaceTextureClient = new android::SurfaceTextureClient(m_surfaceTexture); - - //setup callback - m_videoListener->resetFrameAvailable(); - m_surfaceTexture->setFrameAvailableListener(m_videoListener); - - m_newWindowRequest = false; - m_newWindowReady = true; - } - m_newVideoRequestCond.signal(); -} - -void VideoTexture::drawVideo(const TransformationMatrix& matrix, const SkRect& parentBounds) -{ - android::Mutex::Autolock lock(m_videoLock); - - if(!m_surfaceTexture.get() || m_dimensions.isEmpty() - || !m_videoListener->isFrameAvailable()) - return; - - m_surfaceTexture->updateTexImage(); - - float surfaceMatrix[16]; - m_surfaceTexture->getTransformMatrix(surfaceMatrix); - - SkRect dimensions = m_dimensions; - dimensions.offset(parentBounds.fLeft, parentBounds.fTop); - -#ifdef DEBUG - if (!parentBounds.contains(dimensions)) { - XLOG("The video exceeds is parent's bounds."); - } -#endif // DEBUG - - TilesManager::instance()->shader()->drawVideoLayerQuad(matrix, surfaceMatrix, - dimensions, m_textureId); -} - -ANativeWindow* VideoTexture::requestNewWindow() -{ - android::Mutex::Autolock lock(m_videoLock); - - // the window was not ready before the timeout so return it this time - if (m_newWindowReady) { - m_newWindowReady = false; - return m_surfaceTextureClient.get(); - } - // we only allow for one texture, so if one already exists return null - else if (m_surfaceTextureClient.get()) { - return 0; - } - - m_newWindowRequest = true; - - // post an inval message to the UI thread to fulfill the request - if (m_weakWebViewRef) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobject localWebViewRef = env->NewLocalRef(m_weakWebViewRef); - if (localWebViewRef) { - jclass wvClass = env->GetObjectClass(localWebViewRef); - jmethodID postInvalMethod = env->GetMethodID(wvClass, "postInvalidate", "()V"); - env->CallVoidMethod(localWebViewRef, postInvalMethod); - env->DeleteLocalRef(wvClass); - env->DeleteLocalRef(localWebViewRef); - } - checkException(env); - } - - //block until the request can be fulfilled or we time out - bool timedOut = false; - while (m_newWindowRequest && !timedOut) { - int ret = m_newVideoRequestCond.waitRelative(m_videoLock, 500000000); // .5 sec - timedOut = ret == TIMED_OUT; - } - - if (m_surfaceTextureClient.get()) - m_newWindowReady = false; - - return m_surfaceTextureClient.get(); -} - -ANativeWindow* VideoTexture::getNativeWindow() -{ - android::Mutex::Autolock lock(m_videoLock); - return m_surfaceTextureClient.get(); -} - -void VideoTexture::releaseNativeWindow() -{ - android::Mutex::Autolock lock(m_videoLock); - m_dimensions.setEmpty(); - - if (m_surfaceTexture.get()) - m_surfaceTexture->setFrameAvailableListener(0); - - // clear the strong pointer references - m_surfaceTextureClient.clear(); - m_surfaceTexture.clear(); -} - -void VideoTexture::setDimensions(const SkRect& dimensions) -{ - android::Mutex::Autolock lock(m_videoLock); - m_dimensions = dimensions; -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/MediaTexture.h b/WebCore/platform/graphics/android/MediaTexture.h deleted file mode 100644 index 722afd8..0000000 --- a/WebCore/platform/graphics/android/MediaTexture.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MediaTexture_h -#define MediaTexture_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "RefPtr.h" -#include "DoubleBufferedTexture.h" -#include "LayerAndroid.h" -#include <utils/RefBase.h> -#include <jni.h> - -namespace android { - class SurfaceTexture; -} - -namespace WebCore { - -class VideoListener; - -class MediaTexture : public DoubleBufferedTexture { - -public: - MediaTexture(EGLContext sharedContext); - - void producerInc(); - void producerDec(); - void consumerInc(); - void consumerDec(); - - int getProducerCount() { android::Mutex::Autolock lock(m_mediaLock); return m_producerRefCount; } - int getConsumerCount() { android::Mutex::Autolock lock(m_mediaLock); return m_consumerRefCount; } - -private: - android::Mutex m_mediaLock; - int m_producerRefCount; - int m_consumerRefCount; -}; - -class VideoTexture : public android::LightRefBase<VideoTexture> { - -public: - VideoTexture(jobject weakWebViewRef); - ~VideoTexture(); - - void initNativeWindowIfNeeded(); - void drawVideo(const TransformationMatrix& matrix, const SkRect& parentBounds); - - ANativeWindow* requestNewWindow(); - ANativeWindow* getNativeWindow(); - void releaseNativeWindow(); - void setDimensions(const SkRect& dimensions); - - -private: - GLuint m_textureId; - sp<android::SurfaceTexture> m_surfaceTexture; - sp<ANativeWindow> m_surfaceTextureClient; - sp<VideoListener> m_videoListener; - SkRect m_dimensions; - bool m_newWindowRequest; - bool m_newWindowReady; - - jobject m_weakWebViewRef; - - android::Mutex m_videoLock; - android::Condition m_newVideoRequestCond; -}; - - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) - -#endif // MediaTexture_h diff --git a/WebCore/platform/graphics/android/PaintLayerOperation.cpp b/WebCore/platform/graphics/android/PaintLayerOperation.cpp deleted file mode 100644 index 35867c7..0000000 --- a/WebCore/platform/graphics/android/PaintLayerOperation.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "PaintLayerOperation.h" - -#include "LayerAndroid.h" - -bool PaintLayerOperation::operator==(const QueuedOperation* operation) -{ - if (operation->type() != type()) - return false; - const PaintLayerOperation* op = static_cast<const PaintLayerOperation*>(operation); - return op->m_layer->uniqueId() == m_layer->uniqueId(); -} - -void PaintLayerOperation::run() -{ - if (m_layer) - m_layer->paintBitmapGL(); -} - -SkLayer* PaintLayerOperation::baseLayer() -{ - if (!m_layer) - return 0; - - return m_layer->getRootLayer(); -} - -LayerTexture* PaintLayerOperation::texture() -{ - if (!m_layer) - return 0; - return m_layer->texture(); -} - -bool PaintLayerBaseFilter::check(QueuedOperation* operation) -{ - if (operation->type() == QueuedOperation::PaintLayer) { - PaintLayerOperation* op = static_cast<PaintLayerOperation*>(operation); - if (op->baseLayer() == m_baseLayer) - return true; - } - return false; -} - -bool PaintLayerTextureFilter::check(QueuedOperation* operation) -{ - if (operation->type() == QueuedOperation::PaintLayer) { - PaintLayerOperation* op = static_cast<PaintLayerOperation*>(operation); - if (op->texture() == m_texture) - return true; - } - return false; -} diff --git a/WebCore/platform/graphics/android/PaintLayerOperation.h b/WebCore/platform/graphics/android/PaintLayerOperation.h deleted file mode 100644 index 74e87af..0000000 --- a/WebCore/platform/graphics/android/PaintLayerOperation.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 PaintLayerOperation_h -#define PaintLayerOperation_h - -#include "QueuedOperation.h" - -class SkLayer; - -namespace WebCore { - -class LayerAndroid; -class LayerTexture; - -class PaintLayerOperation : public QueuedOperation { - public: - PaintLayerOperation(LayerAndroid* layer) - : QueuedOperation(QueuedOperation::PaintLayer, 0) - , m_layer(layer) {} - virtual ~PaintLayerOperation() {} - virtual bool operator==(const QueuedOperation* operation); - virtual void run(); - SkLayer* baseLayer(); - LayerAndroid* layer() { return m_layer; } - LayerTexture* texture(); - - private: - LayerAndroid* m_layer; -}; - -class PaintLayerBaseFilter : public OperationFilter { - public: - PaintLayerBaseFilter(SkLayer* layer) : m_baseLayer(layer) {} - virtual bool check(QueuedOperation* operation); - - private: - SkLayer* m_baseLayer; -}; - -class PaintLayerTextureFilter : public OperationFilter { - public: - PaintLayerTextureFilter(LayerTexture* texture) : m_texture(texture) {} - virtual bool check(QueuedOperation* operation); - - private: - LayerTexture* m_texture; -}; - -} - -#endif // PaintLayerOperation_h diff --git a/WebCore/platform/graphics/android/PaintTileOperation.cpp b/WebCore/platform/graphics/android/PaintTileOperation.cpp deleted file mode 100644 index 222b69b..0000000 --- a/WebCore/platform/graphics/android/PaintTileOperation.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2011, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "PaintTileOperation.h" - -namespace WebCore { - -PaintTileOperation::PaintTileOperation(BaseTile* tile) - : QueuedOperation(QueuedOperation::PaintTile, tile->page()) - , m_tile(tile) -{ - if (m_tile) - m_tile->setRepaintPending(true); -} - -PaintTileOperation::~PaintTileOperation() -{ - if (m_tile) { - m_tile->setRepaintPending(false); - m_tile = 0; - } -} - -bool PaintTileOperation::operator==(const QueuedOperation* operation) -{ - if (operation->type() != type()) - return false; - const PaintTileOperation* op = static_cast<const PaintTileOperation*>(operation); - return op->m_tile == m_tile; -} - -void PaintTileOperation::run() -{ - if (m_tile) { - m_tile->paintBitmap(); - m_tile->setRepaintPending(false); - m_tile = 0; - } -} - -int PaintTileOperation::priority() -{ - if (!m_tile || m_tile->usedLevel() < 0) - return -1; - bool goingDown = m_tile->page()->scrollingDown(); - SkIRect *rect = m_tile->page()->expandedTileBounds(); - int firstTileX = rect->fLeft; - int nbTilesWidth = rect->width(); - int priority = m_tile->x() - firstTileX; - if (goingDown) - priority += (rect->fBottom - m_tile->y()) * nbTilesWidth; - else - priority += (m_tile->y() - rect->fTop) * nbTilesWidth; - priority += m_tile->usedLevel() * 100000; - return priority; -} - -} diff --git a/WebCore/platform/graphics/android/PaintTileOperation.h b/WebCore/platform/graphics/android/PaintTileOperation.h deleted file mode 100644 index 0920f32..0000000 --- a/WebCore/platform/graphics/android/PaintTileOperation.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 PaintTileSetOperation_h -#define PaintTileSetOperation_h - -#include "QueuedOperation.h" - -namespace WebCore { - -class PaintTileOperation : public QueuedOperation { - public: - PaintTileOperation(BaseTile* tile); - virtual ~PaintTileOperation(); - virtual bool operator==(const QueuedOperation* operation); - virtual void run(); - virtual int priority(); - - private: - BaseTile* m_tile; -}; - -} - -#endif // PaintTileSetOperation_h diff --git a/WebCore/platform/graphics/android/PathAndroid.cpp b/WebCore/platform/graphics/android/PathAndroid.cpp deleted file mode 100644 index e0d7171..0000000 --- a/WebCore/platform/graphics/android/PathAndroid.cpp +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "Path.h" - -#include "AffineTransform.h" -#include "FloatRect.h" -#include "GraphicsContext.h" -#include "ImageBuffer.h" -#include "PlatformGraphicsContext.h" -#include "SkiaUtils.h" -#include "SkPaint.h" -#include "SkPath.h" -#include "SkRegion.h" -#include "StrokeStyleApplier.h" -#include "TransformationMatrix.h" -#include "android_graphics.h" - -namespace WebCore { - -Path::Path() -{ - m_path = new SkPath; -// m_path->setFlags(SkPath::kWinding_FillType); -} - -Path::Path(const Path& other) -{ - m_path = new SkPath(*other.m_path); -} - -Path::~Path() -{ - delete m_path; -} - -Path& Path::operator=(const Path& other) -{ - *m_path = *other.m_path; - return *this; -} - -bool Path::isEmpty() const -{ - return m_path->isEmpty(); -} - -bool Path::hasCurrentPoint() const -{ - // webkit wants to know if we have any points, including any moveTos. - // Skia's empty() will return true if it has just a moveTo, so we need to - // call getPoints(NULL), which returns the number of points, - // including moveTo. - return m_path->getPoints(0, 0) > 0; -} - -FloatPoint Path::currentPoint() const -{ - if (hasCurrentPoint()) { - SkPoint lastPt; - m_path->getLastPt(&lastPt); - return lastPt; - } - float quietNaN = std::numeric_limits<float>::quiet_NaN(); - return FloatPoint(quietNaN, quietNaN); -} - -bool Path::contains(const FloatPoint& point, WindRule rule) const -{ - SkRegion rgn, clip; - - int x = (int)floorf(point.x()); - int y = (int)floorf(point.y()); - clip.setRect(x, y, x + 1, y + 1); - - SkPath::FillType ft = m_path->getFillType(); // save - m_path->setFillType(rule == RULE_NONZERO ? SkPath::kWinding_FillType : SkPath::kEvenOdd_FillType); - - bool contains = rgn.setPath(*m_path, clip); - - m_path->setFillType(ft); // restore - return contains; -} - -void Path::translate(const FloatSize& size) -{ - m_path->offset(SkFloatToScalar(size.width()), SkFloatToScalar(size.height())); -} - -FloatRect Path::boundingRect() const -{ - const SkRect& r = m_path->getBounds(); - return FloatRect( SkScalarToFloat(r.fLeft), - SkScalarToFloat(r.fTop), - SkScalarToFloat(r.width()), - SkScalarToFloat(r.height())); -} - -void Path::moveTo(const FloatPoint& point) -{ - m_path->moveTo(SkFloatToScalar(point.x()), SkFloatToScalar(point.y())); -} - -void Path::addLineTo(const FloatPoint& p) -{ - m_path->lineTo(SkFloatToScalar(p.x()), SkFloatToScalar(p.y())); -} - -void Path::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& ep) -{ - m_path->quadTo( SkFloatToScalar(cp.x()), SkFloatToScalar(cp.y()), - SkFloatToScalar(ep.x()), SkFloatToScalar(ep.y())); -} - -void Path::addBezierCurveTo(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& ep) -{ - m_path->cubicTo(SkFloatToScalar(p1.x()), SkFloatToScalar(p1.y()), - SkFloatToScalar(p2.x()), SkFloatToScalar(p2.y()), - SkFloatToScalar(ep.x()), SkFloatToScalar(ep.y())); -} - -void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) -{ - m_path->arcTo(SkFloatToScalar(p1.x()), SkFloatToScalar(p1.y()), - SkFloatToScalar(p2.x()), SkFloatToScalar(p2.y()), - SkFloatToScalar(radius)); -} - -void Path::closeSubpath() -{ - m_path->close(); -} - -static const float gPI = 3.14159265f; -static const float g2PI = 6.28318531f; -static const float g180OverPI = 57.29577951308f; - -static float fast_mod(float angle, float max) { - if (angle >= max || angle <= -max) { - angle = fmodf(angle, max); - } - return angle; -} - -void Path::addArc(const FloatPoint& p, float r, float sa, float ea, - bool clockwise) { - SkScalar cx = SkFloatToScalar(p.x()); - SkScalar cy = SkFloatToScalar(p.y()); - SkScalar radius = SkFloatToScalar(r); - - SkRect oval; - oval.set(cx - radius, cy - radius, cx + radius, cy + radius); - - float sweep = ea - sa; - bool prependOval = false; - - /* Note if clockwise and the sign of the sweep disagree. This particular - logic was deduced from http://canvex.lazyilluminati.com/misc/arc.html - */ - if (clockwise && (sweep > 0 || sweep < -g2PI)) { - sweep = fmodf(sweep, g2PI) - g2PI; - } else if (!clockwise && (sweep < 0 || sweep > g2PI)) { - sweep = fmodf(sweep, g2PI) + g2PI; - } - - // If the abs(sweep) >= 2PI, then we need to add a circle before we call - // arcTo, since it treats the sweep mod 2PI. We don't have a prepend call, - // so we just remember this, and at the end create a new path with an oval - // and our current path, and then swap then. - // - if (sweep >= g2PI || sweep <= -g2PI) { - prependOval = true; -// SkDebugf("addArc sa=%g ea=%g cw=%d sweep %g treat as circle\n", sa, ea, clockwise, sweep); - - // now reduce sweep to just the amount we need, so that the current - // point is left where the caller expects it. - sweep = fmodf(sweep, g2PI); - } - - sa = fast_mod(sa, g2PI); - SkScalar startDegrees = SkFloatToScalar(sa * g180OverPI); - SkScalar sweepDegrees = SkFloatToScalar(sweep * g180OverPI); - -// SkDebugf("addArc sa=%g ea=%g cw=%d sweep=%g ssweep=%g\n", sa, ea, clockwise, sweep, SkScalarToFloat(sweepDegrees)); - m_path->arcTo(oval, startDegrees, sweepDegrees, false); - - if (prependOval) { - SkPath tmp; - tmp.addOval(oval); - tmp.addPath(*m_path); - m_path->swap(tmp); - } -} - -void Path::addRect(const FloatRect& rect) -{ - m_path->addRect(rect); -} - -void Path::addEllipse(const FloatRect& rect) -{ - m_path->addOval(rect); -} - -void Path::clear() -{ - m_path->reset(); -} - -static FloatPoint* setfpts(FloatPoint dst[], const SkPoint src[], int count) -{ - for (int i = 0; i < count; i++) - { - dst[i].setX(SkScalarToFloat(src[i].fX)); - dst[i].setY(SkScalarToFloat(src[i].fY)); - } - return dst; -} - -void Path::apply(void* info, PathApplierFunction function) const -{ - SkPath::Iter iter(*m_path, false); - SkPoint pts[4]; - - PathElement elem; - FloatPoint fpts[3]; - - for (;;) - { - switch (iter.next(pts)) { - case SkPath::kMove_Verb: - elem.type = PathElementMoveToPoint; - elem.points = setfpts(fpts, &pts[0], 1); - break; - case SkPath::kLine_Verb: - elem.type = PathElementAddLineToPoint; - elem.points = setfpts(fpts, &pts[1], 1); - break; - case SkPath::kQuad_Verb: - elem.type = PathElementAddQuadCurveToPoint; - elem.points = setfpts(fpts, &pts[1], 2); - break; - case SkPath::kCubic_Verb: - elem.type = PathElementAddCurveToPoint; - elem.points = setfpts(fpts, &pts[1], 3); - break; - case SkPath::kClose_Verb: - elem.type = PathElementCloseSubpath; - elem.points = setfpts(fpts, 0, 0); - break; - case SkPath::kDone_Verb: - return; - } - function(info, &elem); - } -} - -void Path::transform(const AffineTransform& xform) -{ - m_path->transform(xform); -} - -/////////////////////////////////////////////////////////////////////////////// - -// Computes the bounding box for the stroke and style currently selected into -// the given bounding box. This also takes into account the stroke width. -static FloatRect boundingBoxForCurrentStroke(GraphicsContext* context) -{ - const SkPath* path = context->getCurrPath(); - if (NULL == path) { - return FloatRect(); - } - - SkPaint paint; - context->setupStrokePaint(&paint); - SkPath fillPath; - paint.getFillPath(*path, &fillPath); - const SkRect& r = fillPath.getBounds(); - return FloatRect(SkScalarToFloat(r.fLeft), SkScalarToFloat(r.fTop), - SkScalarToFloat(r.width()), SkScalarToFloat(r.height())); -} - -FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) -{ - GraphicsContext* scratch = scratchContext(); - scratch->save(); - scratch->beginPath(); - scratch->addPath(*this); - - if (applier) - applier->strokeStyle(scratch); - - FloatRect r = boundingBoxForCurrentStroke(scratch); - scratch->restore(); - return r; -} - -#if ENABLE(SVG) -bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) const -{ - GraphicsContext* scratch = scratchContext(); - scratch->save(); - - applier->strokeStyle(scratch); - - SkPaint paint; - scratch->setupStrokePaint(&paint); - SkPath strokePath; - paint.getFillPath(*platformPath(), &strokePath); - bool contains = SkPathContainsPoint(&strokePath, point, - SkPath::kWinding_FillType); - - scratch->restore(); - return contains; -} -#endif - -} diff --git a/WebCore/platform/graphics/android/PatternAndroid.cpp b/WebCore/platform/graphics/android/PatternAndroid.cpp deleted file mode 100644 index 568036c..0000000 --- a/WebCore/platform/graphics/android/PatternAndroid.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "Pattern.h" - -#include "android_graphics.h" -#include "GraphicsContext.h" -#include "SkBitmapRef.h" -#include "SkCanvas.h" -#include "SkColorShader.h" -#include "SkShader.h" -#include "SkPaint.h" - -namespace WebCore { - -static SkShader::TileMode toTileMode(bool doRepeat) { - return doRepeat ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; -} - -void Pattern::platformDestroy() -{ - SkSafeUnref(m_pattern); - m_pattern = 0; -} - -SkShader* Pattern::platformPattern(const AffineTransform&) -{ - if (m_pattern) - return m_pattern; - - SkBitmapRef* ref = tileImage()->nativeImageForCurrentFrame(); - if (!ref) - return 0; - m_pattern = SkShader::CreateBitmapShader(ref->bitmap(), - toTileMode(m_repeatX), - toTileMode(m_repeatY)); - m_pattern->setLocalMatrix(m_patternSpaceTransformation); - return m_pattern; -} - -void Pattern::setPlatformPatternSpaceTransform() -{ - if (m_pattern) - m_pattern->setLocalMatrix(m_patternSpaceTransformation); -} - -} //namespace diff --git a/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp b/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp deleted file mode 100644 index fcdcce9..0000000 --- a/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "Node.h" -#include "PlatformGraphicsContext.h" -#include "SkCanvas.h" - -namespace WebCore { - -PlatformGraphicsContext::PlatformGraphicsContext(SkCanvas* canvas, WTF::Vector<Container>* buttons) - : mCanvas(canvas), m_deleteCanvas(false), m_buttons(buttons) -{ -} - -PlatformGraphicsContext::PlatformGraphicsContext() - : mCanvas(new SkCanvas), m_deleteCanvas(true), m_buttons(0) -{ -} - -PlatformGraphicsContext::~PlatformGraphicsContext() -{ - if (m_deleteCanvas) { -// printf("-------------------- deleting offscreen canvas\n"); - delete mCanvas; - } -} - -void PlatformGraphicsContext::storeButtonInfo(Node* node, const IntRect& r) -{ - if (m_buttons == NULL) - return; - // Check to see if we already have a Container for this node. If so, update - // it with the new rectangle and make the new recording canvas reference - // its picture. - Container* end = m_buttons->end(); - for (Container* ptr = m_buttons->begin(); ptr != end; ptr++) { - if (ptr->matches(node)) { - mCanvas->drawPicture(*(ptr->picture())); - ptr->setRect(r); - return; - } - } - // We did not have a Container representing this node, so create a new one. - Container container(node, r); - // Place a reference to our subpicture in the Picture. - mCanvas->drawPicture(*(container.picture())); - // Keep track of the information about the button. - m_buttons->append(container); -} - -} // WebCore diff --git a/WebCore/platform/graphics/android/PlatformGraphicsContext.h b/WebCore/platform/graphics/android/PlatformGraphicsContext.h deleted file mode 100644 index 0ce86d2..0000000 --- a/WebCore/platform/graphics/android/PlatformGraphicsContext.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 platform_graphics_context_h -#define platform_graphics_context_h - -#include "IntRect.h" -#include "RenderSkinAndroid.h" -#include "RenderSkinButton.h" -#include "SkCanvas.h" -#include "SkPicture.h" -#include "SkTDArray.h" - -class SkCanvas; - -class Container { -public: - Container(WebCore::Node* node, const WebCore::IntRect& r) - : m_node(node), m_rect(r), m_state(WebCore::RenderSkinAndroid::kDisabled) - { - m_picture = new SkPicture; - } - - ~Container() - { - m_picture->unref(); - } - - Container& operator=(const Container& src) - { - if (this != &src) { - m_node = src.m_node; - if (m_picture) - m_picture->unref(); - m_picture = src.m_picture; - m_picture->ref(); - m_rect = src.m_rect; - m_state = WebCore::RenderSkinAndroid::kDisabled; - } - return *this; - } - - Container(const Container& src) - { - m_node = src.m_node; - m_picture = src.m_picture; - m_picture->ref(); - m_rect = src.m_rect; - m_state = WebCore::RenderSkinAndroid::kDisabled; - } - - // m_picture has a ref count of 1 to begin with. It will increase each time - // m_picture is referenced by another picture. When the other pictures are - // deleted, the ref count gets decremented. If the ref count is one, then - // no other pictures reference this one, so the button is no longer being - // used, and therefore can be removed. - bool canBeRemoved() - { - return m_picture->getRefCnt() == 1; - } - - bool matches(const WebCore::Node* match) { return m_node == match; } - - const WebCore::Node* node() const { return m_node; } - - // Provide a pointer to our SkPicture. - SkPicture* picture() { return m_picture; } - - WebCore::IntRect rect() { return m_rect; } - - // Update the rectangle with a new rectangle, as the positioning of this - // button may have changed due to a new layout. If it is a new rectangle, - // set its state to disabled, so that it will be redrawn when we cycle - // through the list of buttons. - void setRect(WebCore::IntRect r) - { - if (m_rect != r) { - m_rect = r; - m_state = WebCore::RenderSkinAndroid::kDisabled; - } - } - - // Update the focus state of this button, depending on whether it - // corresponds to the focused node passed in. If its state has changed, - // re-record to the subpicture, so the master picture will reflect the - // change. - void updateFocusState(WebCore::RenderSkinAndroid::State state, - const WebCore::RenderSkinButton* buttonSkin) - { - if (state == m_state) - return; - // If this button is being told to draw focused, but it is already in a - // pressed state, leave it in the pressed state, to show that it is - // being followed. - if (m_state == WebCore::RenderSkinAndroid::kPressed && - state == WebCore::RenderSkinAndroid::kFocused) - return; - m_state = state; - SkCanvas* canvas = m_picture->beginRecording(m_rect.right(), m_rect.bottom()); - buttonSkin->draw(canvas, m_rect, state); - m_picture->endRecording(); - } -private: - // Only used for comparison, since after it is stored it will be transferred - // to the UI thread. - WebCore::Node* m_node; - // The rectangle representing the bounds of the button. - WebCore::IntRect m_rect; - // An SkPicture that, thanks to storeButtonInfo, is pointed to by the master - // picture, so that we can rerecord this button without rerecording the - // world. - SkPicture* m_picture; - // The state of the button - Currently kFocused or kNormal (and kDisabled - // as an initial value), but could be expanded to include other states. - WebCore::RenderSkinAndroid::State m_state; -}; - -namespace WebCore { - - class GraphicsContext; - -class PlatformGraphicsContext { -public: - PlatformGraphicsContext(); - // Pass in a recording canvas, and an array of button information to be - // updated. - PlatformGraphicsContext(SkCanvas* canvas, WTF::Vector<Container>* buttons); - ~PlatformGraphicsContext(); - - SkCanvas* mCanvas; - - bool deleteUs() const { return m_deleteCanvas; } - // If our graphicscontext has a button list, add a new container for the - // nod/rect, and record a new subpicture for this node/button in the current - // mCanvas - void storeButtonInfo(Node* node, const IntRect& r); -private: - bool m_deleteCanvas; - WTF::Vector<Container>* m_buttons; -}; - -} -#endif diff --git a/WebCore/platform/graphics/android/QueuedOperation.h b/WebCore/platform/graphics/android/QueuedOperation.h deleted file mode 100644 index 98f3e2f..0000000 --- a/WebCore/platform/graphics/android/QueuedOperation.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 QueuedOperation_h -#define QueuedOperation_h - -#include "TiledPage.h" - -namespace WebCore { - -class QueuedOperation { - public: - enum OperationType { Undefined, PaintTile, PaintLayer, DeleteTexture }; - QueuedOperation(OperationType type, TiledPage* page) - : m_type(type) - , m_page(page) {} - virtual ~QueuedOperation() {} - virtual void run() = 0; - virtual bool operator==(const QueuedOperation* operation) = 0; - virtual int priority() { return -1; } - OperationType type() const { return m_type; } - TiledPage* page() const { return m_page; } - private: - OperationType m_type; - TiledPage* m_page; -}; - -class OperationFilter { - public: - virtual ~OperationFilter() {} - virtual bool check(QueuedOperation* operation) = 0; -}; - -class PageFilter : public OperationFilter { - public: - PageFilter(TiledPage* page) : m_page(page) {} - virtual bool check(QueuedOperation* operation) - { - if (operation->page() == m_page) - return true; - return false; - } - private: - TiledPage* m_page; -}; - -class PagePaintFilter : public OperationFilter { - public: - PagePaintFilter(TiledPage* page) : m_page(page) {} - virtual bool check(QueuedOperation* operation) - { - if (operation->type() == QueuedOperation::PaintTile - && operation->page() == m_page) - return true; - return false; - } - private: - TiledPage* m_page; -}; - -} - -#endif // QueuedOperation_h diff --git a/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp b/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp deleted file mode 100644 index ca8f03c..0000000 --- a/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "config.h" -#include "ScrollableLayerAndroid.h" - -#if USE(ACCELERATED_COMPOSITING) - -namespace WebCore { - -bool ScrollableLayerAndroid::scrollTo(int x, int y) -{ - SkIRect scrollBounds; - getScrollRect(&scrollBounds); - if (!scrollBounds.fRight && !scrollBounds.fBottom) - return false; - - SkScalar newX = SkScalarPin(x, 0, scrollBounds.fRight); - SkScalar newY = SkScalarPin(y, 0, scrollBounds.fBottom); - // Check for no change. - if (newX == scrollBounds.fLeft && newY == scrollBounds.fTop) - return false; - - SkScalar diffX = newX - scrollBounds.fLeft; - SkScalar diffY = newY - scrollBounds.fTop; - const SkPoint& pos = getPosition(); - setPosition(pos.fX - diffX, pos.fY - diffY); - return true; -} - -void ScrollableLayerAndroid::getScrollRect(SkIRect* out) const -{ - const SkPoint& pos = getPosition(); - out->fLeft = m_scrollLimits.fLeft - pos.fX; - out->fTop = m_scrollLimits.fTop - pos.fY; - out->fRight = getSize().width() - m_scrollLimits.width(); - out->fBottom = getSize().height() - m_scrollLimits.height(); -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/ScrollableLayerAndroid.h b/WebCore/platform/graphics/android/ScrollableLayerAndroid.h deleted file mode 100644 index b23f056..0000000 --- a/WebCore/platform/graphics/android/ScrollableLayerAndroid.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ScrollableLayerAndroid_h -#define ScrollableLayerAndroid_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "LayerAndroid.h" - -namespace WebCore { - -class ScrollableLayerAndroid : public LayerAndroid { - -public: - ScrollableLayerAndroid(RenderLayer* owner) - : LayerAndroid(owner) {} - ScrollableLayerAndroid(const ScrollableLayerAndroid& layer) - : LayerAndroid(layer) - , m_scrollLimits(layer.m_scrollLimits) {} - ScrollableLayerAndroid(const LayerAndroid& layer) - : LayerAndroid(layer) - { - m_scrollLimits.setEmpty(); - } - virtual ~ScrollableLayerAndroid() {}; - - virtual bool contentIsScrollable() const { return true; } - - virtual LayerAndroid* copy() const { return new ScrollableLayerAndroid(*this); } - - // Returns true if the content position has changed. - bool scrollTo(int dx, int dy); - - // Fills the rect with the current scroll offset and the maximum scroll. - // fLeft = scrollX - // fTop = scrollY - // fRight = maxX - // fBottom = maxY - void getScrollRect(SkIRect* out) const; - - void setScrollLimits(float x, float y, float width, float height) - { - m_scrollLimits.set(x, y, x + width, y + height); - } - -private: - SkRect m_scrollLimits; -}; - -} - -#endif // USE(ACCELERATED_COMPOSITING) - -#endif // LayerAndroid_h diff --git a/WebCore/platform/graphics/android/ShaderProgram.cpp b/WebCore/platform/graphics/android/ShaderProgram.cpp deleted file mode 100644 index 6933890..0000000 --- a/WebCore/platform/graphics/android/ShaderProgram.cpp +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "ShaderProgram.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "FloatPoint3D.h" -#include "GLUtils.h" - -#include <GLES2/gl2.h> -#include <cutils/log.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ShaderProgram", __VA_ARGS__) - -namespace WebCore { - -static const char gVertexShader[] = - "attribute vec4 vPosition;\n" - "uniform mat4 projectionMatrix;\n" - "varying vec2 v_texCoord;\n" - "void main() {\n" - " gl_Position = projectionMatrix * vPosition;\n" - " v_texCoord = vec2(vPosition);\n" - "}\n"; - -static const char gFragmentShader[] = - "precision mediump float;\n" - "varying vec2 v_texCoord; \n" - "uniform float alpha; \n" - "uniform sampler2D s_texture; \n" - "void main() {\n" - " gl_FragColor = texture2D(s_texture, v_texCoord); \n" - " gl_FragColor *= alpha; " - "}\n"; - -static const char gVideoVertexShader[] = - "attribute vec4 vPosition;\n" - "uniform mat4 textureMatrix;\n" - "uniform mat4 projectionMatrix;\n" - "varying vec2 v_texCoord;\n" - "void main() {\n" - " gl_Position = projectionMatrix * vPosition;\n" - " v_texCoord = vec2(textureMatrix * vec4(vPosition.x, 1.0 - vPosition.y, 0.0, 1.0));\n" - "}\n"; - -static const char gVideoFragmentShader[] = - "#extension GL_OES_EGL_image_external : require\n" - "precision mediump float;\n" - "uniform samplerExternalOES s_yuvTexture;\n" - "varying vec2 v_texCoord;\n" - "void main() {\n" - " gl_FragColor = texture2D(s_yuvTexture, v_texCoord);\n" - "}\n"; - -GLuint ShaderProgram::loadShader(GLenum shaderType, const char* pSource) -{ - GLuint shader = glCreateShader(shaderType); - if (shader) { - glShaderSource(shader, 1, &pSource, 0); - glCompileShader(shader); - GLint compiled = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) { - GLint infoLen = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); - if (infoLen) { - char* buf = (char*) malloc(infoLen); - if (buf) { - glGetShaderInfoLog(shader, infoLen, 0, buf); - XLOG("could not compile shader %d:\n%s\n", shaderType, buf); - free(buf); - } - glDeleteShader(shader); - shader = 0; - } - } - } - return shader; -} - -GLuint ShaderProgram::createProgram(const char* pVertexSource, const char* pFragmentSource) -{ - GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); - if (!vertexShader) { - XLOG("couldn't load the vertex shader!"); - return -1; - } - - GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); - if (!pixelShader) { - XLOG("couldn't load the pixel shader!"); - return -1; - } - - GLuint program = glCreateProgram(); - if (program) { - glAttachShader(program, vertexShader); - GLUtils::checkGlError("glAttachShader vertex"); - glAttachShader(program, pixelShader); - GLUtils::checkGlError("glAttachShader pixel"); - glLinkProgram(program); - GLint linkStatus = GL_FALSE; - glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); - if (linkStatus != GL_TRUE) { - GLint bufLength = 0; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); - if (bufLength) { - char* buf = (char*) malloc(bufLength); - if (buf) { - glGetProgramInfoLog(program, bufLength, 0, buf); - XLOG("could not link program:\n%s\n", buf); - free(buf); - } - } - glDeleteProgram(program); - program = -1; - } - } - return program; -} - -ShaderProgram::ShaderProgram() - : m_blendingEnabled(false) -{ - init(); -} - -void ShaderProgram::init() -{ - m_program = createProgram(gVertexShader, gFragmentShader); - m_videoProgram = createProgram(gVideoVertexShader, gVideoFragmentShader); - if (m_program == -1 || m_videoProgram == -1) - return; - - m_hProjectionMatrix = glGetUniformLocation(m_program, "projectionMatrix"); - m_hAlpha = glGetUniformLocation(m_program, "alpha"); - m_hTexSampler = glGetUniformLocation(m_program, "s_texture"); - - m_hPosition = glGetAttribLocation(m_program, "vPosition"); - - m_hVideoProjectionMatrix = glGetUniformLocation(m_videoProgram, "projectionMatrix"); - m_hVideoTextureMatrix = glGetUniformLocation(m_videoProgram, "textureMatrix"); - m_hVideoTexSampler = glGetUniformLocation(m_videoProgram, "s_yuvTexture"); - - m_hVideoPosition = glGetAttribLocation(m_program, "vPosition"); - - const GLfloat coord[] = { - 0.0f, 0.0f, // C - 1.0f, 0.0f, // D - 0.0f, 1.0f, // A - 1.0f, 1.0f // B - }; - - glGenBuffers(1, m_textureBuffer); - glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); - glBufferData(GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), coord, GL_STATIC_DRAW); -} - -void ShaderProgram::resetBlending() -{ - glDisable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glBlendEquation(GL_FUNC_ADD); - m_blendingEnabled = false; -} - -void ShaderProgram::setBlendingState(bool enableBlending) -{ - if (enableBlending == m_blendingEnabled) - return; - - if (enableBlending) - glEnable(GL_BLEND); - else - glDisable(GL_BLEND); - - m_blendingEnabled = enableBlending; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Drawing -///////////////////////////////////////////////////////////////////////////////////////// - -void ShaderProgram::setViewport(SkRect& viewport) -{ - TransformationMatrix ortho; - GLUtils::setOrthographicMatrix(ortho, viewport.fLeft, viewport.fTop, - viewport.fRight, viewport.fBottom, -1000, 1000); - m_projectionMatrix = ortho; - m_viewport = viewport; -} - -void ShaderProgram::setProjectionMatrix(SkRect& geometry) -{ - TransformationMatrix translate; - translate.translate3d(geometry.fLeft, geometry.fTop, 0.0); - TransformationMatrix scale; - scale.scale3d(geometry.width(), geometry.height(), 1.0); - - TransformationMatrix total = m_projectionMatrix; - total.multLeft(translate); - total.multLeft(scale); - - GLfloat projectionMatrix[16]; - GLUtils::toGLMatrix(projectionMatrix, total); - glUniformMatrix4fv(m_hProjectionMatrix, 1, GL_FALSE, projectionMatrix); -} - -void ShaderProgram::drawQuad(SkRect& geometry, int textureId, float opacity) -{ - setProjectionMatrix(geometry); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureId); - - glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); - glEnableVertexAttribArray(m_hPosition); - glVertexAttribPointer(m_hPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); - glUniform1f(alpha(), opacity); - - setBlendingState(opacity < 1.0); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - GLUtils::checkGlError("drawQuad"); -} - -void ShaderProgram::setViewRect(const IntRect& viewRect) -{ - m_viewRect = viewRect; - - // We do clipping using glScissor, which needs to take - // coordinates in screen space. The following matrix transform - // content coordinates in screen coordinates. - TransformationMatrix translate; - translate.translate(1.0, 1.0); - - TransformationMatrix scale; - scale.scale3d(m_viewRect.width() * 0.5f, m_viewRect.height() * 0.5f, 1); - - m_documentToScreenMatrix = m_projectionMatrix; - m_documentToScreenMatrix.multiply(translate); - m_documentToScreenMatrix.multiply(scale); - - m_documentToInvScreenMatrix = m_projectionMatrix; - translate.scale3d(1, -1, 1); - m_documentToInvScreenMatrix.multiply(translate); - m_documentToInvScreenMatrix.multiply(scale); -} - -// This function transform a clip rect extracted from the current layer -// into a clip rect in screen coordinates -- used by the clipping rects -FloatRect ShaderProgram::rectInScreenCoord(const TransformationMatrix& drawMatrix, const IntSize& size) -{ - FloatRect srect(0, 0, size.width(), size.height()); - TransformationMatrix renderMatrix = drawMatrix; - renderMatrix.multiply(m_documentToScreenMatrix); - return renderMatrix.mapRect(srect); -} - -// used by the partial screen invals -FloatRect ShaderProgram::rectInInvScreenCoord(const TransformationMatrix& drawMatrix, const IntSize& size) -{ - FloatRect srect(0, 0, size.width(), size.height()); - TransformationMatrix renderMatrix = drawMatrix; - renderMatrix.multiply(m_documentToInvScreenMatrix); - return renderMatrix.mapRect(srect); -} - -FloatRect ShaderProgram::rectInInvScreenCoord(const FloatRect& rect) -{ - return m_documentToInvScreenMatrix.mapRect(rect); -} - -FloatRect ShaderProgram::rectInScreenCoord(const FloatRect& rect) -{ - return m_documentToScreenMatrix.mapRect(rect); -} - -FloatRect ShaderProgram::convertInvScreenCoordToScreenCoord(const FloatRect& rect) -{ - FloatRect documentRect = m_documentToInvScreenMatrix.inverse().mapRect(rect); - return rectInScreenCoord(documentRect); -} - -FloatRect ShaderProgram::convertScreenCoordToInvScreenCoord(const FloatRect& rect) -{ - FloatRect documentRect = m_documentToScreenMatrix.inverse().mapRect(rect); - return rectInInvScreenCoord(documentRect); -} - -void ShaderProgram::setScreenClip(const IntRect& clip) -{ - m_screenClip = clip; - IntRect mclip = clip; - - // the clip from frameworks is in full screen coordinates - mclip.setY(clip.y() - m_webViewRect.y() - m_titleBarHeight); - FloatRect tclip = convertInvScreenCoordToScreenCoord(mclip); - IntRect screenClip(tclip.x(), tclip.y(), tclip.width(), tclip.height()); - m_screenClip = screenClip; -} - -// clip is in screen coordinates -void ShaderProgram::clip(const FloatRect& clip) -{ - if (clip == m_clipRect) - return; - - if (clip.width() == 0 && clip.height() == 0) - return; - - // we should only call glScissor in this function, so that we can easily - // track the current clipping rect. - - IntRect screenClip(clip.x(), - clip.y(), - clip.width(), clip.height()); - - if (!m_screenClip.isEmpty()) - screenClip.intersect(m_screenClip); - - screenClip.setY(screenClip.y() + m_viewRect.y()); - if (screenClip.x() < 0) { - int w = screenClip.width(); - w += screenClip.x(); - screenClip.setX(0); - screenClip.setWidth(w); - } - if (screenClip.y() < 0) { - int h = screenClip.height(); - h += screenClip.y(); - screenClip.setY(0); - screenClip.setHeight(h); - } - - glScissor(screenClip.x(), screenClip.y(), screenClip.width(), screenClip.height()); - - m_clipRect = clip; -} - -IntRect ShaderProgram::clippedRectWithViewport(const IntRect& rect, int margin) -{ - IntRect viewport(m_viewport.fLeft - margin, m_viewport.fTop - margin, - m_viewport.width() + margin, m_viewport.height() + margin); - viewport.intersect(rect); - return viewport; -} - -float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, float h) -{ - TransformationMatrix renderMatrix = drawMatrix; - renderMatrix.scale3d(w, h, 1); - renderMatrix.multiply(m_projectionMatrix); - FloatPoint3D point(0.5, 0.5, 0.0); - FloatPoint3D result = renderMatrix.mapPoint(point); - return result.z(); -} - -void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix, - SkRect& geometry, int textureId, float opacity, - bool forceBlending) -{ - - TransformationMatrix renderMatrix = drawMatrix; - // move the drawing depending on where the texture is on the layer - renderMatrix.translate(geometry.fLeft, geometry.fTop); - renderMatrix.scale3d(geometry.width(), geometry.height(), 1); - renderMatrix.multiply(m_projectionMatrix); - - GLfloat projectionMatrix[16]; - GLUtils::toGLMatrix(projectionMatrix, renderMatrix); - glUniformMatrix4fv(m_hProjectionMatrix, 1, GL_FALSE, projectionMatrix); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureId); - - glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); - glEnableVertexAttribArray(m_hPosition); - glVertexAttribPointer(m_hPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); - glUniform1f(alpha(), opacity); - - setBlendingState(forceBlending || opacity < 1.0); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); -} - -void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, - float* textureMatrix, SkRect& geometry, - int textureId) -{ - // switch to our custom yuv video rendering program - glUseProgram(m_videoProgram); - - TransformationMatrix renderMatrix = drawMatrix; - renderMatrix.translate(geometry.fLeft, geometry.fTop); - renderMatrix.scale3d(geometry.width(), geometry.height(), 1); - renderMatrix.multiply(m_projectionMatrix); - - GLfloat projectionMatrix[16]; - GLUtils::toGLMatrix(projectionMatrix, renderMatrix); - glUniformMatrix4fv(m_hVideoProjectionMatrix, 1, GL_FALSE, projectionMatrix); - glUniformMatrix4fv(m_hVideoTextureMatrix, 1, GL_FALSE, textureMatrix); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId); - - glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); - glEnableVertexAttribArray(m_hVideoPosition); - glVertexAttribPointer(m_hVideoPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); - - setBlendingState(false); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - // switch back to our normal rendering program - glUseProgram(m_program); -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/ShaderProgram.h b/WebCore/platform/graphics/android/ShaderProgram.h deleted file mode 100644 index 55afe4f..0000000 --- a/WebCore/platform/graphics/android/ShaderProgram.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ShaderProgram_h -#define ShaderProgram_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "FloatRect.h" -#include "IntRect.h" -#include "SkRect.h" -#include "TransformationMatrix.h" -#include <GLES2/gl2.h> - -namespace WebCore { - -class ShaderProgram { - public: - ShaderProgram(); - void init(); - int projectionMatrix() { return m_hProjectionMatrix; } - int alpha() { return m_hAlpha; } - int textureSampler() { return m_hTexSampler; } - int program() { return m_program; } - - // Drawing - void setViewport(SkRect& viewport); - void drawQuad(SkRect& geometry, int textureId, float opacity); - float zValue(const TransformationMatrix& drawMatrix, float w, float h); - void drawLayerQuad(const TransformationMatrix& drawMatrix, - SkRect& geometry, int textureId, float opacity, - bool forceBlending = false); - void drawVideoLayerQuad(const TransformationMatrix& drawMatrix, - float* textureMatrix, SkRect& geometry, int textureId); - void setViewRect(const IntRect& viewRect); - FloatRect rectInScreenCoord(const TransformationMatrix& drawMatrix, - const IntSize& size); - FloatRect rectInInvScreenCoord(const TransformationMatrix& drawMatrix, - const IntSize& size); - - FloatRect rectInInvScreenCoord(const FloatRect& rect); - FloatRect rectInScreenCoord(const FloatRect& rect); - FloatRect convertInvScreenCoordToScreenCoord(const FloatRect& rect); - FloatRect convertScreenCoordToInvScreenCoord(const FloatRect& rect); - - void setTitleBarHeight(int height) { m_titleBarHeight = height; } - void setWebViewRect(const IntRect& rect) { m_webViewRect = rect; } - void setScreenClip(const IntRect& clip); - void clip(const FloatRect& rect); - IntRect clippedRectWithViewport(const IntRect& rect, int margin = 0); - - void resetBlending(); - - private: - GLuint loadShader(GLenum shaderType, const char* pSource); - GLuint createProgram(const char* vertexSource, const char* fragmentSource); - void setProjectionMatrix(SkRect& geometry); - - void setBlendingState(bool enableBlending); - - bool m_blendingEnabled; - - int m_program; - int m_videoProgram; - - TransformationMatrix m_projectionMatrix; - GLuint m_textureBuffer[1]; - - TransformationMatrix m_documentToScreenMatrix; - TransformationMatrix m_documentToInvScreenMatrix; - SkRect m_viewport; - IntRect m_viewRect; - FloatRect m_clipRect; - IntRect m_screenClip; - int m_titleBarHeight; - IntRect m_webViewRect; - - // uniforms - int m_hProjectionMatrix; - int m_hAlpha; - int m_hTexSampler; - int m_hVideoProjectionMatrix; - int m_hVideoTextureMatrix; - int m_hVideoTexSampler; - - // attribs - GLint m_hPosition; - GLint m_hVideoPosition; -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) -#endif // ShaderProgram_h diff --git a/WebCore/platform/graphics/android/SharedBufferStream.cpp b/WebCore/platform/graphics/android/SharedBufferStream.cpp deleted file mode 100644 index 952495b..0000000 --- a/WebCore/platform/graphics/android/SharedBufferStream.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "JavaSharedClient.h" -#include "SharedBuffer.h" -#include "SharedBufferStream.h" - -using namespace android; - -namespace WebCore { - - static void CallDeref(void* buffer) { - ((SharedBuffer*)buffer)->deref(); - } - - SharedBufferStream::SharedBufferStream(SharedBuffer* buffer) - : SkMemoryStream(buffer->data(), buffer->size(), false) { - fBuffer = buffer; - buffer->ref(); - } - - SharedBufferStream::~SharedBufferStream() { - // we can't necessarily call fBuffer->deref() here, as we may be - // in a different thread from webkit, and SharedBuffer is not - // threadsafe. Therefore we defer it until it can be executed in the - // webkit thread. - JavaSharedClient::EnqueueFunctionPtr(CallDeref, fBuffer); - } - -} diff --git a/WebCore/platform/graphics/android/SharedBufferStream.h b/WebCore/platform/graphics/android/SharedBufferStream.h deleted file mode 100644 index da59b69..0000000 --- a/WebCore/platform/graphics/android/SharedBufferStream.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 WebCore_SharedBufferStream_DEFINED -#define WebCore_SharedBufferStream_DEFINED - -#include "SkStream.h" -#include "SharedBuffer.h" - -namespace WebCore { - - /** Subclass of SkStream that wrapps a webcore SharedBuffer object. To - allow this object to be deleted from any thread, the impl will ensure - that we unref the SharedBuffer object from the correct webcore thread. - */ - class SharedBufferStream : public SkMemoryStream { - public: - SharedBufferStream(SharedBuffer* buffer); - virtual ~SharedBufferStream(); - - private: - // don't allow this to change our data. should not get called, but we - // override here just to be sure - virtual void setMemory(const void* data, size_t length, bool copyData) { - sk_throw(); - } - - // we share ownership of this with webkit - SharedBuffer* fBuffer; - }; -} - -#endif diff --git a/WebCore/platform/graphics/android/SharedTexture.cpp b/WebCore/platform/graphics/android/SharedTexture.cpp deleted file mode 100644 index 040a28a..0000000 --- a/WebCore/platform/graphics/android/SharedTexture.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "SharedTexture.h" - -#include "GLUtils.h" - -#define LOG_NDEBUG 1 -#define LOG_TAG "SharedTexture.cpp" -#include <utils/Log.h> - -namespace WebCore { - -TextureInfo::TextureInfo() -{ - m_textureId = GL_NO_TEXTURE; - m_width = 0; - m_height = 0; - m_internalFormat = 0; -} - -bool TextureInfo::equalsAttributes(const TextureInfo* otherTexture) -{ - return otherTexture->m_width == m_width - && otherTexture->m_height == m_height - && otherTexture->m_internalFormat == m_internalFormat; -} - -void TextureInfo::copyAttributes(const TextureInfo* sourceTexture) -{ - m_width = sourceTexture->m_width; - m_height = sourceTexture->m_height; - m_internalFormat = sourceTexture->m_internalFormat; -} - -bool TextureInfo::operator==(const TextureInfo& otherTexture) -{ - return otherTexture.m_textureId == m_textureId && equalsAttributes(&otherTexture); -} - -SharedTexture::SharedTexture() -{ - m_eglImage = EGL_NO_IMAGE_KHR; - m_isNewImage = true; - m_syncObject = EGL_NO_SYNC_KHR; - - // Defer initialization of these values until we initialize the source - // texture. This ensures that this initialization happens in the appropriate - // thread. - m_display = 0; - m_supportsEGLImage = false; - m_supportsEGLFenceSyncKHR = false; -} - -// called by the consumer when it no longer wants to consume and after it has -// terminated all providers. If EGLImages are used, the deletion of the -// source texture and EGLImage is the responsibility of the caller. -SharedTexture::~SharedTexture() -{ - deleteTargetTexture(); -} - -void SharedTexture::initSourceTexture() -{ - - m_display = eglGetCurrentDisplay(); - m_supportsEGLImage = GLUtils::isEGLImageSupported(); - m_supportsEGLFenceSyncKHR = GLUtils::isEGLFenceSyncSupported(); - - // TODO temporarily disable fence sync until the EGL framework fixes - // performance issues that result from consistently adding/removing fences. - m_supportsEGLFenceSyncKHR = false; - - LOGI("imageEGL: %d syncKHR: %d", m_supportsEGLImage, m_supportsEGLFenceSyncKHR); - - glGenTextures(1, &m_sourceTexture.m_textureId); -} - - -void SharedTexture::deleteSourceTexture() -{ - // We need to delete the source texture and EGLImage in the thread in which - // it was created. In theory we should be able to delete the EGLImage - // from either thread, but it currently throws an error if not deleted - // in the same EGLContext from which it was created. - if (m_supportsEGLImage) { - GLUtils::deleteTexture(&m_sourceTexture.m_textureId); - if (m_eglImage != EGL_NO_IMAGE_KHR) { - eglDestroyImageKHR(eglGetCurrentDisplay(), m_eglImage); - m_eglImage = EGL_NO_IMAGE_KHR; - m_isNewImage = true; - } - LOGI("Deleted Source Texture and EGLImage"); - } -} - -void SharedTexture::deleteTargetTexture() -{ - if (m_supportsEGLImage) - GLUtils::deleteTexture(&m_targetTexture.m_textureId); - else - GLUtils::deleteTexture(&m_sourceTexture.m_textureId); -} - -TextureInfo* SharedTexture::lockSource() -{ - m_lock.lock(); - - if (m_supportsEGLFenceSyncKHR && m_syncObject != EGL_NO_SYNC_KHR) { - - EGLint status = eglClientWaitSyncKHR(m_display, m_syncObject, 0, 1000000); - - if (status == EGL_TIMEOUT_EXPIRED_KHR) - LOGE("Sync timeout for shared texture (%d)", m_sourceTexture.m_textureId); - - eglDestroySyncKHR(m_display, m_syncObject); - m_syncObject = EGL_NO_SYNC_KHR; - } - - return &m_sourceTexture; -} - -void SharedTexture::releaseSource() -{ - if (m_supportsEGLImage) { - // delete the existing image if needed - if (!m_sourceTexture.equalsAttributes(&m_targetTexture)) { - if (m_eglImage != EGL_NO_IMAGE_KHR) { - eglDestroyImageKHR(m_display, m_eglImage); - m_eglImage = EGL_NO_IMAGE_KHR; - m_isNewImage = true; - } - m_targetTexture.copyAttributes(&m_sourceTexture); - } - - // create an image from the texture, only when the texture is valid - if (m_eglImage == EGL_NO_IMAGE_KHR && m_sourceTexture.m_width - && m_sourceTexture.m_height) { - GLUtils::createEGLImageFromTexture(m_sourceTexture.m_textureId, &m_eglImage); - LOGV("Generating Image (%d) 0x%x", m_sourceTexture.m_textureId, m_eglImage); - - glFinish(); // ensures the texture is ready to be used by the consumer - } - - } else { - - m_targetTexture = m_sourceTexture; - - // in the case of shared contexts we must flush the texture edits to the - // GPU. This ensures the edits complete prior to allowing the texture to - // be bound on the producers context. - glFlush(); - } - - m_lock.unlock(); -} - -TextureInfo* SharedTexture::lockTarget() -{ - m_lock.lock(); - - if ((!m_supportsEGLImage && m_targetTexture.m_textureId == GL_NO_TEXTURE) - || (m_supportsEGLImage && m_eglImage == EGL_NO_IMAGE_KHR)) { - m_lock.unlock(); - return 0; - } - - if (m_supportsEGLImage && (m_isNewImage || m_targetTexture.m_textureId == GL_NO_TEXTURE)) { - if (m_targetTexture.m_textureId == GL_NO_TEXTURE) - glGenTextures(1, &m_targetTexture.m_textureId); - - GLUtils::createTextureFromEGLImage(m_targetTexture.m_textureId, m_eglImage); - LOGV("Generating Consumer Texture from 0x%x", m_eglImage); - m_isNewImage = false; - } - - return &m_targetTexture; -} - -void SharedTexture::releaseTarget() -{ - - if (m_supportsEGLFenceSyncKHR) { - if (m_syncObject != EGL_NO_SYNC_KHR) - eglDestroySyncKHR(m_display, m_syncObject); - m_syncObject = eglCreateSyncKHR(m_display, EGL_SYNC_FENCE_KHR, 0); - } else { - // TODO the flush currently prevents the screen from getting partial - // updates but the only way to guarantee this is to call glFinish. Until - // we support an EGL sync we will leave flush enable in order to test - // with modest performance. - glFlush(); - } - - m_lock.unlock(); -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/android/SharedTexture.h b/WebCore/platform/graphics/android/SharedTexture.h deleted file mode 100644 index 37d6091..0000000 --- a/WebCore/platform/graphics/android/SharedTexture.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 SharedTexture_h -#define SharedTexture_h - -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> -#include <utils/threads.h> - -namespace WebCore { - -static const GLuint GL_NO_TEXTURE = 0; - -/** - * TextureInfo is a class that stores both the texture and metadata about the - * texture. - */ -class TextureInfo { -public: - - TextureInfo(); - - bool equalsAttributes(const TextureInfo* otherTexture); - void copyAttributes(const TextureInfo* sourceTexture); - - bool operator==(const TextureInfo& otherTexture); - - GLuint m_textureId; - int32_t m_width; - int32_t m_height; - GLenum m_internalFormat; -}; - -/** - * SharedTexture is a class that encapsulates all the necessary variables - * needed to share a single texture across threads. In the case that threads - * communicate using EGL's sharedContext mechanism or do not support the proper - * EGLImage extensions the targetTexture, eglImage, and isNewImage variables are - * not used. - */ -class SharedTexture { -public: - // consumer thread functions - SharedTexture(); - ~SharedTexture(); - - TextureInfo* lockSource(); - void releaseSource(); - - TextureInfo* lockTarget(); - void releaseTarget(); - - // these locks are only used for the methods below - void lock() { m_lock.lock(); } - void unlock() { m_lock.unlock(); } - - void initSourceTexture(); // producer thread only - void deleteSourceTexture(); // producer thread only - void deleteTargetTexture(); // consumer thread only - GLuint getSourceTextureId() { return m_sourceTexture.m_textureId; } - GLuint getTargetTextureId() { return m_targetTexture.m_textureId; } - EGLImageKHR getEGLImage() { return m_eglImage; } - -private: - /** - * The mutex is used to ensure that the contents of the struct are current across - * threads and that only one thread is manipulating the texture at a given time. - */ - android::Mutex m_lock; - /** - * The texture and its associated metadata that is used by the producer. The - * texture is created in the producer's thread and can only be read by the - * consumer when the consumer shares the same context as the producer. The - * metadata is used to track changes to the texture that would orphan the - * target texture and require a new EGLImage to be constructed. - */ - TextureInfo m_sourceTexture; - /** - * The target texture stores the id and metadata of the texture that is to be - * used by the consumer. In the case where EGLImages are supported this hold - * the current eglImage target. - */ - TextureInfo m_targetTexture; - /** - * The EGLImage is used to share the texture between EGLContexts on two - * different threads. This serves as an alternative to sharing the contexts - * but is only used if GL and EGL support the required extensions. - */ - EGLImageKHR m_eglImage; - /** - * This flag is used to determine if the eglImage has been updated. This - * signals the consumer thread to rebind the targetTexture to the new image. - */ - bool m_isNewImage; - /** - * The sync allows the consumer to release the lock prior to the commands - * executing on the GPU. Prior to releasing the lock the consumer creates - * a sync object and stores it here. After locking the texture the client - * must check that the sync has completed prior to manipulating the texture. - * This value is only used if the proper EGL extensions are supported. - */ - EGLSyncKHR m_syncObject; - - EGLDisplay m_display; - - bool m_supportsEGLImage; - bool m_supportsEGLFenceSyncKHR; -}; - -} // namespace WebCore - -#endif // SharedTexture_h diff --git a/WebCore/platform/graphics/android/SkBitmapRef.h b/WebCore/platform/graphics/android/SkBitmapRef.h deleted file mode 100644 index 2a6e59e..0000000 --- a/WebCore/platform/graphics/android/SkBitmapRef.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 SkBitmapRef_DEFINED -#define SkBitmapRef_DEFINED - -#include "SkRefCnt.h" -#include "SkBitmap.h" - -class SkBitmapRef : public SkRefCnt { -public: - SkBitmapRef() : fOrigWidth(0), fOrigHeight(0), fAccessed(false) {} - explicit SkBitmapRef(const SkBitmap& src) - : fBitmap(src), - fOrigWidth(src.width()), - fOrigHeight(src.height()), - fAccessed(false) {} - - const SkBitmap& bitmap() const { return fBitmap; } - SkBitmap& bitmap() { return fBitmap; } - - int origWidth() const { return fOrigWidth; } - int origHeight() const { return fOrigHeight; } - - void setOrigSize(int width, int height) { - fOrigWidth = width; - fOrigHeight = height; - } - // return true if this is not the first access - // mark it true so all subsequent calls return true - bool accessed() { bool result = fAccessed; - fAccessed = true; return result; } - -private: - SkBitmap fBitmap; - int fOrigWidth, fOrigHeight; - bool fAccessed; -}; - -#endif diff --git a/WebCore/platform/graphics/android/TextureOwner.h b/WebCore/platform/graphics/android/TextureOwner.h deleted file mode 100644 index aebbf90..0000000 --- a/WebCore/platform/graphics/android/TextureOwner.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 TextureOwner_h -#define TextureOwner_h - -namespace WebCore { - -class TiledPage; -class BackedDoubleBufferedTexture; - -class TextureOwner { -public: - virtual ~TextureOwner() { } - virtual bool removeTexture(BackedDoubleBufferedTexture* texture) = 0; - virtual TiledPage* page() = 0; -}; - -} - -#endif // TextureOwner_h diff --git a/WebCore/platform/graphics/android/TexturesGenerator.cpp b/WebCore/platform/graphics/android/TexturesGenerator.cpp deleted file mode 100644 index e6bef6a..0000000 --- a/WebCore/platform/graphics/android/TexturesGenerator.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "TexturesGenerator.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "BaseLayerAndroid.h" -#include "GLUtils.h" -#include "PaintLayerOperation.h" -#include "TilesManager.h" - -#ifdef DEBUG - -#include <cutils/log.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TexturesGenerator", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -namespace WebCore { - -void TexturesGenerator::scheduleOperation(QueuedOperation* operation) -{ - { - android::Mutex::Autolock lock(mRequestedOperationsLock); - mRequestedOperations.append(operation); - } - mRequestedOperationsCond.signal(); -} - -void TexturesGenerator::removeOperationsForPage(TiledPage* page) -{ - removeOperationsForFilter(new PageFilter(page)); -} - -void TexturesGenerator::removePaintOperationsForPage(TiledPage* page, bool waitForRunning) -{ - removeOperationsForFilter(new PagePaintFilter(page), waitForRunning); -} - -void TexturesGenerator::removeOperationsForBaseLayer(BaseLayerAndroid* layer) -{ - removeOperationsForFilter(new PaintLayerBaseFilter(layer)); -} - -void TexturesGenerator::removeOperationsForTexture(LayerTexture* texture) -{ - removeOperationsForFilter(new PaintLayerTextureFilter(texture)); -} - -void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter) -{ - removeOperationsForFilter(filter, true); -} - -void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool waitForRunning) -{ - android::Mutex::Autolock lock(mRequestedOperationsLock); - for (unsigned int i = 0; i < mRequestedOperations.size();) { - QueuedOperation* operation = mRequestedOperations[i]; - if (filter->check(operation)) { - mRequestedOperations.remove(i); - delete operation; - } else { - i++; - } - } - - if (waitForRunning) { - QueuedOperation* operation = m_currentOperation; - if (operation && filter->check(operation)) - m_waitForCompletion = true; - - delete filter; - - // At this point, it means that we are currently executing an operation that - // we want to be removed -- we should wait until it is done, so that - // when we return our caller can be sure that there is no more operations - // in the queue matching the given filter. - while (m_waitForCompletion) - mRequestedOperationsCond.wait(mRequestedOperationsLock); - } else { - delete filter; - } -} - -status_t TexturesGenerator::readyToRun() -{ - TilesManager::instance()->markGeneratorAsReady(); - XLOG("Thread ready to run"); - return NO_ERROR; -} - -// Must be called from within a lock! -QueuedOperation* TexturesGenerator::popNext() -{ - // Priority can change between when it was added and now - // Hence why the entire queue is rescanned - QueuedOperation* current = mRequestedOperations.last(); - int currentPriority = current->priority(); - if (currentPriority < 0) { - mRequestedOperations.removeLast(); - return current; - } - int currentIndex = mRequestedOperations.size() - 1; - // Scan from the back to make removing faster (less items to copy) - for (int i = mRequestedOperations.size() - 2; i >= 0; i--) { - QueuedOperation *next = mRequestedOperations[i]; - int nextPriority = next->priority(); - if (nextPriority < 0) { - // Found a very high priority item, go ahead and just handle it now - mRequestedOperations.remove(i); - return next; - } - if (nextPriority < currentPriority) { - current = next; - currentPriority = nextPriority; - currentIndex = i; - } - } - mRequestedOperations.remove(currentIndex); - return current; -} - -bool TexturesGenerator::threadLoop() -{ - // Check if we have any pending operations. - mRequestedOperationsLock.lock(); - while (!mRequestedOperations.size()) - mRequestedOperationsCond.wait(mRequestedOperationsLock); - - XLOG("threadLoop, got signal"); - mRequestedOperationsLock.unlock(); - - m_currentOperation = 0; - bool stop = false; - while (!stop) { - mRequestedOperationsLock.lock(); - if (mRequestedOperations.size()) - m_currentOperation = popNext(); - mRequestedOperationsLock.unlock(); - - if (m_currentOperation) { - XLOG("threadLoop, painting the request with priority %d", m_currentOperation->priority()); - m_currentOperation->run(); - } - - mRequestedOperationsLock.lock(); - if (m_currentOperation) { - delete m_currentOperation; - m_currentOperation = 0; - } - if (!mRequestedOperations.size()) - stop = true; - if (m_waitForCompletion) { - m_waitForCompletion = false; - mRequestedOperationsCond.signal(); - } - mRequestedOperationsLock.unlock(); - - } - XLOG("threadLoop empty"); - - return true; -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/TexturesGenerator.h b/WebCore/platform/graphics/android/TexturesGenerator.h deleted file mode 100644 index b03f52d..0000000 --- a/WebCore/platform/graphics/android/TexturesGenerator.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 TexturesGenerator_h -#define TexturesGenerator_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "LayerTexture.h" -#include "QueuedOperation.h" -#include "TiledPage.h" -#include <utils/threads.h> - -namespace WebCore { - -using namespace android; - -class BaseLayerAndroid; -class LayerAndroid; - -class TexturesGenerator : public Thread { -public: - TexturesGenerator() : Thread() - , m_waitForCompletion(false) - , m_currentOperation(0) { } - virtual ~TexturesGenerator() { } - virtual status_t readyToRun(); - - void removeOperationsForPage(TiledPage* page); - void removeOperationsForBaseLayer(BaseLayerAndroid* layer); - void removeOperationsForTexture(LayerTexture* texture); - void removePaintOperationsForPage(TiledPage* page, bool waitForRunning); - void removeOperationsForFilter(OperationFilter* filter); - void removeOperationsForFilter(OperationFilter* filter, bool waitForRunning); - - void scheduleOperation(QueuedOperation* operation); - -private: - QueuedOperation* popNext(); - virtual bool threadLoop(); - Vector<QueuedOperation*> mRequestedOperations; - android::Mutex mRequestedOperationsLock; - android::Condition mRequestedOperationsCond; - bool m_waitForCompletion; - QueuedOperation* m_currentOperation; -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) -#endif // TexturesGenerator_h diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp deleted file mode 100644 index 5212871..0000000 --- a/WebCore/platform/graphics/android/TiledPage.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "TiledPage.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "GLUtils.h" -#include "IntRect.h" -#include "PaintTileOperation.h" -#include "TilesManager.h" - -#ifdef DEBUG - -#include <cutils/log.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TiledPage", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -namespace WebCore { - -using namespace android; - -TiledPage::TiledPage(int id, GLWebViewState* state) - : m_baseTiles(0) - , m_baseTileSize(0) - , m_id(id) - , m_scale(1) - , m_invScale(1) - , m_glWebViewState(state) - , m_latestPictureInval(0) - , m_prepare(false) -{ - m_baseTiles = new BaseTile[TilesManager::getMaxTextureAllocation() + 1]; -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("TiledPage"); -#endif -} - -void TiledPage::updateBaseTileSize() -{ - // This value must be at least 1 greater than the max number of allowed - // textures. This is because prepare() asks for a tile before it reserves - // a texture for that tile. If all textures are currently in use by the - // page then there will be no available tile and having the extra tile - // ensures that this does not happen. After claiming the extra tile the call - // to reserveTexture() will cause some other tile in the page to lose it's - // texture and become available, thus ensuring that we always have at least - // one tile that is available. - int baseTileSize = TilesManager::instance()->maxTextureCount() + 1; - if (baseTileSize > m_baseTileSize) - m_baseTileSize = baseTileSize; -} - -TiledPage::~TiledPage() -{ - // In order to delete the page we must ensure that none of its BaseTiles are - // currently painting or scheduled to be painted by the TextureGenerator - TilesManager::instance()->removeOperationsForPage(this); - delete[] m_baseTiles; -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("TiledPage"); -#endif -} - -BaseTile* TiledPage::getBaseTile(int x, int y) const -{ - for (int j = 0; j < m_baseTileSize; j++) { - BaseTile& tile = m_baseTiles[j]; - if (tile.x() == x && tile.y() == y && !tile.isAvailable()) - return &tile; - } - return 0; -} - -void TiledPage::setUsable(bool usable) -{ - for (int j = 0; j < m_baseTileSize; j++) { - BaseTile& tile = m_baseTiles[j]; - tile.setUsable(usable); - } - return; -} - -void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureCount) -{ - // Given the current scale level we need to mark the appropriate tiles as dirty - const float invTileContentWidth = m_scale / TilesManager::tileWidth(); - const float invTileContentHeight = m_scale / TilesManager::tileHeight(); - - const int firstDirtyTileX = static_cast<int>(floorf(inval.x() * invTileContentWidth)); - const int firstDirtyTileY = static_cast<int>(floorf(inval.y() * invTileContentHeight)); - const int lastDirtyTileX = static_cast<int>(ceilf(inval.right() * invTileContentWidth)); - const int lastDirtyTileY = static_cast<int>(ceilf(inval.bottom() * invTileContentHeight)); - - XLOG("Marking X %d-%d and Y %d-%d dirty", firstDirtyTileX, lastDirtyTileX, firstDirtyTileY, lastDirtyTileY); - // We defer marking the tile as dirty until the next time we need to prepare - // to draw. - m_invalRegion.op(firstDirtyTileX, firstDirtyTileY, lastDirtyTileX, lastDirtyTileY, SkRegion::kUnion_Op); - m_invalTilesRegion.op(inval.x(), inval.y(), inval.right(), inval.bottom(), SkRegion::kUnion_Op); - m_latestPictureInval = pictureCount; -} - -void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds) -{ - if (y < 0) - return; - - for (int i = 0; i < tilesInRow; i++) { - int x = firstTileX; - - // If we are goingLeft, we want to schedule the tiles starting from the - // right (and to the left if not). This is because tiles are appended to - // the list and the texture uploader goes through the set front to back. - if (goingLeft) - x += (tilesInRow - 1) - i; - else - x += i; - - if (x < 0) - continue; - - BaseTile* currentTile = 0; - BaseTile* availableTile = 0; - for (int j = 0; j < m_baseTileSize; j++) { - BaseTile& tile = m_baseTiles[j]; - if (tile.x() == x && tile.y() == y) { - currentTile = &tile; - break; - } - if (!availableTile && tile.isAvailable()) - availableTile = &tile; - } - - if (!currentTile && availableTile) { - currentTile = availableTile; - currentTile->setContents(this, x, y); - } - - if (currentTile) { - currentTile->setScale(m_scale); - - // ensure there is a texture associated with the tile and then check to - // see if the texture is dirty and in need of repainting - currentTile->reserveTexture(); - updateTileUsedLevel(tileBounds, *currentTile); - if (currentTile->isDirty() && !currentTile->isRepaintPending()) { - PaintTileOperation *operation = new PaintTileOperation(currentTile); - TilesManager::instance()->scheduleOperation(operation); - } else if (currentTile->isDirty()) { - XLOG("Tile %dx%d is dirty, but awaiting repaint", currentTile->x(), currentTile->y()); - } - } - } -} - -void TiledPage::updateTileUsedLevel(const SkIRect& tileBounds, BaseTile& tile) -{ - const int lastTileX = tileBounds.fRight - 1; - const int lastTileY = tileBounds.fBottom - 1; - - // set the used level of the tile (e.g. distance from the viewport) - int dx = 0; - int dy = 0; - - if (tileBounds.fLeft > tile.x()) - dx = tileBounds.fLeft - tile.x(); - else if (lastTileX < tile.x()) - dx = tile.x() - lastTileX; - - if (tileBounds.fTop > tile.y()) - dy = tileBounds.fTop - tile.y(); - else if (lastTileY < tile.y()) - dy = tile.y() - lastTileY; - - int d = std::max(dx, dy); - - tile.setUsedLevel(d); -} - -void TiledPage::updateTileState(const SkIRect& tileBounds) -{ - if (!m_glWebViewState || tileBounds.isEmpty()) { - m_invalRegion.setEmpty(); - m_invalTilesRegion.setEmpty(); - return; - } - - for (int x = 0; x < m_baseTileSize; x++) { - - BaseTile& tile = m_baseTiles[x]; - - // if the tile no longer has a texture then proceed to the next tile - if (tile.isAvailable()) - continue; - - // if the tile is in the dirty region then we must invalidate it - if (m_invalRegion.contains(tile.x(), tile.y())) - tile.markAsDirty(m_latestPictureInval, m_invalTilesRegion); - - updateTileUsedLevel(tileBounds, tile); - } - - // clear the invalidated region as all tiles within that region have now - // been marked as dirty. - m_invalRegion.setEmpty(); - m_invalTilesRegion.setEmpty(); -} - -void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds) -{ - if (!m_glWebViewState) - return; - - // update the tiles distance from the viewport - updateTileState(tileBounds); - m_prepare = true; - m_scrollingDown = goingDown; - - int firstTileX = tileBounds.fLeft; - int firstTileY = tileBounds.fTop; - int nbTilesWidth = tileBounds.width(); - int nbTilesHeight = tileBounds.height(); - - int lastTileX = tileBounds.fRight - 1; - int lastTileY = tileBounds.fBottom - 1; - - const int baseContentHeight = m_glWebViewState->baseContentHeight(); - const int baseContentWidth = m_glWebViewState->baseContentWidth(); - - // Expand number of tiles to allow tiles outside of viewport to be prepared for - // smoother scrolling. - int nTilesToPrepare = nbTilesWidth * nbTilesHeight; - int nMaxTilesPerPage = m_baseTileSize / 2; - int expandX = TilesManager::instance()->expandedTileBoundsX(); - int expandY = TilesManager::instance()->expandedTileBoundsY(); - if (nTilesToPrepare + (nbTilesHeight * expandX * 2) <= nMaxTilesPerPage) { - firstTileX -= expandX; - lastTileX += expandX; - nbTilesWidth += expandX * 2; - } - if (nTilesToPrepare + (nbTilesWidth * expandY * 2) <= nMaxTilesPerPage) { - firstTileY -= expandY; - lastTileY += expandY; - nbTilesHeight += expandY * 2; - } - m_expandedTileBounds.fLeft = firstTileX; - m_expandedTileBounds.fTop = firstTileY; - m_expandedTileBounds.fRight = lastTileX; - m_expandedTileBounds.fBottom = lastTileY; - - for (int i = 0; i < nbTilesHeight; i++) - prepareRow(goingLeft, nbTilesWidth, firstTileX, firstTileY + i, tileBounds); -} - -bool TiledPage::ready(const SkIRect& tileBounds, float scale) -{ - if (!m_glWebViewState) - return false; - - if (!m_invalRegion.isEmpty() && !m_prepare) - return false; - - if (m_scale != scale) - return false; - - for (int x = tileBounds.fLeft; x < tileBounds.fRight; x++) { - for (int y = tileBounds.fTop; y < tileBounds.fBottom; y++) { - BaseTile* t = getBaseTile(x, y); - if (!t || !t->isTileReady()) - return false; - } - } - m_prepare = false; - return true; -} - -void TiledPage::draw(float transparency, const SkIRect& tileBounds) -{ - if (!m_glWebViewState) - return; - - const float tileWidth = TilesManager::tileWidth() * m_invScale; - const float tileHeight = TilesManager::tileHeight() * m_invScale; - - SkIRect actualTileBounds = tileBounds; - actualTileBounds.fTop -= TilesManager::instance()->expandedTileBoundsY(); - actualTileBounds.fBottom += TilesManager::instance()->expandedTileBoundsY(); - actualTileBounds.fLeft -= TilesManager::instance()->expandedTileBoundsX(); - actualTileBounds.fRight += TilesManager::instance()->expandedTileBoundsX(); - - for (int j = 0; j < m_baseTileSize; j++) { - BaseTile& tile = m_baseTiles[j]; - if (actualTileBounds.contains(tile.x(), tile.y())) { - - SkRect rect; - rect.fLeft = tile.x() * tileWidth; - rect.fTop = tile.y() * tileHeight; - rect.fRight = rect.fLeft + tileWidth; - rect.fBottom = rect.fTop + tileHeight; - - tile.draw(transparency, rect, m_scale); - } - } -} - -unsigned int TiledPage::paintBaseLayerContent(SkCanvas* canvas) -{ - if (m_glWebViewState) - return m_glWebViewState->paintBaseLayerContent(canvas); - return 0; -} - -TiledPage* TiledPage::sibling() -{ - if (!m_glWebViewState) - return 0; - return m_glWebViewState->sibling(this); -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/TiledPage.h b/WebCore/platform/graphics/android/TiledPage.h deleted file mode 100644 index 1aa3e61..0000000 --- a/WebCore/platform/graphics/android/TiledPage.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 TiledPage_h -#define TiledPage_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "BaseTile.h" -#include "SkCanvas.h" -#include "SkRegion.h" - -namespace WebCore { - -class GLWebViewState; -class IntRect; - -/** - * The TiledPage represents a map of BaseTiles covering the viewport. Each - * GLWebViewState contains two TiledPages, one to display the page at the - * current scale factor, and another in the background that we use to paint the - * page at a different scale factor. For instance, when we zoom using one - * TiledPage its tiles are scaled in hardware and therefore are subject to a - * loss of quality. To address this when the user finishes zooming we paint the - * background TilePage at the new scale factor. When the background TilePage is - * ready, we swap it with the currently displaying TiledPage. - */ -class TiledPage { -public: - TiledPage(int id, GLWebViewState* state); - ~TiledPage(); - - // returns the other TiledPage who shares the same GLWebViewState - TiledPage* sibling(); - - // prepare the page for display on the screen - void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds); - // check to see if the page is ready for display - bool ready(const SkIRect& tileBounds, float scale); - // draw the page on the screen - void draw(float transparency, const SkIRect& tileBounds); - - // used by individual tiles to generate the bitmap for their tile - unsigned int paintBaseLayerContent(SkCanvas*); - // used by individual tiles to get the information about the current picture - GLWebViewState* glWebViewState() { return m_glWebViewState; } - - float scale() const { return m_scale; } - void setScale(float scale) { m_scale = scale; m_invScale = 1 / scale; } - - void invalidateRect(const IntRect& invalRect, const unsigned int pictureCount); - void setUsable(bool usable); - void updateBaseTileSize(); - bool scrollingDown() { return m_scrollingDown; } - SkIRect* expandedTileBounds() { return &m_expandedTileBounds; } - -private: - void updateTileState(const SkIRect& tileBounds); - void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds); - void updateTileUsedLevel(const SkIRect& tileBounds, BaseTile& tile); - - BaseTile* getBaseTile(int x, int y) const; - - // array of tiles used to compose a page. The tiles are allocated in the - // constructor to prevent them from potentially being allocated on the stack - BaseTile* m_baseTiles; - // stores the number of tiles in the m_baseTiles array. This enables us to - // quickly iterate over the array without have to check it's size - int m_baseTileSize; - int m_id; - float m_scale; - float m_invScale; - GLWebViewState* m_glWebViewState; - - // used to identify the tiles that have been invalidated (marked dirty) since - // the last time updateTileState() has been called. The region is stored in - // terms of the (x,y) coordinates used to determine the location of the tile - // within the page, not in content/view pixel coordinates. - SkRegion m_invalRegion; - - // inval regions in content coordinates - SkRegion m_invalTilesRegion; - unsigned int m_latestPictureInval; - bool m_prepare; - bool m_scrollingDown; - SkIRect m_expandedTileBounds; -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) -#endif // TiledPage_h diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp deleted file mode 100644 index 5a9a164..0000000 --- a/WebCore/platform/graphics/android/TilesManager.cpp +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "TilesManager.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "BaseTile.h" -#include "SkCanvas.h" -#include "SkDevice.h" -#include "SkPaint.h" -#include <cutils/atomic.h> - -#ifdef DEBUG - -#include <cutils/log.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TilesManager", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -// Important: We need at least twice as much textures as is needed to cover -// one viewport, otherwise the allocation may stall. -// We need n textures for one TiledPage, and another n textures for the -// second page used when scaling. -// In our case, we use 300x300 textures. On the tablet, this equates to -// at least 5 * 3 = 15 textures. We also enable offscreen textures to a maximum -// of 101 textures used (i.e. ~70Mb max, accounting for the double buffer textures) -#define EXPANDED_TILE_BOUNDS_X 1 -#define EXPANDED_TILE_BOUNDS_Y 2 -#define MAX_TEXTURE_ALLOCATION 3+(5+EXPANDED_TILE_BOUNDS_X*2)*(3+EXPANDED_TILE_BOUNDS_Y*2)*2 -#define TILE_WIDTH 300 -#define TILE_HEIGHT 300 - -// Define a maximum amount of ram used by layers -#define MAX_LAYERS_ALLOCATION 33554432 // 32Mb -// Define a maximum amount of ram used by one layer -#define MAX_LAYER_ALLOCATION 8388608 // 8Mb -#define BYTES_PER_PIXEL 4 // 8888 config - -namespace WebCore { - -GLint TilesManager::getMaxTextureSize() -{ - static GLint maxTextureSize = 0; - if (!maxTextureSize) - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); - return maxTextureSize; -} - -int TilesManager::getMaxTextureAllocation() -{ - return MAX_TEXTURE_ALLOCATION; -} - -TilesManager::TilesManager() - : m_layersMemoryUsage(0) - , m_maxTextureCount(0) - , m_expandedTileBounds(false) - , m_generatorReady(false) - , m_showVisualIndicator(false) -{ - XLOG("TilesManager ctor"); - m_textures.reserveCapacity(MAX_TEXTURE_ALLOCATION); - m_tilesBitmap = new SkBitmap(); - m_tilesBitmap->setConfig(SkBitmap::kARGB_8888_Config, tileWidth(), tileHeight()); - m_tilesBitmap->allocPixels(); - m_tilesBitmap->eraseColor(0); - m_pixmapsGenerationThread = new TexturesGenerator(); - m_pixmapsGenerationThread->run("TexturesGenerator"); -} - -void TilesManager::allocateTiles() -{ - int nbTexturesToAllocate = m_maxTextureCount - m_textures.size(); - XLOG("%d tiles to allocate (%d textures planned)", nbTexturesToAllocate, m_maxTextureCount); - int nbTexturesAllocated = 0; - for (int i = 0; i < nbTexturesToAllocate; i++) { - BackedDoubleBufferedTexture* texture = new BackedDoubleBufferedTexture( - tileWidth(), tileHeight(), m_tilesBitmap); - // the atomic load ensures that the texture has been fully initialized - // before we pass a pointer for other threads to operate on - BackedDoubleBufferedTexture* loadedTexture = - reinterpret_cast<BackedDoubleBufferedTexture*>( - android_atomic_acquire_load(reinterpret_cast<int32_t*>(&texture))); - m_textures.append(loadedTexture); - nbTexturesAllocated++; - } - XLOG("allocated %d textures", nbTexturesAllocated); -} - -void TilesManager::printTextures() -{ -#ifdef DEBUG - XLOG("++++++"); - for (unsigned int i = 0; i < m_textures.size(); i++) { - BackedDoubleBufferedTexture* texture = m_textures[i]; - BaseTile* o = 0; - if (texture->owner()) - o = (BaseTile*) texture->owner(); - int x = -1; - int y = -1; - if (o) { - x = o->x(); - y = o->y(); - } - XLOG("[%d] texture %x usedLevel: %d busy: %d owner: %x (%d, %d) page: %x scale: %.2f", - i, texture, texture->usedLevel(), - texture->busy(), o, x, y, o ? o->page() : 0, o ? o->scale() : 0); - } - XLOG("------"); -#endif // DEBUG -} - -void TilesManager::resetTextureUsage(TiledPage* page) -{ - android::Mutex::Autolock lock(m_texturesLock); - for (unsigned int i = 0; i < m_textures.size(); i++) { - BackedDoubleBufferedTexture* texture = m_textures[i]; - TextureOwner* owner = texture->owner(); - if (owner) { - if (owner->page() == page) - texture->setUsedLevel(-1); - } - } -} - -BackedDoubleBufferedTexture* TilesManager::getAvailableTexture(BaseTile* owner) -{ - android::Mutex::Autolock lock(m_texturesLock); - - // Sanity check that the tile does not already own a texture - if (owner->texture() && owner->texture()->owner() == owner) { - owner->texture()->setUsedLevel(0); - XLOG("same owner (%d, %d), getAvailableTexture(%x) => texture %x", - owner->x(), owner->y(), owner, owner->texture()); - return owner->texture(); - } - - // The heuristic for selecting a texture is as follows: - // 1. return an unused texture if one exists - // 2. return the farthest texture from the viewport (from any tiled page) - // 3. return any texture not used by the tile's page or the page's sibiling - // - // The texture level indicates a tiles closeness to the current viewport - BackedDoubleBufferedTexture* farthestTexture = 0; - int farthestTextureLevel = 0; - const unsigned int max = m_textures.size(); - for (unsigned int i = 0; i < max; i++) { - BackedDoubleBufferedTexture* texture = m_textures[i]; - if (texture->usedLevel() == -1) { // found an unused texture, grab it - farthestTexture = texture; - break; - } - if (farthestTextureLevel < texture->usedLevel()) { - farthestTextureLevel = texture->usedLevel(); - farthestTexture = texture; - } - } - if (farthestTexture && farthestTexture->acquire(owner)) { - XLOG("farthest texture, getAvailableTexture(%x) => texture %x (level %d)", - owner, farthestTexture, farthestTexture->usedLevel()); - farthestTexture->setUsedLevel(0); - return farthestTexture; - } - - // At this point, all textures are used or we failed to aquire the farthest - // texture. Now let's just grab a texture not in use by either of the two - // tiled pages associated with this view. - TiledPage* currentPage = owner->page(); - TiledPage* nextPage = currentPage->sibling(); - for (unsigned int i = 0; i < max; i++) { - BackedDoubleBufferedTexture* texture = m_textures[i]; - if (texture->tryAcquire(owner, currentPage, nextPage)) { - XLOG("grab a texture that wasn't ours, (%x != %x) at %d => texture %x", - owner->page(), texture->owner()->page(), i, texture); - texture->setUsedLevel(0); - return texture; - } - } - - XLOG("Couldn't find an available texture for BaseTile %x (%d, %d) !!!", - owner, owner->x(), owner->y()); -#ifdef DEBUG - printTextures(); -#endif // DEBUG - return 0; -} - -LayerTexture* TilesManager::getExistingTextureForLayer(LayerAndroid* layer, - const IntRect& rect, - bool any, - LayerTexture* texture) -{ - android::Mutex::Autolock lock(m_texturesLock); - LayerTexture* best = 0; - unsigned newestPictureUsed = 0; - for (unsigned int i = 0; i< m_layersTextures.size(); i++) { - if (m_layersTextures[i]->id() != layer->uniqueId()) - continue; - if (!any && rect != m_layersTextures[i]->rect()) - continue; - if (!any && layer->getScale() != m_layersTextures[i]->scale()) - continue; - if (any && texture == m_layersTextures[i]) - continue; - - if (m_layersTextures[i]->ready()) { - unsigned int pictureUsed = m_layersTextures[i]->pictureUsed(); - if (pictureUsed >= newestPictureUsed) { - newestPictureUsed = pictureUsed; - best = m_layersTextures[i]; - } - } - - XLOG("return layer %d (%x) for tile %d (%x)", - i, m_layersTextures[i], - layer->uniqueId(), layer); - } - - if (best && best->acquire(layer, any)) - return best; - return 0; -} - -void TilesManager::printLayersTextures(const char* s) -{ -#ifdef DEBUG - XLOG(">>> print layers textures (%s)", s); - for (unsigned int i = 0; i< m_layersTextures.size(); i++) { - XLOG("[%d] %s, texture %x for layer %d (w: %.2f, h: %.2f), owner: %x", - i, s, m_layersTextures[i], - m_layersTextures[i]->id(), - m_layersTextures[i]->getSize().fWidth, - m_layersTextures[i]->getSize().fHeight, - m_layersTextures[i]->owner()); - } - XLOG("<<< print layers textures (%s)", s); -#endif -} - -void TilesManager::cleanupLayersTextures(LayerAndroid* layer, bool forceCleanup) -{ - android::Mutex::Autolock lock(m_texturesLock); - SkLayer* rootLayer = 0; - if (layer) - rootLayer = layer->getRootLayer(); -#ifdef DEBUG - if (forceCleanup) - XLOG("FORCE cleanup"); - XLOG("before cleanup, memory %d", m_layersMemoryUsage); - printLayersTextures("before cleanup"); -#endif - for (unsigned int i = 0; i< m_layersTextures.size();) { - LayerTexture* texture = m_layersTextures[i]; - - if (forceCleanup && texture->owner()) { - LayerAndroid* textureLayer = - static_cast<LayerAndroid*>(texture->owner()); - if (textureLayer->getRootLayer() != rootLayer) { - // We only want to force destroy layers - // that are not used by the current page - XLOG("force removing texture %x for layer %d", - texture, textureLayer->uniqueId()); - textureLayer->removeTexture(texture); - } - } - - // We only try to destroy textures that have no owners. - // This could be due to: - // 1) - the LayerAndroid dtor has been called (i.e. when swapping - // a LayerAndroid tree with a new one) - // 2) - or due to the above code, forcing a destroy. - // If the texture has been forced to be released (case #2), it - // could still be in use (in the middle of being painted). So we - // need to check that's not the case by checking busy(). See - // LayerAndroid::paintBitmapGL(). - if (!texture->owner() && !texture->busy()) { - m_layersMemoryUsage -= (int) texture->getSize().fWidth - * (int) texture->getSize().fHeight * BYTES_PER_PIXEL; - m_layersTextures.remove(i); - // We can destroy the texture. We first remove it from the textures - // list, and then remove any queued drawing. At this point we know - // the texture has been removed from the layer, and that it's not - // busy, so it's safe to delete. - m_pixmapsGenerationThread->removeOperationsForTexture(texture); - XLOG("delete texture %x", texture); - delete texture; - } else { - // only iterate if we don't delete (if we delete, no need to as we - // remove the element from the array) - i++; - } - } -#ifdef DEBUG - printLayersTextures("after cleanup"); - XLOG("after cleanup, memory %d", m_layersMemoryUsage); -#endif -} - -LayerTexture* TilesManager::createTextureForLayer(LayerAndroid* layer, const IntRect& rect) -{ - int w = rect.width() * layer->getScale(); - int h = rect.height() * layer->getScale(); - unsigned int size = w * h * BYTES_PER_PIXEL; - - // We will not allocate textures that: - // 1) cannot be handled by the graphic card (maxTextureSize & - // totalMaxTextureSize) - // 2) will make us go past our texture limit (MAX_LAYERS_ALLOCATION) - - GLint maxTextureSize = getMaxTextureSize(); - unsigned totalMaxTextureSize = maxTextureSize * maxTextureSize * BYTES_PER_PIXEL; - bool large = w > maxTextureSize || h > maxTextureSize || size > totalMaxTextureSize; - XLOG("createTextureForLayer(%d) @scale %.2f => %d, %d (too large? %x)", layer->uniqueId(), - layer->getScale(), w, h, large); - - // For now just return 0 if too large - if (large) - return 0; - - if (w == 0 || h == 0) // empty layer - return 0; - - if (m_layersMemoryUsage + size > MAX_LAYERS_ALLOCATION) - cleanupLayersTextures(layer, true); - - LayerTexture* texture = new LayerTexture(w, h); - texture->setId(layer->uniqueId()); - texture->setRect(rect); - texture->setScale(layer->getScale()); - - android::Mutex::Autolock lock(m_texturesLock); - m_layersTextures.append(texture); - texture->acquire(layer); - m_layersMemoryUsage += size; - return texture; -} - -int TilesManager::maxLayersAllocation() -{ - return MAX_LAYERS_ALLOCATION; -} - -int TilesManager::maxLayerAllocation() -{ - return MAX_LAYER_ALLOCATION; -} - -int TilesManager::maxTextureCount() -{ - android::Mutex::Autolock lock(m_texturesLock); - return m_maxTextureCount; -} - -void TilesManager::setMaxTextureCount(int max) -{ - XLOG("setMaxTextureCount: %d (current: %d, total:%d)", - max, m_maxTextureCount, MAX_TEXTURE_ALLOCATION); - if (m_maxTextureCount && - (max > MAX_TEXTURE_ALLOCATION || - max <= m_maxTextureCount)) - return; - - android::Mutex::Autolock lock(m_texturesLock); - - if (max < MAX_TEXTURE_ALLOCATION) - m_maxTextureCount = max; - else - m_maxTextureCount = MAX_TEXTURE_ALLOCATION; - - allocateTiles(); -} - -float TilesManager::tileWidth() -{ - return TILE_WIDTH; -} - -float TilesManager::tileHeight() -{ - return TILE_HEIGHT; -} - -int TilesManager::expandedTileBoundsX() { - return m_expandedTileBounds ? EXPANDED_TILE_BOUNDS_X : 0; -} - -int TilesManager::expandedTileBoundsY() { - return m_expandedTileBounds ? EXPANDED_TILE_BOUNDS_Y : 0; -} - -TilesManager* TilesManager::instance() -{ - if (!gInstance) { - gInstance = new TilesManager(); - XLOG("instance(), new gInstance is %x", gInstance); - XLOG("Waiting for the generator..."); - gInstance->waitForGenerator(); - XLOG("Generator ready!"); - } - return gInstance; -} - -TilesManager* TilesManager::gInstance = 0; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h deleted file mode 100644 index 6d49cca..0000000 --- a/WebCore/platform/graphics/android/TilesManager.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2010, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 TilesManager_h -#define TilesManager_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "BackedDoubleBufferedTexture.h" -#include "BaseTile.h" -#include "LayerAndroid.h" -#include "LayerTexture.h" -#include "ShaderProgram.h" -#include "TexturesGenerator.h" -#include "TiledPage.h" -#include <utils/threads.h> - -namespace WebCore { - -class TilesManager { -public: - static TilesManager* instance(); - static GLint getMaxTextureSize(); - static int getMaxTextureAllocation(); - - static bool hardwareAccelerationEnabled() - { - return gInstance != 0; - } - - void removeOperationsForPage(TiledPage* page) - { - m_pixmapsGenerationThread->removeOperationsForPage(page); - } - - void removePaintOperationsForPage(TiledPage* page, bool waitForCompletion) - { - m_pixmapsGenerationThread->removePaintOperationsForPage(page, waitForCompletion); - } - - void removeOperationsForBaseLayer(BaseLayerAndroid* layer) - { - m_pixmapsGenerationThread->removeOperationsForBaseLayer(layer); - } - - void removeOperationsForTexture(LayerTexture* texture) - { - m_pixmapsGenerationThread->removeOperationsForTexture(texture); - } - - void scheduleOperation(QueuedOperation* operation) - { - m_pixmapsGenerationThread->scheduleOperation(operation); - } - - ShaderProgram* shader() { return &m_shader; } - - BackedDoubleBufferedTexture* getAvailableTexture(BaseTile* owner); - - void printLayersTextures(const char* s); - void cleanupLayersTextures(LayerAndroid* layer, bool forceCleanup = false); - LayerTexture* getExistingTextureForLayer(LayerAndroid* layer, const IntRect& rect, - bool any = false, LayerTexture* texture = 0); - LayerTexture* createTextureForLayer(LayerAndroid* layer, const IntRect& rect); - - void markGeneratorAsReady() - { - { - android::Mutex::Autolock lock(m_generatorLock); - m_generatorReady = true; - } - m_generatorReadyCond.signal(); - } - - void printTextures(); - - void resetTextureUsage(TiledPage* page); - - int maxLayersAllocation(); - int maxLayerAllocation(); - int maxTextureCount(); - void setMaxTextureCount(int max); - static float tileWidth(); - static float tileHeight(); - int expandedTileBoundsX(); - int expandedTileBoundsY(); - - void allocateTiles(); - - void setExpandedTileBounds(bool enabled) { - m_expandedTileBounds = enabled; - } - - bool getShowVisualIndicator() { - return m_showVisualIndicator; - } - - void setShowVisualIndicator(bool showVisualIndicator) { - m_showVisualIndicator = showVisualIndicator; - } - -private: - - TilesManager(); - - void waitForGenerator() - { - android::Mutex::Autolock lock(m_generatorLock); - while (!m_generatorReady) - m_generatorReadyCond.wait(m_generatorLock); - } - - Vector<BackedDoubleBufferedTexture*> m_textures; - Vector<LayerTexture*> m_layersTextures; - - unsigned int m_layersMemoryUsage; - - int m_maxTextureCount; - bool m_expandedTileBounds; - - bool m_generatorReady; - - bool m_showVisualIndicator; - - sp<TexturesGenerator> m_pixmapsGenerationThread; - - android::Mutex m_texturesLock; - android::Mutex m_generatorLock; - android::Condition m_generatorReadyCond; - - static TilesManager* gInstance; - - ShaderProgram m_shader; - SkBitmap* m_tilesBitmap; -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) -#endif // TilesManager_h diff --git a/WebCore/platform/graphics/android/VideoLayerAndroid.cpp b/WebCore/platform/graphics/android/VideoLayerAndroid.cpp deleted file mode 100644 index 32e518d..0000000 --- a/WebCore/platform/graphics/android/VideoLayerAndroid.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2011 The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "VideoLayerAndroid.h" - -#include "RenderSkinMediaButton.h" -#include "TilesManager.h" -#include <GLES2/gl2.h> -#include <gui/SurfaceTexture.h> - -#if USE(ACCELERATED_COMPOSITING) - -#ifdef DEBUG -#include <cutils/log.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "VideoLayerAndroid", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -namespace WebCore { - -GLuint VideoLayerAndroid::m_spinnerOuterTextureId = 0; -GLuint VideoLayerAndroid::m_spinnerInnerTextureId = 0; -GLuint VideoLayerAndroid::m_posterTextureId = 0; -GLuint VideoLayerAndroid::m_backgroundTextureId = 0; -bool VideoLayerAndroid::m_createdTexture = false; - -double VideoLayerAndroid::m_rotateDegree = 0; - -const IntRect VideoLayerAndroid::buttonRect(0, 0, IMAGESIZE, IMAGESIZE); - -VideoLayerAndroid::VideoLayerAndroid() - : LayerAndroid((RenderLayer*)0) -{ - init(); -} - -VideoLayerAndroid::VideoLayerAndroid(const VideoLayerAndroid& layer) - : LayerAndroid(layer) -{ - init(); -} - -void VideoLayerAndroid::init() -{ - // m_surfaceTexture is only useful on UI thread, no need to copy. - // And it will be set at setBaseLayer timeframe - - m_playerState = INITIALIZED; - m_textureId = 0; -} - -// We can use this function to set the Layer to point to surface texture. -void VideoLayerAndroid::setSurfaceTexture(sp<SurfaceTexture> texture, - int textureName, PlayerState playerState) -{ - m_surfaceTexture = texture; - m_textureId = textureName; - - m_playerState = playerState; -} - -GLuint VideoLayerAndroid::createSpinnerInnerTexture() -{ - return createTextureFromImage(RenderSkinMediaButton::SPINNER_INNER); -} - -GLuint VideoLayerAndroid::createSpinnerOuterTexture() -{ - return createTextureFromImage(RenderSkinMediaButton::SPINNER_OUTER); -} - -GLuint VideoLayerAndroid::createPosterTexture() -{ - return createTextureFromImage(RenderSkinMediaButton::VIDEO); -} - -GLuint VideoLayerAndroid::createTextureFromImage(int buttonType) -{ - SkRect rect = SkRect(buttonRect); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); - bitmap.allocPixels(); - bitmap.eraseColor(0); - - SkCanvas canvas(bitmap); - canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode); - RenderSkinMediaButton::Draw(&canvas, buttonRect, buttonType, true); - - GLuint texture; - glGenTextures(1, &texture); - - GLUtils::createTextureWithBitmap(texture, bitmap); - bitmap.reset(); - return texture; -} - -GLuint VideoLayerAndroid::createBackgroundTexture() -{ - GLuint texture; - glGenTextures(1, &texture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - GLubyte pixels[4 *3] = { - 128, 128, 128, - 128, 128, 128, - 128, 128, 128, - 128, 128, 128 - }; - glBindTexture(GL_TEXTURE_2D, texture); - GLUtils::checkGlError("glBindTexture"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels); - GLUtils::checkGlError("glTexImage2D"); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - return texture; -} - -bool VideoLayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) -{ - // Lazily allocated the textures. - if (!m_createdTexture) { - m_backgroundTextureId = createBackgroundTexture(); - m_spinnerOuterTextureId = createSpinnerOuterTexture(); - m_spinnerInnerTextureId = createSpinnerInnerTexture(); - m_posterTextureId = createPosterTexture(); - m_createdTexture = true; - } - - SkRect rect = SkRect::MakeSize(getSize()); - GLfloat surfaceMatrix[16]; - - SkRect innerRect = SkRect(buttonRect); - if (innerRect.contains(rect)) - innerRect = rect; - - innerRect.offset((rect.width() - IMAGESIZE) / 2 , (rect.height() - IMAGESIZE) / 2); - - // Draw the poster image, the progressing image or the Video depending - // on the player's state. - if (m_playerState == PREPARING) { - // Show the progressing animation, with two rotating circles - TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), rect, - m_backgroundTextureId, - 0.5, true); - - TransformationMatrix addReverseRotation; - TransformationMatrix addRotation = drawTransform(); - addRotation.translate(innerRect.fLeft, innerRect.fTop); - addRotation.translate(IMAGESIZE / 2, IMAGESIZE / 2); - addReverseRotation = addRotation; - addRotation.rotate(m_rotateDegree); - addRotation.translate(-IMAGESIZE / 2, -IMAGESIZE / 2); - - SkRect size = SkRect::MakeWH(innerRect.width(), innerRect.height()); - TilesManager::instance()->shader()->drawLayerQuad(addRotation, size, - m_spinnerOuterTextureId, - 1, true); - - addReverseRotation.rotate(-m_rotateDegree); - addReverseRotation.translate(-IMAGESIZE / 2, -IMAGESIZE / 2); - - TilesManager::instance()->shader()->drawLayerQuad(addReverseRotation, size, - m_spinnerInnerTextureId, - 1, true); - - m_rotateDegree += ROTATESTEP; - - } else if (m_playerState == PLAYING && m_surfaceTexture.get()) { - // Show the real video. - m_surfaceTexture->updateTexImage(); - m_surfaceTexture->getTransformMatrix(surfaceMatrix); - TilesManager::instance()->shader()->drawVideoLayerQuad(drawTransform(), - surfaceMatrix, - rect, m_textureId); - } else { - // Show the poster - TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), rect, - m_backgroundTextureId, - 0.5, true); - - TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), innerRect, - m_posterTextureId, - 1, true); - } - - return drawChildrenGL(glWebViewState, matrix); -} - -} -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/VideoLayerAndroid.h b/WebCore/platform/graphics/android/VideoLayerAndroid.h deleted file mode 100644 index eac565e..0000000 --- a/WebCore/platform/graphics/android/VideoLayerAndroid.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2011 The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 VideoLayerAndroid_h -#define VideoLayerAndroid_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "GLUtils.h" -#include "LayerAndroid.h" -#include <jni.h> - -namespace android { -class SurfaceTexture; -} - -namespace WebCore { - -// state get from UI thread to decide which image to draw. -// PREPARING should be the progressing image -// PLAYING will be the Video (Surface Texture). -// Otherwise will draw a static image. -// NOTE: These values are matching the ones in HTML5VideoView.java -// Please keep them in sync when changed here. -typedef enum {INITIALIZED, PREPARING, PREPARED, PLAYING} PlayerState; - -class VideoLayerAndroid : public LayerAndroid { - -public: - VideoLayerAndroid(); - explicit VideoLayerAndroid(const VideoLayerAndroid& layer); - - virtual bool isVideo() const { return true; } - virtual LayerAndroid* copy() const { return new VideoLayerAndroid(*this); } - - // The following 3 functions are called in UI thread only. - virtual bool drawGL(GLWebViewState*, SkMatrix& matrix); - void setSurfaceTexture(sp<SurfaceTexture> texture, int textureName, PlayerState playerState); - GLuint createBackgroundTexture(); - GLuint createSpinnerOuterTexture(); - GLuint createSpinnerInnerTexture(); - GLuint createPosterTexture(); - -private: - GLuint createTextureFromImage(int buttonType); - void init(); - // Surface texture for showing the video is actually allocated in Java side - // and passed into this native code. - GLuint m_textureId; - sp<android::SurfaceTexture> m_surfaceTexture; - - PlayerState m_playerState; - - // Texture for showing the static image will be created at native side. - // TODO: instead using a shared texture, we could make a texture pool to - // show different screen shots for different videos - static bool m_createdTexture; - static GLuint m_backgroundTextureId; - static GLuint m_posterTextureId; - static GLuint m_spinnerOuterTextureId; - static GLuint m_spinnerInnerTextureId; - - static double m_rotateDegree; - - static const int ROTATESTEP = 12; - static const int IMAGESIZE = 64; - static const IntRect buttonRect; -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) - -#endif // VideoLayerAndroid_h diff --git a/WebCore/platform/graphics/android/VideoListener.h b/WebCore/platform/graphics/android/VideoListener.h deleted file mode 100644 index 7cac6d6..0000000 --- a/WebCore/platform/graphics/android/VideoListener.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef VideoListener_h -#define VideoListener_h - -#if USE(ACCELERATED_COMPOSITING) - -#include <gui/SurfaceTexture.h> -#include <jni.h> -#include <JNIUtility.h> -#include "WebCoreJni.h" - -#ifdef DEBUG - -#include <cutils/log.h> -#include <wtf/text/CString.h> - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "VideoListener", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -namespace WebCore { - -class VideoListener : public android::SurfaceTexture::FrameAvailableListener { - -public: - VideoListener(jobject weakWebViewRef) - : m_weakWebViewRef(weakWebViewRef) - , m_postInvalMethod(0) - , m_frameAvailable(false) - { - if (!m_weakWebViewRef) - return; - - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobject localWebViewRef = env->NewLocalRef(m_weakWebViewRef); - if (localWebViewRef) { - jclass wvClass = env->GetObjectClass(localWebViewRef); - m_postInvalMethod = env->GetMethodID(wvClass, "postInvalidate", "()V"); - env->DeleteLocalRef(wvClass); - env->DeleteLocalRef(localWebViewRef); - } - checkException(env); - } - - virtual void onFrameAvailable() - { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobject localWebViewRef = env->NewLocalRef(m_weakWebViewRef); - if (localWebViewRef) { - env->CallVoidMethod(localWebViewRef, m_postInvalMethod); - env->DeleteLocalRef(localWebViewRef); - } - checkException(env); - if (!m_frameAvailable) { - m_frameAvailable = true; - } - } - - void resetFrameAvailable() { m_frameAvailable = false; } - bool isFrameAvailable() { return m_frameAvailable; } - -private: - jobject m_weakWebViewRef; - jmethodID m_postInvalMethod; - bool m_frameAvailable; -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) -#endif // VideoListener_h diff --git a/WebCore/platform/graphics/android/android_graphics.cpp b/WebCore/platform/graphics/android/android_graphics.cpp deleted file mode 100644 index e50cfec..0000000 --- a/WebCore/platform/graphics/android/android_graphics.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "CachedPrefix.h" -#include "android_graphics.h" -#include "CachedColor.h" -#include "CachedRoot.h" -#include "IntRect.h" -#include "LayerAndroid.h" -#include "SkCanvas.h" -#include "SkCornerPathEffect.h" -#include "SkPath.h" -#include "SkRegion.h" -#include "WebViewCore.h" - -namespace android { - -// The CSS values for the inner and outer widths may be specified as fractions -#define WIDTH_SCALE 0.0625f // 1/16, to offset the scale in CSSStyleSelector - -void CursorRing::draw(SkCanvas* canvas, LayerAndroid* layer, IntRect* inval) -{ - if (!m_lastBounds.isEmpty()) { - *inval = m_lastBounds; - m_lastBounds = IntRect(0, 0, 0, 0); - } -#if USE(ACCELERATED_COMPOSITING) - int layerId = m_node->isInLayer() ? m_frame->layer(m_node)->uniqueId() : -1; - if (layer->uniqueId() != layerId) - return; -#endif - if (canvas->quickReject(m_bounds, SkCanvas::kAA_EdgeType)) { - DBG_NAV_LOGD("canvas->quickReject cursorNode=%d (nodePointer=%p)" - " bounds=(%d,%d,w=%d,h=%d)", m_node->index(), m_node->nodePointer(), - m_bounds.x(), m_bounds.y(), m_bounds.width(), m_bounds.height()); - return; - } - const CachedColor& colors = m_frame->color(m_node); - unsigned rectCount = m_rings.size(); - SkRegion rgn; - SkPath path; - for (unsigned i = 0; i < rectCount; i++) - { - SkRect r(m_rings[i]); - SkIRect ir; - - r.round(&ir); - ir.inset(-colors.outset(), -colors.outset()); - rgn.op(ir, SkRegion::kUnion_Op); - } - rgn.getBoundaryPath(&path); - - SkPaint paint; - paint.setAntiAlias(true); - paint.setPathEffect(new SkCornerPathEffect( - SkIntToScalar(colors.radius())))->unref(); - SkColor outer; - SkColor inner; - if (m_isPressed) { - SkColor pressed; - pressed = colors.fillColor(); - paint.setColor(pressed); - canvas->drawPath(path, paint); - outer = colors.pressedOuterColor(); - inner = colors.pressedInnerColor(); - } else { - outer = colors.selectedOuterColor(); - inner = colors.selectedInnerColor(); - } - paint.setStyle(SkPaint::kStroke_Style); - paint.setStrokeWidth(colors.outerWidth() * WIDTH_SCALE); - paint.setColor(outer); - canvas->drawPath(path, paint); - paint.setStrokeWidth(colors.innerWidth() * WIDTH_SCALE); - paint.setColor(inner); - canvas->drawPath(path, paint); - SkRect localBounds, globalBounds; - localBounds = path.getBounds(); - float width = std::max(colors.innerWidth(), colors.outerWidth()); - width *= WIDTH_SCALE; - localBounds.inset(-width, -width); - const SkMatrix& matrix = canvas->getTotalMatrix(); - matrix.mapRect(&globalBounds, localBounds); - SkIRect globalIBounds; - globalBounds.round(&globalIBounds); - m_lastBounds = globalIBounds; - inval->unite(m_lastBounds); -} - -void CursorRing::setIsButton(const CachedNode* node) -{ - m_isButton = false; - m_viewImpl->gButtonMutex.lock(); - // If this is a button drawn by us (rather than webkit) do not draw the - // cursor ring, since its cursor will be shown by a change in what we draw. - // Should be in sync with recordButtons, since that will be called - // before this. - if (m_viewImpl->m_buttons.size() > 0) { - WebCore::Node* cursorPointer = (WebCore::Node*) node->nodePointer(); - Container* end = m_viewImpl->m_buttons.end(); - for (Container* ptr = m_viewImpl->m_buttons.begin(); ptr != end; ptr++) { - if (ptr->matches(cursorPointer)) { - m_isButton = true; - break; - } - } - } - m_viewImpl->gButtonMutex.unlock(); -} - -bool CursorRing::setup() -{ - m_node->localCursorRings(m_frame, &m_rings); - if (!m_rings.size()) { - DBG_NAV_LOG("!rings.size()"); - m_viewImpl->m_hasCursorBounds = false; - return false; - } - setIsButton(m_node); - m_bounds = m_node->localBounds(m_frame); - m_viewImpl->updateCursorBounds(m_root, m_frame, m_node); - - bool useHitBounds = m_node->useHitBounds(); - if (useHitBounds) - m_bounds = m_node->localHitBounds(m_frame); - if (useHitBounds || m_node->useBounds()) { - m_rings.clear(); - m_rings.append(m_bounds); - } - m_absBounds = m_node->bounds(m_frame); - const CachedColor& colors = m_frame->color(m_node); - m_bounds.inflate(SkScalarCeil(colors.outerWidth())); - m_absBounds.inflate(SkScalarCeil(colors.outerWidth())); - if (!m_node->hasCursorRing() || (m_node->isPlugin() && m_node->isFocus())) - return false; -#if DEBUG_NAV_UI - const WebCore::IntRect& ring = m_rings[0]; - DBG_NAV_LOGD("cursorNode=%d (nodePointer=%p) pressed=%s rings=%d" - " (%d, %d, %d, %d) isPlugin=%s", - m_node->index(), m_node->nodePointer(), - m_isPressed ? "true" : "false", - m_rings.size(), ring.x(), ring.y(), ring.width(), ring.height(), - m_node->isPlugin() ? "true" : "false"); - DBG_NAV_LOGD("[%d] inner=%d outer=%d outset=%d radius=%d" - " fill=0x%08x pin=0x%08x pout=0x%08x sin=0x%08x sout=0x%08x", - m_node->colorIndex(), colors.innerWidth(), colors.outerWidth(), - colors.outset(), colors.radius(), colors.fillColor(), - colors.pressedInnerColor(), colors.pressedOuterColor(), - colors.selectedInnerColor(), colors.selectedInnerColor()); -#endif - return true; -} - -} diff --git a/WebCore/platform/graphics/android/android_graphics.h b/WebCore/platform/graphics/android/android_graphics.h deleted file mode 100644 index 89312b5..0000000 --- a/WebCore/platform/graphics/android/android_graphics.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2007, The Android Open Source Project - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 android_graphics_DEFINED -#define android_graphics_DEFINED - -#include "DrawExtra.h" -#include "IntRect.h" -#include "SkTypes.h" -#include "wtf/Vector.h" - -namespace WebCore { - class GraphicsContext; -} - -SkCanvas* android_gc2canvas(GraphicsContext* gc); - -namespace android { - -class CachedFrame; -class CachedNode; -class CachedRoot; -class WebViewCore; - -// Data and methods for cursor rings - -// used to inflate node cache entry -#define CURSOR_RING_HIT_TEST_RADIUS 5 - -class CursorRing : public DrawExtra { -public: - CursorRing(WebViewCore* core) : m_viewImpl(core) {} - virtual ~CursorRing() {} - virtual void draw(SkCanvas* , LayerAndroid* , IntRect* ); - void setIsButton(const CachedNode* ); - bool setup(); - WTF::Vector<IntRect>& rings() { return m_rings; } -private: - friend class WebView; - WebViewCore* m_viewImpl; // copy for convenience - WTF::Vector<IntRect> m_rings; - IntRect m_bounds; - IntRect m_absBounds; - IntRect m_lastBounds; - const CachedRoot* m_root; - const CachedFrame* m_frame; - const CachedNode* m_node; - bool m_isButton; - bool m_isPressed; -}; - -} - -#endif |