Changeset 76856 in webkit


Ignore:
Timestamp:
Jan 27, 2011 3:39:50 PM (13 years ago)
Author:
Adam Roben
Message:

Move LegacyCACFLayerTreeHost into its own files

More preparation for <http://webkit.org/b/53251> <rdar://problem/8925496> CACFLayerTreeHost

Reviewed by Simon Fraser.

  • WebCore.vcproj/WebCore.vcproj: Added LegacyCACFLayerTreeHost.{cpp,h}.
  • platform/graphics/ca/win/CACFLayerTreeHost.cpp: Moved code from here to new files.
  • platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp: Added.
  • platform/graphics/ca/win/LegacyCACFLayerTreeHost.h: Added.
Location:
trunk/Source/WebCore
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r76854 r76856  
     12011-01-27  Adam Roben  <aroben@apple.com>
     2
     3        Move LegacyCACFLayerTreeHost into its own files
     4
     5        More preparation for <http://webkit.org/b/53251> <rdar://problem/8925496> CACFLayerTreeHost
     6        should use WKCACFView for rendering
     7
     8        Reviewed by Simon Fraser.
     9
     10        * WebCore.vcproj/WebCore.vcproj: Added LegacyCACFLayerTreeHost.{cpp,h}.
     11
     12        * platform/graphics/ca/win/CACFLayerTreeHost.cpp: Moved code from here to new files.
     13
     14        * platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp: Added.
     15        * platform/graphics/ca/win/LegacyCACFLayerTreeHost.h: Added.
     16
    1172011-01-27  Patrick Gansterer  <paroga@webkit.org>
    218
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r76852 r76856  
    2894428944                                                </File>
    2894528945                                                <File
     28946                                                        RelativePath="..\platform\graphics\ca\win\LegacyCACFLayerTreeHost.cpp"
     28947                                                        >
     28948                                                </File>
     28949                                                <File
     28950                                                        RelativePath="..\platform\graphics\ca\win\LegacyCACFLayerTreeHost.h"
     28951                                                        >
     28952                                                </File>
     28953                                                <File
    2894628954                                                        RelativePath="..\platform\graphics\ca\win\PlatformCAAnimationWin.cpp"
    2894728955                                                        >
  • trunk/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp

    r76853 r76856  
    3131#include "CACFLayerTreeHostClient.h"
    3232#include "LayerChangesFlusher.h"
     33#include "LegacyCACFLayerTreeHost.h"
    3334#include "PlatformCALayer.h"
    3435#include "WebCoreInstanceHandle.h"
    35 #include <WebKitSystemInterface/WebKitSystemInterface.h>
    3636#include <limits.h>
    3737#include <wtf/CurrentTime.h>
    38 #include <wtf/HashMap.h>
    3938#include <wtf/OwnArrayPtr.h>
    40 #include <wtf/OwnPtr.h>
    41 #include <wtf/PassOwnPtr.h>
    42 #include <wtf/StdLibExtras.h>
    43 
    44 #ifndef NDEBUG
    45 #define D3D_DEBUG_INFO
    46 #endif
    47 
    48 #include <d3d9.h>
    49 #include <d3dx9.h>
    50 
    51 using namespace std;
    52 
    53 #pragma comment(lib, "d3d9")
    54 #pragma comment(lib, "d3dx9")
     39
    5540#ifdef DEBUG_ALL
    5641#pragma comment(lib, "QuartzCore_debug")
     
    5944#endif
    6045
    61 static IDirect3D9* s_d3d = 0;
    62 static IDirect3D9* d3d()
    63 {
    64     if (s_d3d)
    65         return s_d3d;
    66 
    67     if (!LoadLibrary(TEXT("d3d9.dll")))
    68         return 0;
    69 
    70     s_d3d = Direct3DCreate9(D3D_SDK_VERSION);
    71 
    72     return s_d3d;
    73 }
    74 
    7546inline static CGRect winRectToCGRect(RECT rc)
    7647{
     
    8455
    8556namespace WebCore {
    86 
    87 static D3DPRESENT_PARAMETERS initialPresentationParameters()
    88 {
    89     D3DPRESENT_PARAMETERS parameters = {0};
    90     parameters.Windowed = TRUE;
    91     parameters.SwapEffect = D3DSWAPEFFECT_COPY;
    92     parameters.BackBufferCount = 1;
    93     parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
    94     parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
    95 
    96     return parameters;
    97 }
    98 
    99 // FIXME: <rdar://6507851> Share this code with CoreAnimation.
    100 static bool hardwareCapabilitiesIndicateCoreAnimationSupport(const D3DCAPS9& caps)
    101 {
    102     // CoreAnimation needs two or more texture units.
    103     if (caps.MaxTextureBlendStages < 2)
    104         return false;
    105 
    106     // CoreAnimation needs non-power-of-two textures.
    107     if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
    108         return false;
    109 
    110     // CoreAnimation needs vertex shader 2.0 or greater.
    111     if (D3DSHADER_VERSION_MAJOR(caps.VertexShaderVersion) < 2)
    112         return false;
    113 
    114     // CoreAnimation needs pixel shader 2.0 or greater.
    115     if (D3DSHADER_VERSION_MAJOR(caps.PixelShaderVersion) < 2)
    116         return false;
    117 
    118     return true;
    119 }
    12057
    12158bool CACFLayerTreeHost::acceleratedCompositingAvailable()
     
    176113}
    177114
    178 // FIXME: Currently there is a LegacyCACFLayerTreeHost for each WebView and each
    179 // has its own WKCACFContext and Direct3DDevice9, which is inefficient.
    180 // (https://bugs.webkit.org/show_bug.cgi?id=31855)
    181 class LegacyCACFLayerTreeHost : public CACFLayerTreeHost {
    182 public:
    183     static PassRefPtr<LegacyCACFLayerTreeHost> create();
    184     virtual ~LegacyCACFLayerTreeHost();
    185 
    186 private:
    187     LegacyCACFLayerTreeHost();
    188 
    189     void initD3DGeometry();
    190 
    191     // Call this when the device window has changed size or when IDirect3DDevice9::Present returns
    192     // D3DERR_DEVICELOST. Returns true if the device was recovered, false if rendering must be
    193     // aborted and reattempted soon.
    194     enum ResetReason { ChangedWindowSize, LostDevice };
    195     bool resetDevice(ResetReason);
    196 
    197     void renderSoon();
    198     void renderTimerFired(Timer<LegacyCACFLayerTreeHost>*);
    199 
    200     virtual void initializeContext(void* userData, PlatformCALayer*);
    201     virtual void resize();
    202     virtual bool createRenderer();
    203     virtual void destroyRenderer();
    204     virtual CFTimeInterval lastCommitTime() const;
    205     virtual void flushContext();
    206     virtual void paint();
    207     virtual void render(const Vector<CGRect>& dirtyRects = Vector<CGRect>());
    208 
    209     Timer<LegacyCACFLayerTreeHost> m_renderTimer;
    210     COMPtr<IDirect3DDevice9> m_d3dDevice;
    211     WKCACFContext* m_context;
    212     bool m_mightBeAbleToCreateDeviceLater;
    213     bool m_mustResetLostDeviceBeforeRendering;
    214 
    215 #ifndef NDEBUG
    216     bool m_printTree;
    217 #endif
    218 };
    219 
    220 PassRefPtr<LegacyCACFLayerTreeHost> LegacyCACFLayerTreeHost::create()
    221 {
    222     return adoptRef(new LegacyCACFLayerTreeHost);
    223 }
    224 
    225115PassRefPtr<CACFLayerTreeHost> CACFLayerTreeHost::create()
    226116{
     
    230120    host->initialize();
    231121    return host.release();
    232 }
    233 
    234 LegacyCACFLayerTreeHost::LegacyCACFLayerTreeHost()
    235     : m_renderTimer(this, &LegacyCACFLayerTreeHost::renderTimerFired)
    236     , m_context(wkCACFContextCreate())
    237     , m_mightBeAbleToCreateDeviceLater(true)
    238     , m_mustResetLostDeviceBeforeRendering(false)
    239 {
    240 #ifndef NDEBUG
    241     char* printTreeFlag = getenv("CA_PRINT_TREE");
    242     m_printTree = printTreeFlag && atoi(printTreeFlag);
    243 #endif
    244122}
    245123
     
    256134}
    257135
    258 void LegacyCACFLayerTreeHost::initializeContext(void* userData, PlatformCALayer* layer)
    259 {
    260     wkCACFContextSetUserData(m_context, userData);
    261     wkCACFContextSetLayer(m_context, layer->platformLayer());
    262 }
    263 
    264136void CACFLayerTreeHost::initialize()
    265137{
     
    285157    CGColorRelease(debugColor);
    286158#endif
    287 }
    288 
    289 LegacyCACFLayerTreeHost::~LegacyCACFLayerTreeHost()
    290 {
    291     wkCACFContextDestroy(m_context);
    292159}
    293160
     
    359226}
    360227
    361 bool LegacyCACFLayerTreeHost::createRenderer()
    362 {
    363     if (m_d3dDevice || !m_mightBeAbleToCreateDeviceLater)
    364         return m_d3dDevice;
    365 
    366     m_mightBeAbleToCreateDeviceLater = false;
    367     D3DPRESENT_PARAMETERS parameters = initialPresentationParameters();
    368 
    369     if (!d3d() || !::IsWindow(window()))
    370         return false;
    371 
    372     // D3D doesn't like to make back buffers for 0 size windows. We skirt this problem if we make the
    373     // passed backbuffer width and height non-zero. The window will necessarily get set to a non-zero
    374     // size eventually, and then the backbuffer size will get reset.
    375     RECT rect;
    376     GetClientRect(window(), &rect);
    377 
    378     if (rect.left-rect.right == 0 || rect.bottom-rect.top == 0) {
    379         parameters.BackBufferWidth = 1;
    380         parameters.BackBufferHeight = 1;
    381     }
    382 
    383     D3DCAPS9 d3dCaps;
    384     if (FAILED(d3d()->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps)))
    385         return false;
    386 
    387     DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE;
    388     if ((d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) && d3dCaps.VertexProcessingCaps)
    389         behaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
    390     else
    391         behaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    392 
    393     COMPtr<IDirect3DDevice9> device;
    394     if (FAILED(d3d()->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window(), behaviorFlags, &parameters, &device))) {
    395         // In certain situations (e.g., shortly after waking from sleep), Direct3DCreate9() will
    396         // return an IDirect3D9 for which IDirect3D9::CreateDevice will always fail. In case we
    397         // have one of these bad IDirect3D9s, get rid of it so we'll fetch a new one the next time
    398         // we want to call CreateDevice.
    399         s_d3d->Release();
    400         s_d3d = 0;
    401 
    402         // Even if we don't have a bad IDirect3D9, in certain situations (e.g., shortly after
    403         // waking from sleep), CreateDevice will fail, but will later succeed if called again.
    404         m_mightBeAbleToCreateDeviceLater = true;
    405 
    406         return false;
    407     }
    408 
    409     // Now that we've created the IDirect3DDevice9 based on the capabilities we
    410     // got from the IDirect3D9 global object, we requery the device for its
    411     // actual capabilities. The capabilities returned by the device can
    412     // sometimes be more complete, for example when using software vertex
    413     // processing.
    414     D3DCAPS9 deviceCaps;
    415     if (FAILED(device->GetDeviceCaps(&deviceCaps)))
    416         return false;
    417 
    418     if (!hardwareCapabilitiesIndicateCoreAnimationSupport(deviceCaps))
    419         return false;
    420 
    421     m_d3dDevice = device;
    422 
    423     initD3DGeometry();
    424 
    425     wkCACFContextSetD3DDevice(m_context, m_d3dDevice.get());
    426 
    427     if (IsWindow(window())) {
    428         rootLayer()->setBounds(bounds());
    429         wkCACFContextFlush(m_context);
    430     }
    431 
    432     return true;
    433 }
    434 
    435 void LegacyCACFLayerTreeHost::destroyRenderer()
    436 {
    437     wkCACFContextSetLayer(m_context, 0);
    438 
    439     wkCACFContextSetD3DDevice(m_context, 0);
    440     m_d3dDevice = 0;
    441     if (s_d3d)
    442         s_d3d->Release();
    443 
    444     s_d3d = 0;
    445     m_mightBeAbleToCreateDeviceLater = true;
    446 
    447     CACFLayerTreeHost::destroyRenderer();
    448 }
    449 
    450228void CACFLayerTreeHost::destroyRenderer()
    451229{
     
    453231    m_rootChildLayer = 0;
    454232    LayerChangesFlusher::shared().cancelPendingFlush(this);
    455 }
    456 
    457 void LegacyCACFLayerTreeHost::resize()
    458 {
    459     if (!m_d3dDevice)
    460         return;
    461 
    462     // Resetting the device might fail here. But that's OK, because if it does it we will attempt to
    463     // reset the device the next time we try to render.
    464     resetDevice(ChangedWindowSize);
    465 
    466     if (rootLayer()) {
    467         rootLayer()->setBounds(bounds());
    468         wkCACFContextFlush(m_context);
    469     }
    470233}
    471234
     
    500263}
    501264
    502 void LegacyCACFLayerTreeHost::renderTimerFired(Timer<LegacyCACFLayerTreeHost>*)
    503 {
    504     paint();
    505 }
    506 
    507 void LegacyCACFLayerTreeHost::paint()
    508 {
    509     createRenderer();
    510     if (!m_d3dDevice) {
    511         if (m_mightBeAbleToCreateDeviceLater)
    512             renderSoon();
    513         return;
    514     }
    515 
    516     CACFLayerTreeHost::paint();
    517 }
    518 
    519265void CACFLayerTreeHost::paint()
    520266{
     
    522268    getDirtyRects(m_window, dirtyRects);
    523269    render(dirtyRects);
    524 }
    525 
    526 void LegacyCACFLayerTreeHost::render(const Vector<CGRect>& windowDirtyRects)
    527 {
    528     ASSERT(m_d3dDevice);
    529 
    530     if (m_mustResetLostDeviceBeforeRendering && !resetDevice(LostDevice)) {
    531         // We can't reset the device right now. Try again soon.
    532         renderSoon();
    533         return;
    534     }
    535 
    536     CGRect bounds = this->bounds();
    537 
    538     // Give the renderer some space to use. This needs to be valid until the
    539     // wkCACFContextFinishUpdate() call below.
    540     char space[4096];
    541     if (!wkCACFContextBeginUpdate(m_context, space, sizeof(space), CACurrentMediaTime(), bounds, windowDirtyRects.data(), windowDirtyRects.size()))
    542         return;
    543 
    544     HRESULT err = S_OK;
    545     CFTimeInterval timeToNextRender = numeric_limits<CFTimeInterval>::infinity();
    546 
    547     do {
    548         // FIXME: don't need to clear dirty region if layer tree is opaque.
    549 
    550         WKCACFUpdateRectEnumerator* e = wkCACFContextCopyUpdateRectEnumerator(m_context);
    551         if (!e)
    552             break;
    553 
    554         Vector<D3DRECT, 64> rects;
    555         for (const CGRect* r = wkCACFUpdateRectEnumeratorNextRect(e); r; r = wkCACFUpdateRectEnumeratorNextRect(e)) {
    556             D3DRECT rect;
    557             rect.x1 = r->origin.x;
    558             rect.x2 = rect.x1 + r->size.width;
    559             rect.y1 = bounds.origin.y + bounds.size.height - (r->origin.y + r->size.height);
    560             rect.y2 = rect.y1 + r->size.height;
    561 
    562             rects.append(rect);
    563         }
    564         wkCACFUpdateRectEnumeratorRelease(e);
    565 
    566         timeToNextRender = wkCACFContextGetNextUpdateTime(m_context);
    567 
    568         if (rects.isEmpty())
    569             break;
    570 
    571         m_d3dDevice->Clear(rects.size(), rects.data(), D3DCLEAR_TARGET, 0, 1.0f, 0);
    572 
    573         m_d3dDevice->BeginScene();
    574         wkCACFContextRenderUpdate(m_context);
    575         m_d3dDevice->EndScene();
    576 
    577         err = m_d3dDevice->Present(0, 0, 0, 0);
    578 
    579         if (err == D3DERR_DEVICELOST) {
    580             wkCACFContextAddUpdateRect(m_context, bounds);
    581             if (!resetDevice(LostDevice)) {
    582                 // We can't reset the device right now. Try again soon.
    583                 renderSoon();
    584                 return;
    585             }
    586         }
    587     } while (err == D3DERR_DEVICELOST);
    588 
    589     wkCACFContextFinishUpdate(m_context);
    590 
    591 #ifndef NDEBUG
    592     if (m_printTree)
    593         rootLayer()->printTree();
    594 #endif
    595 
    596     // If timeToNextRender is not infinity, it means animations are running, so queue up to render again
    597     if (timeToNextRender != numeric_limits<CFTimeInterval>::infinity())
    598         renderSoon();
    599 }
    600 
    601 void LegacyCACFLayerTreeHost::renderSoon()
    602 {
    603     if (!m_renderTimer.isActive())
    604         m_renderTimer.startOneShot(0);
    605270}
    606271
     
    634299}
    635300
    636 void LegacyCACFLayerTreeHost::flushContext()
    637 {
    638     wkCACFContextFlush(m_context);
    639     renderSoon();
    640 }
    641 
    642 CFTimeInterval LegacyCACFLayerTreeHost::lastCommitTime() const
    643 {
    644     return wkCACFContextGetLastCommitTime(m_context);
    645 }
    646 
    647301void CACFLayerTreeHost::notifyAnimationsStarted()
    648302{
     
    666320}
    667321
    668 void LegacyCACFLayerTreeHost::initD3DGeometry()
    669 {
    670     ASSERT(m_d3dDevice);
    671 
    672     CGRect bounds = this->bounds();
    673 
    674     float x0 = bounds.origin.x;
    675     float y0 = bounds.origin.y;
    676     float x1 = x0 + bounds.size.width;
    677     float y1 = y0 + bounds.size.height;
    678 
    679     D3DXMATRIXA16 projection;
    680     D3DXMatrixOrthoOffCenterRH(&projection, x0, x1, y0, y1, -1.0f, 1.0f);
    681 
    682     m_d3dDevice->SetTransform(D3DTS_PROJECTION, &projection);
    683 }
    684 
    685 bool LegacyCACFLayerTreeHost::resetDevice(ResetReason reason)
    686 {
    687     ASSERT(m_d3dDevice);
    688     ASSERT(m_context);
    689 
    690     HRESULT hr = m_d3dDevice->TestCooperativeLevel();
    691 
    692     if (hr == D3DERR_DEVICELOST || hr == D3DERR_DRIVERINTERNALERROR) {
    693         // The device cannot be reset at this time. Try again soon.
    694         m_mustResetLostDeviceBeforeRendering = true;
    695         return false;
    696     }
    697 
    698     m_mustResetLostDeviceBeforeRendering = false;
    699 
    700     if (reason == LostDevice && hr == D3D_OK) {
    701         // The device wasn't lost after all.
    702         return true;
    703     }
    704 
    705     // We can reset the device.
    706 
    707     // We have to release the context's D3D resrouces whenever we reset the IDirect3DDevice9 in order to
    708     // destroy any D3DPOOL_DEFAULT resources that Core Animation has allocated (e.g., textures used
    709     // for mask layers). See <http://msdn.microsoft.com/en-us/library/bb174425(v=VS.85).aspx>.
    710     wkCACFContextReleaseD3DResources(m_context);
    711 
    712     D3DPRESENT_PARAMETERS parameters = initialPresentationParameters();
    713     hr = m_d3dDevice->Reset(&parameters);
    714 
    715     // TestCooperativeLevel told us the device may be reset now, so we should
    716     // not be told here that the device is lost.
    717     ASSERT(hr != D3DERR_DEVICELOST);
    718 
    719     initD3DGeometry();
    720 
    721     return true;
    722 }
    723 
    724322}
    725323
Note: See TracChangeset for help on using the changeset viewer.