Changeset 76856 in webkit
- Timestamp:
- Jan 27, 2011 3:39:50 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r76854 r76856 1 2011-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 1 17 2011-01-27 Patrick Gansterer <paroga@webkit.org> 2 18 -
trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj
r76852 r76856 28944 28944 </File> 28945 28945 <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 28946 28954 RelativePath="..\platform\graphics\ca\win\PlatformCAAnimationWin.cpp" 28947 28955 > -
trunk/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp
r76853 r76856 31 31 #include "CACFLayerTreeHostClient.h" 32 32 #include "LayerChangesFlusher.h" 33 #include "LegacyCACFLayerTreeHost.h" 33 34 #include "PlatformCALayer.h" 34 35 #include "WebCoreInstanceHandle.h" 35 #include <WebKitSystemInterface/WebKitSystemInterface.h>36 36 #include <limits.h> 37 37 #include <wtf/CurrentTime.h> 38 #include <wtf/HashMap.h>39 38 #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 55 40 #ifdef DEBUG_ALL 56 41 #pragma comment(lib, "QuartzCore_debug") … … 59 44 #endif 60 45 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 75 46 inline static CGRect winRectToCGRect(RECT rc) 76 47 { … … 84 55 85 56 namespace 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 }120 57 121 58 bool CACFLayerTreeHost::acceleratedCompositingAvailable() … … 176 113 } 177 114 178 // FIXME: Currently there is a LegacyCACFLayerTreeHost for each WebView and each179 // 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 returns192 // D3DERR_DEVICELOST. Returns true if the device was recovered, false if rendering must be193 // 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 NDEBUG216 bool m_printTree;217 #endif218 };219 220 PassRefPtr<LegacyCACFLayerTreeHost> LegacyCACFLayerTreeHost::create()221 {222 return adoptRef(new LegacyCACFLayerTreeHost);223 }224 225 115 PassRefPtr<CACFLayerTreeHost> CACFLayerTreeHost::create() 226 116 { … … 230 120 host->initialize(); 231 121 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 NDEBUG241 char* printTreeFlag = getenv("CA_PRINT_TREE");242 m_printTree = printTreeFlag && atoi(printTreeFlag);243 #endif244 122 } 245 123 … … 256 134 } 257 135 258 void LegacyCACFLayerTreeHost::initializeContext(void* userData, PlatformCALayer* layer)259 {260 wkCACFContextSetUserData(m_context, userData);261 wkCACFContextSetLayer(m_context, layer->platformLayer());262 }263 264 136 void CACFLayerTreeHost::initialize() 265 137 { … … 285 157 CGColorRelease(debugColor); 286 158 #endif 287 }288 289 LegacyCACFLayerTreeHost::~LegacyCACFLayerTreeHost()290 {291 wkCACFContextDestroy(m_context);292 159 } 293 160 … … 359 226 } 360 227 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 the373 // passed backbuffer width and height non-zero. The window will necessarily get set to a non-zero374 // 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 else391 behaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;392 393 COMPtr<IDirect3DDevice9> device;394 if (FAILED(d3d()->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window(), behaviorFlags, ¶meters, &device))) {395 // In certain situations (e.g., shortly after waking from sleep), Direct3DCreate9() will396 // return an IDirect3D9 for which IDirect3D9::CreateDevice will always fail. In case we397 // have one of these bad IDirect3D9s, get rid of it so we'll fetch a new one the next time398 // 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 after403 // 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 we410 // got from the IDirect3D9 global object, we requery the device for its411 // actual capabilities. The capabilities returned by the device can412 // sometimes be more complete, for example when using software vertex413 // 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 450 228 void CACFLayerTreeHost::destroyRenderer() 451 229 { … … 453 231 m_rootChildLayer = 0; 454 232 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 to463 // 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 }470 233 } 471 234 … … 500 263 } 501 264 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 519 265 void CACFLayerTreeHost::paint() 520 266 { … … 522 268 getDirtyRects(m_window, dirtyRects); 523 269 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 the539 // 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 NDEBUG592 if (m_printTree)593 rootLayer()->printTree();594 #endif595 596 // If timeToNextRender is not infinity, it means animations are running, so queue up to render again597 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);605 270 } 606 271 … … 634 299 } 635 300 636 void LegacyCACFLayerTreeHost::flushContext()637 {638 wkCACFContextFlush(m_context);639 renderSoon();640 }641 642 CFTimeInterval LegacyCACFLayerTreeHost::lastCommitTime() const643 {644 return wkCACFContextGetLastCommitTime(m_context);645 }646 647 301 void CACFLayerTreeHost::notifyAnimationsStarted() 648 302 { … … 666 320 } 667 321 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 to708 // destroy any D3DPOOL_DEFAULT resources that Core Animation has allocated (e.g., textures used709 // 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(¶meters);714 715 // TestCooperativeLevel told us the device may be reset now, so we should716 // not be told here that the device is lost.717 ASSERT(hr != D3DERR_DEVICELOST);718 719 initD3DGeometry();720 721 return true;722 }723 724 322 } 725 323
Note: See TracChangeset
for help on using the changeset viewer.