Changeset 152099 in webkit


Ignore:
Timestamp:
Jun 27, 2013 8:42:18 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Unreviewed, rolling out r152074.
http://trac.webkit.org/changeset/152074
https://bugs.webkit.org/show_bug.cgi?id=118137

It caused lots of layout and API test crash on Qt Wk2.
(Requested by kadam on #webkit).

Source/WebCore:

  • CMakeLists.txt:
  • Target.pri:
  • platform/graphics/texmap/coordinated/CompositingCoordinator.cpp: Removed.
  • platform/graphics/texmap/coordinated/CompositingCoordinator.h: Removed.

Source/WebKit2:

  • WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp:

(WebKit::CoordinatedLayerTreeHost::~CoordinatedLayerTreeHost):
(WebKit::CoordinatedLayerTreeHost::CoordinatedLayerTreeHost):
(WebKit::CoordinatedLayerTreeHost::setRootCompositingLayer):
(WebKit::CoordinatedLayerTreeHost::invalidate):
(WebKit::CoordinatedLayerTreeHost::forceRepaint):
(WebKit::CoordinatedLayerTreeHost::sizeDidChange):
(WebKit::CoordinatedLayerTreeHost::flushPendingLayerChanges):
(WebKit::CoordinatedLayerTreeHost::clearPendingStateChanges):
(WebKit::CoordinatedLayerTreeHost::initializeRootCompositingLayerIfNeeded):
(WebKit::CoordinatedLayerTreeHost::syncLayerState):
(WebKit::CoordinatedLayerTreeHost::prepareCustomFilterProxiesIfNeeded):
(WebKit::CoordinatedLayerTreeHost::checkCustomFilterProgramProxies):
(WebKit::CoordinatedLayerTreeHost::removeCustomFilterProgramProxy):
(WebKit::CoordinatedLayerTreeHost::detachLayer):
(WebKit::CoordinatedLayerTreeHost::performScheduledLayerFlush):
(WebKit::CoordinatedLayerTreeHost::syncDisplayState):
(WebKit::CoordinatedLayerTreeHost::didPerformScheduledLayerFlush):
(WebKit::CoordinatedLayerTreeHost::createPageOverlayLayer):
(WebKit::CoordinatedLayerTreeHost::createImageBackingIfNeeded):
(WebKit::CoordinatedLayerTreeHost::createImageBacking):
(WebKit::CoordinatedLayerTreeHost::updateImageBacking):
(WebKit::CoordinatedLayerTreeHost::clearImageBackingContents):
(WebKit::CoordinatedLayerTreeHost::removeImageBacking):
(WebKit::CoordinatedLayerTreeHost::flushPendingImageBackingChanges):
(WebKit::CoordinatedLayerTreeHost::notifyAnimationStarted):
(WebKit::CoordinatedLayerTreeHost::notifyFlushRequired):
(WebKit::CoordinatedLayerTreeHost::paintContents):
(WebKit::CoordinatedLayerTreeHost::createGraphicsLayer):
(WebKit::CoordinatedLayerTreeHost::deviceScaleFactor):
(WebKit::CoordinatedLayerTreeHost::pageScaleFactor):
(WebKit::CoordinatedLayerTreeHost::createUpdateAtlas):
(WebKit::CoordinatedLayerTreeHost::removeUpdateAtlas):
(WebKit::CoordinatedLayerTreeHost::visibleContentsRect):
(WebKit::CoordinatedLayerTreeHost::mainContentsLayer):
(WebKit::CoordinatedLayerTreeHost::setVisibleContentsRect):
(WebKit::CoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged):
(WebKit::CoordinatedLayerTreeHost::graphicsLayerFactory):
(WebKit::CoordinatedLayerTreeHost::scheduleAnimation):
(WebKit::CoordinatedLayerTreeHost::renderNextFrame):
(WebKit::CoordinatedLayerTreeHost::purgeBackingStores):
(WebKit::CoordinatedLayerTreeHost::paintToSurface):
(WebKit::CoordinatedLayerTreeHost::scheduleReleaseInactiveAtlases):
(WebKit::CoordinatedLayerTreeHost::releaseInactiveAtlasesTimerFired):
(WebKit::CoordinatedLayerTreeHost::commitScrollOffset):

  • WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.h:
  • WebProcess/WebPage/LayerTreeHost.h:

(WebKit::LayerTreeHost::setVisibleContentsRect):
(WebKit::LayerTreeHost::renderNextFrame):
(WebKit::LayerTreeHost::purgeBackingStores):

Location:
trunk/Source
Files:
2 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/CMakeLists.txt

    r152080 r152099  
    19791979
    19801980    platform/graphics/texmap/coordinated/AreaAllocator.cpp
    1981     platform/graphics/texmap/coordinated/CompositingCoordinator.cpp
    19821981    platform/graphics/texmap/coordinated/CoordinatedBackingStore.cpp
    19831982    platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp
  • trunk/Source/WebCore/ChangeLog

    r152098 r152099  
     12013-06-27  Commit Queue  <commit-queue@webkit.org>
     2
     3        Unreviewed, rolling out r152074.
     4        http://trac.webkit.org/changeset/152074
     5        https://bugs.webkit.org/show_bug.cgi?id=118137
     6
     7        It caused lots of layout and API test crash on Qt Wk2.
     8        (Requested by kadam on #webkit).
     9
     10        * CMakeLists.txt:
     11        * Target.pri:
     12        * platform/graphics/texmap/coordinated/CompositingCoordinator.cpp: Removed.
     13        * platform/graphics/texmap/coordinated/CompositingCoordinator.h: Removed.
     14
    1152013-06-27  Seokju Kwon  <seokju.kwon@gmail.com>
    216
  • trunk/Source/WebCore/Target.pri

    r152080 r152099  
    40904090        platform/graphics/texmap/TextureMapperShaderProgram.h \
    40914091        platform/graphics/texmap/coordinated/AreaAllocator.h \
    4092         platform/graphics/texmap/coordinated/CompositingCoordinator.h \
    40934092        platform/graphics/texmap/coordinated/CoordinatedBackingStore.h \
    40944093        platform/graphics/texmap/coordinated/CoordinatedCustomFilterOperation.h \
     
    41264125        platform/graphics/texmap/TextureMapperShaderProgram.cpp \
    41274126        platform/graphics/texmap/coordinated/AreaAllocator.cpp \
    4128         platform/graphics/texmap/coordinated/CompositingCoordinator.cpp \
    41294127        platform/graphics/texmap/coordinated/CoordinatedBackingStore.cpp \
    41304128        platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp \
  • trunk/Source/WebKit2/ChangeLog

    r152095 r152099  
     12013-06-27  Commit Queue  <commit-queue@webkit.org>
     2
     3        Unreviewed, rolling out r152074.
     4        http://trac.webkit.org/changeset/152074
     5        https://bugs.webkit.org/show_bug.cgi?id=118137
     6
     7        It caused lots of layout and API test crash on Qt Wk2.
     8        (Requested by kadam on #webkit).
     9
     10        * WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp:
     11        (WebKit::CoordinatedLayerTreeHost::~CoordinatedLayerTreeHost):
     12        (WebKit::CoordinatedLayerTreeHost::CoordinatedLayerTreeHost):
     13        (WebKit::CoordinatedLayerTreeHost::setRootCompositingLayer):
     14        (WebKit::CoordinatedLayerTreeHost::invalidate):
     15        (WebKit::CoordinatedLayerTreeHost::forceRepaint):
     16        (WebKit::CoordinatedLayerTreeHost::sizeDidChange):
     17        (WebKit::CoordinatedLayerTreeHost::flushPendingLayerChanges):
     18        (WebKit::CoordinatedLayerTreeHost::clearPendingStateChanges):
     19        (WebKit::CoordinatedLayerTreeHost::initializeRootCompositingLayerIfNeeded):
     20        (WebKit::CoordinatedLayerTreeHost::syncLayerState):
     21        (WebKit::CoordinatedLayerTreeHost::prepareCustomFilterProxiesIfNeeded):
     22        (WebKit::CoordinatedLayerTreeHost::checkCustomFilterProgramProxies):
     23        (WebKit::CoordinatedLayerTreeHost::removeCustomFilterProgramProxy):
     24        (WebKit::CoordinatedLayerTreeHost::detachLayer):
     25        (WebKit::CoordinatedLayerTreeHost::performScheduledLayerFlush):
     26        (WebKit::CoordinatedLayerTreeHost::syncDisplayState):
     27        (WebKit::CoordinatedLayerTreeHost::didPerformScheduledLayerFlush):
     28        (WebKit::CoordinatedLayerTreeHost::createPageOverlayLayer):
     29        (WebKit::CoordinatedLayerTreeHost::createImageBackingIfNeeded):
     30        (WebKit::CoordinatedLayerTreeHost::createImageBacking):
     31        (WebKit::CoordinatedLayerTreeHost::updateImageBacking):
     32        (WebKit::CoordinatedLayerTreeHost::clearImageBackingContents):
     33        (WebKit::CoordinatedLayerTreeHost::removeImageBacking):
     34        (WebKit::CoordinatedLayerTreeHost::flushPendingImageBackingChanges):
     35        (WebKit::CoordinatedLayerTreeHost::notifyAnimationStarted):
     36        (WebKit::CoordinatedLayerTreeHost::notifyFlushRequired):
     37        (WebKit::CoordinatedLayerTreeHost::paintContents):
     38        (WebKit::CoordinatedLayerTreeHost::createGraphicsLayer):
     39        (WebKit::CoordinatedLayerTreeHost::deviceScaleFactor):
     40        (WebKit::CoordinatedLayerTreeHost::pageScaleFactor):
     41        (WebKit::CoordinatedLayerTreeHost::createUpdateAtlas):
     42        (WebKit::CoordinatedLayerTreeHost::removeUpdateAtlas):
     43        (WebKit::CoordinatedLayerTreeHost::visibleContentsRect):
     44        (WebKit::CoordinatedLayerTreeHost::mainContentsLayer):
     45        (WebKit::CoordinatedLayerTreeHost::setVisibleContentsRect):
     46        (WebKit::CoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged):
     47        (WebKit::CoordinatedLayerTreeHost::graphicsLayerFactory):
     48        (WebKit::CoordinatedLayerTreeHost::scheduleAnimation):
     49        (WebKit::CoordinatedLayerTreeHost::renderNextFrame):
     50        (WebKit::CoordinatedLayerTreeHost::purgeBackingStores):
     51        (WebKit::CoordinatedLayerTreeHost::paintToSurface):
     52        (WebKit::CoordinatedLayerTreeHost::scheduleReleaseInactiveAtlases):
     53        (WebKit::CoordinatedLayerTreeHost::releaseInactiveAtlasesTimerFired):
     54        (WebKit::CoordinatedLayerTreeHost::commitScrollOffset):
     55        * WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.h:
     56        * WebProcess/WebPage/LayerTreeHost.h:
     57        (WebKit::LayerTreeHost::setVisibleContentsRect):
     58        (WebKit::LayerTreeHost::renderNextFrame):
     59        (WebKit::LayerTreeHost::purgeBackingStores):
     60
    1612013-06-27  Xabier Rodriguez Calvar  <calvaris@igalia.com>
    262
  • trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp

    r152074 r152099  
    4141#include <WebCore/Frame.h>
    4242#include <WebCore/FrameView.h>
     43#include <WebCore/GraphicsSurface.h>
     44#include <WebCore/InspectorController.h>
     45#include <WebCore/Page.h>
     46#include <WebCore/RenderLayer.h>
     47#include <WebCore/RenderLayerBacking.h>
     48#include <WebCore/RenderLayerCompositor.h>
     49#include <WebCore/RenderView.h>
    4350#include <WebCore/Settings.h>
     51#include <WebCore/SurfaceUpdateInfo.h>
     52#include <WebCore/TextureMapperPlatformLayer.h>
    4453#include <wtf/CurrentTime.h>
     54#include <wtf/TemporaryChange.h>
    4555
    4656#if ENABLE(CSS_SHADERS)
     
    6373    disconnectCustomFilterPrograms();
    6474#endif
     75    purgeBackingStores();
     76
     77    LayerMap::iterator end = m_registeredLayers.end();
     78    for (LayerMap::iterator it = m_registeredLayers.begin(); it != end; ++it)
     79        it->value->setCoordinator(0);
    6580}
    6681
    6782CoordinatedLayerTreeHost::CoordinatedLayerTreeHost(WebPage* webPage)
    6883    : LayerTreeHost(webPage)
     84    , m_rootCompositingLayer(0)
    6985    , m_notifyAfterScheduledLayerFlush(false)
    7086    , m_isValid(true)
     87    , m_isPurging(false)
     88    , m_isFlushingLayerChanges(false)
     89    , m_waitingForUIProcess(true)
    7190    , m_isSuspended(false)
    72     , m_isWaitingForRenderer(true)
     91    , m_shouldSyncFrame(false)
     92    , m_didInitializeRootCompositingLayer(false)
    7393    , m_layerFlushTimer(this, &CoordinatedLayerTreeHost::layerFlushTimerFired)
     94    , m_releaseInactiveAtlasesTimer(this, &CoordinatedLayerTreeHost::releaseInactiveAtlasesTimerFired)
    7495    , m_layerFlushSchedulingEnabled(true)
    7596    , m_forceRepaintAsyncCallbackID(0)
    76 {
    77     m_coordinator = CompositingCoordinator::create(webPage->corePage(), this);
    78 
    79     m_coordinator->createRootLayer(webPage->size());
    80     m_layerTreeContext.coordinatedLayerID = toCoordinatedGraphicsLayer(m_coordinator->rootLayer())->id();
     97    , m_animationsLocked(false)
     98#if ENABLE(REQUEST_ANIMATION_FRAME)
     99    , m_lastAnimationServiceTime(0)
     100#endif
     101{
     102    m_webPage->corePage()->settings()->setApplyDeviceScaleFactorInCompositor(true);
     103
     104    // Create a root layer.
     105    m_rootLayer = GraphicsLayer::create(this, this);
     106#ifndef NDEBUG
     107    m_rootLayer->setName("CoordinatedLayerTreeHost root layer");
     108#endif
     109    m_rootLayer->setDrawsContent(false);
     110    m_rootLayer->setSize(m_webPage->size());
     111    m_layerTreeContext.coordinatedLayerID = toCoordinatedGraphicsLayer(m_rootLayer.get())->id();
    81112
    82113    CoordinatedSurface::setFactory(createCoordinatedSurface);
    83114
    84     if (webPage->hasPageOverlay())
     115    // This is a temporary way to enable this only in the GL case, until TextureMapperImageBuffer is removed.
     116    // See https://bugs.webkit.org/show_bug.cgi?id=114869
     117    CoordinatedGraphicsLayer::setShouldSupportContentsTiling(true);
     118
     119    if (m_webPage->hasPageOverlay())
    85120        createPageOverlayLayer();
    86121
     
    124159void CoordinatedLayerTreeHost::setRootCompositingLayer(WebCore::GraphicsLayer* graphicsLayer)
    125160{
    126     m_coordinator->setRootCompositingLayer(graphicsLayer);
     161    if (m_rootCompositingLayer)
     162        m_rootCompositingLayer->removeFromParent();
     163
     164    m_rootCompositingLayer = graphicsLayer;
     165    if (m_rootCompositingLayer)
     166        m_rootLayer->addChildAtIndex(m_rootCompositingLayer, 0);
    127167}
    128168
     
    132172
    133173    ASSERT(m_isValid);
    134     m_coordinator->clearRootLayer();
     174    m_rootLayer = nullptr;
    135175    m_isValid = false;
    136176}
     
    140180    // This is necessary for running layout tests. Since in this case we are not waiting for a UIProcess to reply nicely.
    141181    // Instead we are just triggering forceRepaint. But we still want to have the scripted animation callbacks being executed.
    142     m_coordinator->syncDisplayState();
     182    syncDisplayState();
    143183
    144184    // We need to schedule another flush, otherwise the forced paint might cancel a later expected flush.
    145185    // This is aligned with LayerTreeHostCA.
    146186    scheduleLayerFlush();
    147     m_coordinator->flushPendingLayerChanges();
     187    flushPendingLayerChanges();
    148188}
    149189
     
    159199void CoordinatedLayerTreeHost::sizeDidChange(const WebCore::IntSize& newSize)
    160200{
    161     m_coordinator->sizeDidChange(newSize);
     201    m_rootLayer->setSize(newSize);
    162202    scheduleLayerFlush();
    163203}
     
    194234}
    195235
    196 void CoordinatedLayerTreeHost::setVisibleContentsRect(const FloatRect& rect, const FloatPoint& trajectoryVector)
    197 {
    198     m_coordinator->setVisibleContentsRect(rect, trajectoryVector);
    199     scheduleLayerFlush();
    200 }
    201 
    202 void CoordinatedLayerTreeHost::renderNextFrame()
    203 {
    204     m_coordinator->renderNextFrame();
    205     m_isWaitingForRenderer = false;
    206     scheduleLayerFlush();
    207 }
    208 
    209 void CoordinatedLayerTreeHost::purgeBackingStores()
    210 {
    211     m_coordinator->purgeBackingStores();
    212 }
    213 
    214 void CoordinatedLayerTreeHost::willSyncLayerState(CoordinatedGraphicsLayerState& state)
    215 {
     236bool CoordinatedLayerTreeHost::flushPendingLayerChanges()
     237{
     238    if (m_waitingForUIProcess)
     239        return false;
     240
     241    TemporaryChange<bool> protector(m_isFlushingLayerChanges, true);
     242
     243    initializeRootCompositingLayerIfNeeded();
     244
     245    m_rootLayer->flushCompositingStateForThisLayerOnly();
     246    if (m_pageOverlayLayer)
     247        m_pageOverlayLayer->flushCompositingStateForThisLayerOnly();
     248
     249    bool didSync = m_webPage->corePage()->mainFrame()->view()->flushCompositingStateIncludingSubframes();
     250
     251    toCoordinatedGraphicsLayer(m_rootLayer.get())->updateContentBuffersIncludingSubLayers();
     252    toCoordinatedGraphicsLayer(m_rootLayer.get())->syncPendingStateChangesIncludingSubLayers();
     253
     254    flushPendingImageBackingChanges();
     255
     256    if (m_shouldSyncFrame) {
     257        didSync = true;
     258
     259        if (m_rootCompositingLayer) {
     260            m_state.contentsSize = roundedIntSize(m_rootCompositingLayer->size());
     261            if (CoordinatedGraphicsLayer* contentsLayer = mainContentsLayer())
     262                m_state.coveredRect = contentsLayer->coverRect();
     263        }
     264
     265        m_state.scrollPosition = m_visibleContentsRect.location();
     266
     267        m_webPage->send(Messages::CoordinatedLayerTreeHostProxy::CommitCoordinatedGraphicsState(m_state));
     268
     269        clearPendingStateChanges();
     270        m_waitingForUIProcess = true;
     271        m_shouldSyncFrame = false;
     272    }
     273
     274    if (m_forceRepaintAsyncCallbackID) {
     275        m_webPage->send(Messages::WebPageProxy::VoidCallback(m_forceRepaintAsyncCallbackID));
     276        m_forceRepaintAsyncCallbackID = 0;
     277    }
     278
     279    return didSync;
     280}
     281
     282void CoordinatedLayerTreeHost::clearPendingStateChanges()
     283{
     284    m_state.layersToCreate.clear();
     285    m_state.layersToUpdate.clear();
     286    m_state.layersToRemove.clear();
     287
     288    m_state.imagesToCreate.clear();
     289    m_state.imagesToRemove.clear();
     290    m_state.imagesToUpdate.clear();
     291    m_state.imagesToClear.clear();
     292
     293    m_state.updateAtlasesToCreate.clear();
     294    m_state.updateAtlasesToRemove.clear();
     295
    216296#if ENABLE(CSS_SHADERS)
    217     if (state.animationsChanged)
    218         prepareCustomFilterProxiesForAnimations(state.animations);
     297    m_state.customFiltersToCreate.clear();
     298    m_state.customFiltersToRemove.clear();
     299#endif
     300}
     301
     302void CoordinatedLayerTreeHost::initializeRootCompositingLayerIfNeeded()
     303{
     304    if (m_didInitializeRootCompositingLayer)
     305        return;
     306
     307    m_state.rootCompositingLayer = toCoordinatedGraphicsLayer(m_rootLayer.get())->id();
     308    m_didInitializeRootCompositingLayer = true;
     309    m_shouldSyncFrame = true;
     310}
     311
     312void CoordinatedLayerTreeHost::syncLayerState(CoordinatedLayerID id, CoordinatedGraphicsLayerState& state)
     313{
     314    m_shouldSyncFrame = true;
     315
     316#if ENABLE(CSS_SHADERS)
     317    prepareCustomFilterProxiesIfNeeded(state);
     318#endif
     319
     320    m_state.layersToUpdate.append(std::make_pair(id, state));
     321}
     322
     323#if ENABLE(CSS_SHADERS)
     324void CoordinatedLayerTreeHost::prepareCustomFilterProxiesIfNeeded(CoordinatedGraphicsLayerState& state)
     325{
     326    if (state.animationsChanged) {
     327        GraphicsLayerAnimations& activeAnimations = state.animations;
     328        for (size_t i = 0; i < activeAnimations.animations().size(); ++i) {
     329            const KeyframeValueList& keyframes = activeAnimations.animations().at(i).keyframes();
     330            if (keyframes.property() != AnimatedPropertyWebkitFilter)
     331                continue;
     332            for (size_t j = 0; j < keyframes.size(); ++j) {
     333                const FilterAnimationValue& filterValue = static_cast<const FilterAnimationValue&>(keyframes.at(j));
     334                checkCustomFilterProgramProxies(filterValue.value());
     335            }
     336        }
     337    }
    219338
    220339    if (state.filtersChanged)
    221340        checkCustomFilterProgramProxies(state.filters);
    222 #else
    223     UNUSED_PARAM(state);
    224 #endif
    225 }
    226 
    227 #if ENABLE(CSS_SHADERS)
    228 void CoordinatedLayerTreeHost::prepareCustomFilterProxiesForAnimations(GraphicsLayerAnimations& activeAnimations)
    229 {
    230     for (size_t i = 0; i < activeAnimations.animations().size(); ++i) {
    231         const KeyframeValueList& keyframes = activeAnimations.animations().at(i).keyframes();
    232         if (keyframes.property() != AnimatedPropertyWebkitFilter)
    233             continue;
    234         for (size_t j = 0; j < keyframes.size(); ++j) {
    235             const FilterAnimationValue& filterValue = static_cast<const FilterAnimationValue&>(keyframes.at(j));
    236             checkCustomFilterProgramProxies(filterValue.value());
    237         }
    238     }
    239341}
    240342
     
    266368            customFilterProgramProxy->setClient(this);
    267369            m_customFilterPrograms.add(customFilterProgramProxy.get());
    268             m_coordinator->state().customFiltersToCreate.append(std::make_pair(customFilterProgramProxy->id(), customOperation->validatedProgram()->validatedProgramInfo()));
     370            m_state.customFiltersToCreate.append(std::make_pair(customFilterProgramProxy->id(), customOperation->validatedProgram()->validatedProgramInfo()));
    269371        } else {
    270372            // If the client was not disconnected then this coordinator must be the client for it.
     
    279381    // send a message to the other process to delete it.
    280382    m_customFilterPrograms.remove(customFilterProgramProxy);
    281     m_coordinator->state().customFiltersToRemove.append(customFilterProgramProxy->id());
     383    m_state.customFiltersToRemove.append(customFilterProgramProxy->id());
    282384}
    283385
     
    291393#endif // ENABLE(CSS_SHADERS)
    292394
    293 void CoordinatedLayerTreeHost::didFlushRootLayer()
    294 {
    295     if (m_pageOverlayLayer)
    296         m_pageOverlayLayer->flushCompositingStateForThisLayerOnly();
     395void CoordinatedLayerTreeHost::detachLayer(CoordinatedGraphicsLayer* layer)
     396{
     397    m_registeredLayers.remove(layer->id());
     398
     399    size_t index = m_state.layersToCreate.find(layer->id());
     400    if (index != notFound) {
     401        m_state.layersToCreate.remove(index);
     402        return;
     403    }
     404
     405    m_state.layersToRemove.append(layer->id());
     406    scheduleLayerFlush();
    297407}
    298408
    299409void CoordinatedLayerTreeHost::performScheduledLayerFlush()
    300410{
    301     if (m_isSuspended || m_isWaitingForRenderer)
    302         return;
    303 
    304     m_coordinator->syncDisplayState();
     411    if (m_isSuspended || m_waitingForUIProcess)
     412        return;
     413
     414    syncDisplayState();
    305415
    306416    if (!m_isValid)
    307417        return;
    308418
    309     bool didSync = m_coordinator->flushPendingLayerChanges();
    310 
    311     if (m_forceRepaintAsyncCallbackID) {
    312         m_webPage->send(Messages::WebPageProxy::VoidCallback(m_forceRepaintAsyncCallbackID));
    313         m_forceRepaintAsyncCallbackID = 0;
    314     }
    315 
    316     if (m_notifyAfterScheduledLayerFlush && didSync) {
     419    if (flushPendingLayerChanges())
     420        didPerformScheduledLayerFlush();
     421}
     422
     423void CoordinatedLayerTreeHost::syncDisplayState()
     424{
     425#if ENABLE(INSPECTOR)
     426    m_webPage->corePage()->inspectorController()->didBeginFrame();
     427#endif
     428
     429#if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER) && !USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     430    // Make sure that any previously registered animation callbacks are being executed before we flush the layers.
     431    m_lastAnimationServiceTime = WTF::monotonicallyIncreasingTime();
     432    m_webPage->corePage()->mainFrame()->view()->serviceScriptedAnimations(m_lastAnimationServiceTime);
     433#endif
     434
     435    m_webPage->layoutIfNeeded();
     436}
     437
     438void CoordinatedLayerTreeHost::didPerformScheduledLayerFlush()
     439{
     440    if (m_notifyAfterScheduledLayerFlush) {
    317441        static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers();
    318442        m_notifyAfterScheduledLayerFlush = false;
     
    329453    ASSERT(!m_pageOverlayLayer);
    330454
    331     m_pageOverlayLayer = GraphicsLayer::create(graphicsLayerFactory(), m_coordinator.get());
     455    m_pageOverlayLayer = GraphicsLayer::create(this, this);
    332456#ifndef NDEBUG
    333     m_pageOverlayLayer->setName("CompositingCoordinator page overlay content");
     457    m_pageOverlayLayer->setName("CoordinatedLayerTreeHost page overlay content");
    334458#endif
    335459
    336460    m_pageOverlayLayer->setDrawsContent(true);
    337     m_pageOverlayLayer->setSize(m_coordinator->rootLayer()->size());
    338 
    339     m_coordinator->rootLayer()->addChild(m_pageOverlayLayer.get());
     461    m_pageOverlayLayer->setSize(m_webPage->size());
     462
     463    m_rootLayer->addChild(m_pageOverlayLayer.get());
    340464}
    341465
     
    347471}
    348472
    349 void CoordinatedLayerTreeHost::paintLayerContents(const GraphicsLayer* graphicsLayer, GraphicsContext& graphicsContext, const IntRect& clipRect)
     473PassRefPtr<CoordinatedImageBacking> CoordinatedLayerTreeHost::createImageBackingIfNeeded(Image* image)
     474{
     475    CoordinatedImageBackingID imageID = CoordinatedImageBacking::getCoordinatedImageBackingID(image);
     476    ImageBackingMap::iterator it = m_imageBackings.find(imageID);
     477    RefPtr<CoordinatedImageBacking> imageBacking;
     478    if (it == m_imageBackings.end()) {
     479        imageBacking = CoordinatedImageBacking::create(this, image);
     480        m_imageBackings.add(imageID, imageBacking);
     481    } else
     482        imageBacking = it->value;
     483
     484    return imageBacking;
     485}
     486
     487void CoordinatedLayerTreeHost::createImageBacking(CoordinatedImageBackingID imageID)
     488{
     489    m_state.imagesToCreate.append(imageID);
     490}
     491
     492void CoordinatedLayerTreeHost::updateImageBacking(CoordinatedImageBackingID imageID, PassRefPtr<CoordinatedSurface> coordinatedSurface)
     493{
     494    m_shouldSyncFrame = true;
     495    m_state.imagesToUpdate.append(std::make_pair(imageID, coordinatedSurface));
     496}
     497
     498void CoordinatedLayerTreeHost::clearImageBackingContents(CoordinatedImageBackingID imageID)
     499{
     500    m_shouldSyncFrame = true;
     501    m_state.imagesToClear.append(imageID);
     502}
     503
     504void CoordinatedLayerTreeHost::removeImageBacking(CoordinatedImageBackingID imageID)
     505{
     506    if (m_isPurging)
     507        return;
     508
     509    ASSERT(m_imageBackings.contains(imageID));
     510    m_imageBackings.remove(imageID);
     511
     512    m_state.imagesToRemove.append(imageID);
     513}
     514
     515void CoordinatedLayerTreeHost::flushPendingImageBackingChanges()
     516{
     517    ImageBackingMap::iterator end = m_imageBackings.end();
     518    for (ImageBackingMap::iterator iter = m_imageBackings.begin(); iter != end; ++iter)
     519        iter->value->update();
     520}
     521
     522void CoordinatedLayerTreeHost::notifyAnimationStarted(const WebCore::GraphicsLayer*, double /* time */)
     523{
     524}
     525
     526void CoordinatedLayerTreeHost::notifyFlushRequired(const WebCore::GraphicsLayer*)
     527{
     528    scheduleLayerFlush();
     529}
     530
     531void CoordinatedLayerTreeHost::paintContents(const WebCore::GraphicsLayer* graphicsLayer, WebCore::GraphicsContext& graphicsContext, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect)
    350532{
    351533    if (graphicsLayer == m_pageOverlayLayer) {
     
    357539}
    358540
    359 void CoordinatedLayerTreeHost::commitSceneState(WebCore::CoordinatedGraphicsState& state)
    360 {
    361     m_webPage->send(Messages::CoordinatedLayerTreeHostProxy::CommitCoordinatedGraphicsState(state));
    362     m_isWaitingForRenderer = true;
     541PassOwnPtr<GraphicsLayer> CoordinatedLayerTreeHost::createGraphicsLayer(GraphicsLayerClient* client)
     542{
     543    CoordinatedGraphicsLayer* layer = new CoordinatedGraphicsLayer(client);
     544    layer->setCoordinator(this);
     545    m_registeredLayers.add(layer->id(), layer);
     546    m_state.layersToCreate.append(layer->id());
     547    layer->setNeedsVisibleRectAdjustment();
     548    scheduleLayerFlush();
     549    return adoptPtr(layer);
    363550}
    364551
     
    368555}
    369556
     557float CoordinatedLayerTreeHost::deviceScaleFactor() const
     558{
     559    return m_webPage->deviceScaleFactor();
     560}
     561
     562float CoordinatedLayerTreeHost::pageScaleFactor() const
     563{
     564    return m_webPage->pageScaleFactor();
     565}
     566
    370567bool LayerTreeHost::supportsAcceleratedCompositing()
    371568{
     
    373570}
    374571
     572void CoordinatedLayerTreeHost::createUpdateAtlas(uint32_t atlasID, PassRefPtr<CoordinatedSurface> coordinatedSurface)
     573{
     574    m_state.updateAtlasesToCreate.append(std::make_pair(atlasID, coordinatedSurface));
     575}
     576
     577void CoordinatedLayerTreeHost::removeUpdateAtlas(uint32_t atlasID)
     578{
     579    if (m_isPurging)
     580        return;
     581    m_state.updateAtlasesToRemove.append(atlasID);
     582}
     583
     584WebCore::FloatRect CoordinatedLayerTreeHost::visibleContentsRect() const
     585{
     586    return m_visibleContentsRect;
     587}
     588
     589CoordinatedGraphicsLayer* CoordinatedLayerTreeHost::mainContentsLayer()
     590{
     591    if (!m_rootCompositingLayer)
     592        return 0;
     593
     594    return toCoordinatedGraphicsLayer(m_rootCompositingLayer)->findFirstDescendantWithContentsRecursively();
     595}
     596
     597void CoordinatedLayerTreeHost::setVisibleContentsRect(const FloatRect& rect, const FloatPoint& trajectoryVector)
     598{
     599    // A zero trajectoryVector indicates that tiles all around the viewport are requested.
     600    if (CoordinatedGraphicsLayer* contentsLayer = mainContentsLayer())
     601        contentsLayer->setVisibleContentRectTrajectoryVector(trajectoryVector);
     602
     603    bool contentsRectDidChange = rect != m_visibleContentsRect;
     604    if (contentsRectDidChange) {
     605        m_visibleContentsRect = rect;
     606
     607        LayerMap::iterator end = m_registeredLayers.end();
     608        for (LayerMap::iterator it = m_registeredLayers.begin(); it != end; ++it) {
     609            it->value->setNeedsVisibleRectAdjustment();
     610        }
     611    }
     612
     613    scheduleLayerFlush();
     614    if (m_webPage->useFixedLayout()) {
     615        // Round the rect instead of enclosing it to make sure that its size stays
     616        // the same while panning. This can have nasty effects on layout.
     617        m_webPage->setFixedVisibleContentRect(roundedIntRect(rect));
     618    }
     619}
     620
    375621void CoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged()
    376622{
    377     m_coordinator->deviceOrPageScaleFactorChanged();
     623    m_rootLayer->deviceOrPageScaleFactorChanged();
    378624    if (m_pageOverlayLayer)
    379625        m_pageOverlayLayer->deviceOrPageScaleFactorChanged();
     
    386632GraphicsLayerFactory* CoordinatedLayerTreeHost::graphicsLayerFactory()
    387633{
    388     return m_coordinator.get();
     634    return this;
    389635}
    390636
     
    392638void CoordinatedLayerTreeHost::scheduleAnimation()
    393639{
    394     if (m_isWaitingForRenderer)
     640    if (m_waitingForUIProcess)
    395641        return;
    396642
     
    398644        return;
    399645
    400     m_layerFlushTimer.startOneShot(m_coordinator->nextAnimationServiceTime());
    401     scheduleLayerFlush();
    402 }
    403 #endif
     646    // According to the requestAnimationFrame spec, rAF callbacks should not be faster than 60FPS.
     647    static const double MinimalTimeoutForAnimations = 1. / 60.;
     648    m_layerFlushTimer.startOneShot(std::max<double>(0., MinimalTimeoutForAnimations - WTF::monotonicallyIncreasingTime() + m_lastAnimationServiceTime));
     649    scheduleLayerFlush();
     650}
     651#endif
     652
     653void CoordinatedLayerTreeHost::renderNextFrame()
     654{
     655    m_waitingForUIProcess = false;
     656    scheduleLayerFlush();
     657    for (unsigned i = 0; i < m_updateAtlases.size(); ++i)
     658        m_updateAtlases[i]->didSwapBuffers();
     659}
     660
     661void CoordinatedLayerTreeHost::purgeBackingStores()
     662{
     663    TemporaryChange<bool> purgingToggle(m_isPurging, true);
     664
     665    LayerMap::iterator end = m_registeredLayers.end();
     666    for (LayerMap::iterator it = m_registeredLayers.begin(); it != end; ++it)
     667        it->value->purgeBackingStores();
     668
     669    m_imageBackings.clear();
     670    m_updateAtlases.clear();
     671}
     672
     673bool CoordinatedLayerTreeHost::paintToSurface(const IntSize& size, CoordinatedSurface::Flags flags, uint32_t& atlasID, IntPoint& offset, CoordinatedSurface::Client* client)
     674{
     675    for (unsigned i = 0; i < m_updateAtlases.size(); ++i) {
     676        UpdateAtlas* atlas = m_updateAtlases[i].get();
     677        if (atlas->supportsAlpha() == (flags & CoordinatedSurface::SupportsAlpha)) {
     678            // This will false if there is no available buffer space.
     679            if (atlas->paintOnAvailableBuffer(size, atlasID, offset, client))
     680                return true;
     681        }
     682    }
     683
     684    static const int ScratchBufferDimension = 1024; // Should be a power of two.
     685    m_updateAtlases.append(adoptPtr(new UpdateAtlas(this, ScratchBufferDimension, flags)));
     686    scheduleReleaseInactiveAtlases();
     687    return m_updateAtlases.last()->paintOnAvailableBuffer(size, atlasID, offset, client);
     688}
     689
     690const double ReleaseInactiveAtlasesTimerInterval = 0.5;
     691
     692void CoordinatedLayerTreeHost::scheduleReleaseInactiveAtlases()
     693{
     694    if (!m_releaseInactiveAtlasesTimer.isActive())
     695        m_releaseInactiveAtlasesTimer.startRepeating(ReleaseInactiveAtlasesTimerInterval);
     696}
     697
     698void CoordinatedLayerTreeHost::releaseInactiveAtlasesTimerFired(Timer<CoordinatedLayerTreeHost>*)
     699{
     700    // We always want to keep one atlas for non-composited content.
     701    OwnPtr<UpdateAtlas> atlasToKeepAnyway;
     702    bool foundActiveAtlasForNonCompositedContent = false;
     703    for (int i = m_updateAtlases.size() - 1;  i >= 0; --i) {
     704        UpdateAtlas* atlas = m_updateAtlases[i].get();
     705        if (!atlas->isInUse())
     706            atlas->addTimeInactive(ReleaseInactiveAtlasesTimerInterval);
     707        bool usableForNonCompositedContent = !atlas->supportsAlpha();
     708        if (atlas->isInactive()) {
     709            if (!foundActiveAtlasForNonCompositedContent && !atlasToKeepAnyway && usableForNonCompositedContent)
     710                atlasToKeepAnyway = m_updateAtlases[i].release();
     711            m_updateAtlases.remove(i);
     712        } else if (usableForNonCompositedContent)
     713            foundActiveAtlasForNonCompositedContent = true;
     714    }
     715
     716    if (!foundActiveAtlasForNonCompositedContent && atlasToKeepAnyway)
     717        m_updateAtlases.append(atlasToKeepAnyway.release());
     718
     719    if (m_updateAtlases.size() <= 1)
     720        m_releaseInactiveAtlasesTimer.stop();
     721}
    404722
    405723void CoordinatedLayerTreeHost::setBackgroundColor(const WebCore::Color& color)
     
    410728void CoordinatedLayerTreeHost::commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset)
    411729{
    412     m_coordinator->commitScrollOffset(layerID, offset);
     730    LayerMap::iterator i = m_registeredLayers.find(layerID);
     731    if (i == m_registeredLayers.end())
     732        return;
     733
     734    i->value->commitScrollOffset(offset);
    413735}
    414736
  • trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.h

    r152074 r152099  
    2626#include "LayerTreeContext.h"
    2727#include "LayerTreeHost.h"
    28 #include <WebCore/CompositingCoordinator.h>
     28#include "Timer.h"
     29#include <WebCore/CoordinatedGraphicsLayer.h>
     30#include <WebCore/CoordinatedGraphicsState.h>
     31#include <WebCore/CoordinatedImageBacking.h>
     32#include <WebCore/GraphicsLayerClient.h>
    2933#include <WebCore/GraphicsLayerFactory.h>
     34#include <WebCore/UpdateAtlas.h>
    3035#include <wtf/OwnPtr.h>
    3136
     
    4247class WebPage;
    4348
    44 class CoordinatedLayerTreeHost : public LayerTreeHost, public WebCore::CompositingCoordinator::Client
     49class CoordinatedLayerTreeHost : public LayerTreeHost, WebCore::GraphicsLayerClient
     50    , public WebCore::CoordinatedGraphicsLayerClient
     51    , public WebCore::CoordinatedImageBacking::Client
     52    , public WebCore::UpdateAtlas::Client
     53    , public WebCore::GraphicsLayerFactory
    4554#if ENABLE(CSS_SHADERS)
    4655    , WebCustomFilterProgramProxyClient
     
    7685    virtual void pageBackgroundTransparencyChanged() OVERRIDE;
    7786
     87    virtual void renderNextFrame();
     88    virtual void purgeBackingStores();
     89    virtual void setVisibleContentsRect(const WebCore::FloatRect&, const WebCore::FloatPoint&);
    7890    virtual void didReceiveCoordinatedLayerTreeHostMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&);
    7991    virtual WebCore::GraphicsLayerFactory* graphicsLayerFactory() OVERRIDE;
     
    8799    static PassRefPtr<WebCore::CoordinatedSurface> createCoordinatedSurface(const WebCore::IntSize&, WebCore::CoordinatedSurface::Flags);
    88100
     101    void commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset);
     102
    89103protected:
    90104    explicit CoordinatedLayerTreeHost(WebPage*);
    91105
    92106private:
     107    // GraphicsLayerClient
     108    virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double time);
     109    virtual void notifyFlushRequired(const WebCore::GraphicsLayer*);
     110    virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect);
     111    virtual float deviceScaleFactor() const OVERRIDE;
     112    virtual float pageScaleFactor() const OVERRIDE;
     113
     114    // CoordinatedImageBacking::Client
     115    virtual void createImageBacking(WebCore::CoordinatedImageBackingID) OVERRIDE;
     116    virtual void updateImageBacking(WebCore::CoordinatedImageBackingID, PassRefPtr<WebCore::CoordinatedSurface>) OVERRIDE;
     117    virtual void clearImageBackingContents(WebCore::CoordinatedImageBackingID) OVERRIDE;
     118    virtual void removeImageBacking(WebCore::CoordinatedImageBackingID) OVERRIDE;
     119
     120    void flushPendingImageBackingChanges();
     121
     122    // CoordinatedGraphicsLayerClient
     123    virtual bool isFlushingLayerChanges() const OVERRIDE { return m_isFlushingLayerChanges; }
     124    virtual WebCore::FloatRect visibleContentsRect() const;
     125    virtual PassRefPtr<WebCore::CoordinatedImageBacking> createImageBackingIfNeeded(WebCore::Image*) OVERRIDE;
     126    virtual void detachLayer(WebCore::CoordinatedGraphicsLayer*);
     127    virtual bool paintToSurface(const WebCore::IntSize&, WebCore::CoordinatedSurface::Flags, uint32_t& /* atlasID */, WebCore::IntPoint&, WebCore::CoordinatedSurface::Client*) OVERRIDE;
     128    virtual void syncLayerState(WebCore::CoordinatedLayerID, WebCore::CoordinatedGraphicsLayerState&);
     129
     130    // UpdateAtlas::Client
     131    virtual void createUpdateAtlas(uint32_t atlasID, PassRefPtr<WebCore::CoordinatedSurface>) OVERRIDE;
     132    virtual void removeUpdateAtlas(uint32_t atlasID) OVERRIDE;
     133
     134    // GraphicsLayerFactory
     135    virtual PassOwnPtr<WebCore::GraphicsLayer> createGraphicsLayer(WebCore::GraphicsLayerClient*) OVERRIDE;
     136
    93137    // CoordinatedLayerTreeHost
     138    void initializeRootCompositingLayerIfNeeded();
    94139    void createPageOverlayLayer();
    95140    void destroyPageOverlayLayer();
     141    bool flushPendingLayerChanges();
     142    void clearPendingStateChanges();
    96143    void cancelPendingLayerFlush();
    97144    void performScheduledLayerFlush();
    98     void setVisibleContentsRect(const WebCore::FloatRect&, const WebCore::FloatPoint&);
    99     void renderNextFrame();
    100     void purgeBackingStores();
    101     void commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset);
    102 
     145    void didPerformScheduledLayerFlush();
     146    void syncDisplayState();
    103147    void layerFlushTimerFired(WebCore::Timer<CoordinatedLayerTreeHost>*);
    104148
    105     // CompositingCoordinator::Client
    106     virtual void didFlushRootLayer() OVERRIDE;
    107     virtual void willSyncLayerState(WebCore::CoordinatedGraphicsLayerState&) OVERRIDE;
    108     virtual void notifyFlushRequired() OVERRIDE { scheduleLayerFlush(); };
    109     virtual void commitSceneState(WebCore::CoordinatedGraphicsState&) OVERRIDE;
    110     virtual void paintLayerContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, const WebCore::IntRect& clipRect) OVERRIDE;
    111 
    112 #if ENABLE(CSS_SHADERS)
    113     void prepareCustomFilterProxiesForAnimations(WebCore::GraphicsLayerAnimations&);
     149    void scheduleReleaseInactiveAtlases();
     150
     151    void releaseInactiveAtlasesTimerFired(WebCore::Timer<CoordinatedLayerTreeHost>*);
     152
     153#if ENABLE(CSS_SHADERS)
     154    void prepareCustomFilterProxiesIfNeeded(WebCore::CoordinatedGraphicsLayerState&);
    114155
    115156    // WebCustomFilterProgramProxyClient
     
    120161#endif
    121162
    122     OwnPtr<WebCore::CompositingCoordinator> m_coordinator;
     163    OwnPtr<WebCore::GraphicsLayer> m_rootLayer;
     164    WebCore::GraphicsLayer* m_rootCompositingLayer;
    123165
    124166    // The page overlay layer. Will be null if there's no page overlay.
     
    126168    RefPtr<PageOverlay> m_pageOverlay;
    127169
     170    WebCore::CoordinatedGraphicsState m_state;
     171
     172    typedef HashMap<WebCore::CoordinatedLayerID, WebCore::CoordinatedGraphicsLayer*> LayerMap;
     173    LayerMap m_registeredLayers;
     174    typedef HashMap<WebCore::CoordinatedImageBackingID, RefPtr<WebCore::CoordinatedImageBacking> > ImageBackingMap;
     175    ImageBackingMap m_imageBackings;
     176    Vector<OwnPtr<WebCore::UpdateAtlas> > m_updateAtlases;
     177
    128178#if ENABLE(CSS_SHADERS)
    129179    HashSet<WebCustomFilterProgramProxy*> m_customFilterPrograms;
     
    132182    bool m_notifyAfterScheduledLayerFlush;
    133183    bool m_isValid;
     184    // We don't send the messages related to releasing resources to UI Process during purging, because UI Process already had removed all resources.
     185    bool m_isPurging;
     186    bool m_isFlushingLayerChanges;
     187
     188    bool m_waitingForUIProcess;
    134189    bool m_isSuspended;
    135     bool m_isWaitingForRenderer;
     190    WebCore::FloatRect m_visibleContentsRect;
    136191
    137192    LayerTreeContext m_layerTreeContext;
    138 
     193    bool m_shouldSyncFrame;
     194    bool m_didInitializeRootCompositingLayer;
    139195    WebCore::Timer<CoordinatedLayerTreeHost> m_layerFlushTimer;
     196    WebCore::Timer<CoordinatedLayerTreeHost> m_releaseInactiveAtlasesTimer;
    140197    bool m_layerFlushSchedulingEnabled;
    141198    uint64_t m_forceRepaintAsyncCallbackID;
     199    bool m_animationsLocked;
     200
     201#if ENABLE(REQUEST_ANIMATION_FRAME)
     202    double m_lastAnimationServiceTime;
     203#endif
    142204};
    143205
  • trunk/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h

    r152074 r152099  
    8888
    8989#if USE(COORDINATED_GRAPHICS)
     90    virtual void setVisibleContentsRect(const WebCore::FloatRect&, float /* scale */, const WebCore::FloatPoint&) { }
     91    virtual void renderNextFrame() { }
     92    virtual void purgeBackingStores() { }
    9093    virtual void didReceiveCoordinatedLayerTreeHostMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&) = 0;
    9194#endif
Note: See TracChangeset for help on using the changeset viewer.