direct2d reader project spartan windows 8.1

Post on 19-Dec-2015

255 Views

Category:

Documents

8 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Anthony HodsdonSoftware Developer, Windows GraphicsWhat’s New in Direct2D and DirectWrite for Windows 10

What’s New in Direct2D and DirectWrite for Windows 10

3-775

What are Direct2D and DirectWrite?Text and Font Handling EnhancementsImaging EnhancementsEffect EnhancementsNew 2D Primitives

Agenda

Direct2D and DirectWrite

What are Direct2D and DirectWrite?

DirectWrite

Fonts Layout

Direct2D

Text

What are Direct2D and DirectWrite?

XAMLDWM

Shell

Reader Project Spartan

Win2D

Text

Scalable text rendering improvements

Standard text rendering:• Bitmap-based glyph cache• Optimized for fixed zoom levels but• Requires re-rasterization at each

text size • Inappropriate for text zooming

Scalable text rendering improvements

Windows 8.1

Common mitigation:• Render to a bitmap and scale• Fast but produces blurry results

Scalable text rendering improvements

Windows 8.1

Accelerated vector text rendering:• Improved vector text rendering

algorithm• Hardware glyph cache extended to

support size-independent vector text

• Net result: both fast and crisp text while zooming

Scalable text rendering improvements

Windows 10

Vector text demo

void Setup(){ m_dwriteFactory->CreateCustomRenderingParams( gamma, enhancedContrast, grayscaleEnhancedContrast, clearTypeLevel, pixelGeometry, DWRITE_RENDERING_MODE_OUTLINE, gridFitMode, &m_outlineParams );}

Scalable text rendering improvements

void OnRender({ if (animating) { d2dContext->SetTextRenderingParams( m_outlineParams.Get() ); }

d2dContext->DrawTextLayout(/* … */);}

Scalable text rendering improvements

Suggested usage:• Use standard text rendering for

static text to get the best possible quality

• Switch to vector text rendering during manipulations and animations

• Best on feature level 10+ hardware

Scalable text rendering improvements

When do I use vector text?

Font selection

Fonts

• Developers can target phone, tablet, and PC but

• Not all fonts available on phone• Full suite of desktop fonts: ~½ GB

• Net result: Inconsistent document viewing experience

Font selection

Windows 8.1

Windows 10 divides fonts into two classes:• Recommended fonts:

• Guaranteed available on all devices• Includes common UI and document fonts

• Optional fonts:• May or may not be present on all devices• Hosted in the cloud via a Microsoft service• Downloadable just-in-time during app

execution

Downloadable fonts

Windows 10

Key features:• Asynchronous

• Pending fonts use font fallback

• Global font cache• Downloadable fonts can be shared across

processes• Size of cache scales depending on the

device

• Supported in both DirectX and XAML apps

Downloadable fonts

Windows 10

Downloadable fonts demo

spDwriteFactory->GetSystemFontCollection( TRUE, // include downloadable fonts &spFontCollection );

spDwriteFactory->CreateTextFormat( L"Gabriola", spFontCollection, /* ... */ &spTextFormat );

Downloadable fonts

class MyFontDownloadListener : IDWriteFontDownloadListener{ STDMETHOD_(void, DownloadCompleted)( /* ... */) { RerenderDocument(); }}

spDwriteFactory->GetFontDownloadQueue(/* ... */, &spQueue);spQueue->AddListener(/* ... */);spQueue->BeginDownload();

Downloadable fonts

Suggested usage:• Use fonts in the recommended set

for UI text• Ensures UI is consistent, even when offline• Limits bandwidth usage when online

• Use downloadable fonts to maintain document fidelity

Downloadable fonts

When do I use downloadable fonts?

Font enumeration

Fonts

Font collections:• Highly structured mechanism for

enumerating fonts

Font enumeration

Windows 8.1

Font sets:• More flexible alternative to font

collections

Font enumeration

Windows 10

Font enumeration

Font collections and font sets compared

IDWriteFontCollection IDWriteFontSet

Filtering criteria Family name

Family name; Postscript name; Script/language; Weight;…

Custom construction

Requires implementing loader callback interface

Simple builder pattern

Font selection Local and downloadable Local and downloadable

Font property queries Local only Local and downloadable

Plus: Easy interop between font collections and font sets

spDwriteFactory->GetSystemFontSet( &spSystemFontSet );

DWRITE_FONT_PROPERTY properties = { { DWRITE_FONT_PROPERTY_ID_STYLE, L"2" /* italic */, nullptr }, { DWRITE_FONT_PROPERTY_ID_WEIGHT, L"700" /* bold */, nullptr }, };

ComPtr<IDWriteFontSet> spMatchingFonts spSystemFontSet->GetMatchingFonts( properties, ARRAYSIZE(properties), &spMatchingFonts );

Font enumeration

Image loading and rendering

Different APIs for different scenarios:• CreateBitmapFromWicBitmap• Bitmap source effect• YCbCr effect

Substantial amount of code required to get optimal performance

Image loading and rendering

Windows 8.1

YCbCr image loading in Windows 8.1 (Part 1)bool JpegYCbCrOptimizationsRenderer::DoesWicSupportRequestedYCbCr()

{ ComPtr<IWICPlanarBitmapSourceTransform> wicPlanarSource; HRESULT hr = m_wicScaler.As(&wicPlanarSource); if (SUCCEEDED(hr)) { BOOL isTransformSupported; uint32 supportedWidth = m_cachedBitmapPixelWidth; uint32 supportedHeight = m_cachedBitmapPixelHeight; DX::ThrowIfFailed( wicPlanarSource->DoesSupportTransform( &supportedWidth, &supportedHeight, WICBitmapTransformRotate0, WICPlanarOptionsDefault, SampleConstants::WicYCbCrFormats, m_planeDescriptions, SampleConstants::NumPlanes, &isTransformSupported ) );  if ((isTransformSupported == TRUE) && (supportedWidth == m_cachedBitmapPixelWidth) && (supportedHeight == m_cachedBitmapPixelHeight)) { return true; } }  return false;} bool JpegYCbCrOptimizationsRenderer::DoesDriverSupportYCbCr(){ auto d2dContext = m_deviceResources->GetD2DDeviceContext();  if ((d2dContext->IsDxgiFormatSupported(DXGI_FORMAT_R8_UNORM)) && (d2dContext->IsDxgiFormatSupported(DXGI_FORMAT_R8G8_UNORM))) { return true; }  return false;}

void JpegYCbCrOptimizationsRenderer::CreateYCbCrDeviceResources(){

  auto wicFactory = m_deviceResources->GetWicImagingFactory(); auto d2dContext = m_deviceResources->GetD2DDeviceContext(); ComPtr<IWICPlanarBitmapSourceTransform> wicPlanarSource; DX::ThrowIfFailed( m_wicScaler.As(&wicPlanarSource) );  ComPtr<IWICBitmap> bitmaps[SampleConstants::NumPlanes]; ComPtr<IWICBitmapLock> locks[SampleConstants::NumPlanes]; WICBitmapPlane planes[SampleConstants::NumPlanes];  for (uint32 i = 0; i < SampleConstants::NumPlanes; i++) { DX::ThrowIfFailed( wicFactory->CreateBitmap( m_planeDescriptions[i].Width, m_planeDescriptions[i].Height, m_planeDescriptions[i].Format, WICBitmapCacheOnLoad, &bitmaps[i] ) );  LockBitmap(bitmaps[i].Get(), WICBitmapLockWrite, nullptr, &locks[i], &planes[i]); }  DX::ThrowIfFailed( wicPlanarSource->CopyPixels( nullptr, m_cachedBitmapPixelWidth, m_cachedBitmapPixelHeight, WICBitmapTransformRotate0, WICPlanarOptionsDefault, planes, SampleConstants::NumPlanes ) );  DX::ThrowIfFailed(d2dContext->CreateEffect(CLSID_D2D1YCbCr, &m_d2dYCbCrEffect));  ComPtr<ID2D1Bitmap1> d2dBitmaps[SampleConstants::NumPlanes]; for (uint32 i = 0; i < SampleConstants::NumPlanes; i++) { locks[i] = nullptr; DX::ThrowIfFailed(d2dContext->CreateBitmapFromWicBitmap(bitmaps[i].Get(), &d2dBitmaps[i])); m_d2dYCbCrEffect->SetInput(i, d2dBitmaps[i].Get()); }}

YCbCr image loading in Windows 8.1 (Part 2)

void JpegYCbCrOptimizationsRenderer::LockBitmap( _In_ IWICBitmap *pBitmap, DWORD bitmapLockFlags, _In_opt_ const WICRect *prcSource, _Outptr_ IWICBitmapLock **ppBitmapLock, _Out_ WICBitmapPlane *pPlane ){ ComPtr<IWICBitmapLock> lock; DX::ThrowIfFailed(pBitmap->Lock(prcSource, bitmapLockFlags, &lock)); DX::ThrowIfFailed(lock->GetStride(&pPlane->cbStride)); DX::ThrowIfFailed(lock->GetDataPointer(&pPlane->cbBufferSize, &pPlane->pbBuffer)); DX::ThrowIfFailed(lock->GetPixelFormat(&pPlane->Format)); *ppBitmapLock = lock.Detach();} void JpegYCbCrOptimizationsRenderer::CreateBgraDeviceResources(){ auto wicFactory = m_deviceResources->GetWicImagingFactory(); auto d2dContext = m_deviceResources->GetD2DDeviceContext();  ComPtr<IWICFormatConverter> formatConverter; DX::ThrowIfFailed(wicFactory->CreateFormatConverter(&formatConverter));  DX::ThrowIfFailed( formatConverter->Initialize( m_wicScaler.Get(), GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.0L, WICBitmapPaletteTypeCustom ) );  ComPtr<ID2D1Bitmap1> bgraBitmap; DX::ThrowIfFailed(d2dContext->CreateBitmapFromWicBitmap(formatConverter.Get(), &bgraBitmap)); DX::ThrowIfFailed(d2dContext->CreateEffect(CLSID_D2D12DAffineTransform, &m_d2dTransformEffect)); m_d2dTransformEffect->SetInput(0, bgraBitmap.Get());} 

void JpegYCbCrOptimizationsRenderer::CreateDeviceIndependentResources(){ auto wicFactory = m_deviceResources->GetWicImagingFactory();  ComPtr<IWICBitmapDecoder> decoder; DX::ThrowIfFailed( wicFactory->CreateDecoderFromFilename( L"mammoth.jpg", nullptr, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &decoder ) );  ComPtr<IWICBitmapFrameDecode> frameDecode; DX::ThrowIfFailed( decoder->GetFrame(0, &frameDecode) );  uint32 imageWidth, imageHeight; DX::ThrowIfFailed( frameDecode->GetSize(&imageWidth, &imageHeight) );  GetDisplayResolution(); float horzScale = static_cast<float>(m_displayResolutionX) / static_cast<float>(imageWidth); float vertScale = static_cast<float>(m_displayResolutionY) / static_cast<float>(imageHeight); float scale = min(horzScale, min(vertScale, 1.0f)); m_cachedBitmapPixelWidth = static_cast<uint32>(imageWidth * scale); m_cachedBitmapPixelHeight = static_cast<uint32>(imageHeight * scale);  DX::ThrowIfFailed( wicFactory->CreateBitmapScaler(&m_wicScaler) );  DX::ThrowIfFailed( m_wicScaler->Initialize( frameDecode.Get(), m_cachedBitmapPixelWidth, m_cachedBitmapPixelHeight, WICBitmapInterpolationModeLinear ) );}

YCbCr image loading in Windows 8.1 (Part 3)

offset.height = (size.Height - DX::ConvertPixelsToDips(static_cast<float>(m_cachedBitmapPixelHeight), dpi) * scale) / 2;  D2D1::Matrix3x2F transform = D2D1::Matrix3x2F::Scale(scale, scale) * D2D1::Matrix3x2F::Translation(offset);  switch (m_sampleMode) { case YCbCrSupportMode::DisabledFallback: case YCbCrSupportMode::DisabledForced: DX::ThrowIfFailed( m_d2dTransformEffect->SetValue( D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX, transform ) );  break;  case YCbCrSupportMode::Enabled: DX::ThrowIfFailed( m_d2dYCbCrEffect->SetValue( D2D1_YCBCR_PROP_TRANSFORM_MATRIX, transform ) );  break;  case YCbCrSupportMode::Unknown: default: DX::ThrowIfFailed(E_FAIL); } }}

void JpegYCbCrOptimizationsRenderer::CreateDeviceDependentResources(bool forceBgra){ if (forceBgra == false) { if (DoesWicSupportRequestedYCbCr() && DoesDriverSupportYCbCr()) { CreateYCbCrDeviceResources(); m_sampleMode = YCbCrSupportMode::Enabled; } else { CreateBgraDeviceResources(); m_sampleMode = YCbCrSupportMode::DisabledFallback; } } else { CreateBgraDeviceResources(); m_sampleMode = YCbCrSupportMode::DisabledForced; }} void JpegYCbCrOptimizationsRenderer::CreateWindowSizeDependentResources(){ if (m_deviceResourceTaskMode == Completed) { auto size = m_deviceResources->GetLogicalSize(); float dpi = m_deviceResources->GetDpi();  float horzScale = size.Width / DX::ConvertPixelsToDips(static_cast<float>(m_cachedBitmapPixelWidth), dpi); float vertScale = size.Height / DX::ConvertPixelsToDips(static_cast<float>(m_cachedBitmapPixelHeight), dpi); float scale = min(horzScale, min(vertScale, 1.0f));  D2D1_SIZE_F offset; offset.width = (size.Width - DX::ConvertPixelsToDips(static_cast<float>(m_cachedBitmapPixelWidth), dpi) * scale) / 2;

Image source:• Simple, efficient API for loading and

rendering images

Image loading and rendering

Windows 10

void Setup(){ m_spD2DFactory->CreateImageSourceFromWic( spWicBitmapSource, loadingOptions, alphaMode, &m_spImageSource);}

void OnRender(){ m_spDrawingContext->DrawImage(m_spImageSource);}

Image loading and rendering

Image source advantages:• Support for arbitrarily large images• Easy integration with printing and

effects• Numerous baked-in optimizations

Image loading and rendering

Windows 10

Image effect optimizations

Image effect optimizations

What are image effects?

Saturation

Hue rotation

Gaussian blur

Image effect optimizations

Contrast effect

Exposure effect

Temp/tint effect

Saturation effect

Image effect optimizations

Contrast effect

Exposure effect

Temp/tint effect

Saturation effect

Shader pass 1 Shader pass 2 Shader pass 3

Shader pass 4 Shader pass 5

Windows 8.1:

Image effect optimizations

Contrast effect

Exposure effect

Temp/tint effect

Saturation effect

Shader pass 1

Shader pass 2

Windows 10 (Shader linking):

Shader linking demo

• Built-in effects get shader linking applied automatically.

• Custom effects should use new HLSL macros. (See details here)

Image effect optimizations

How can I use shader linking in my app?

New image effects

New image effectsAnalysisHistogram

FilterGaussian blurDirectional blurConvolve matrixMorphologyEdge Detection

CompositeCompositeArithmetic compositeBlend

TransparencyLuminance to alphaChroma key

PhotoBrightnessContrastExposureGrayscaleHighlights and ShadowsInvertSepiaSharpenStraightenTemperature and TintVignette

SourceBitmap sourceFloodTurbulence

StylizePoint-specularSpot-specularDistant-specularPoint-diffuseSpot-diffuseDistant-diffuseShadowDisplacement mapEmbossPosterize

TransformTileCropBorderScale2D affine transform3D perspective transform3D transformAtlasDPI Compensation

ColorDiscrete transferTable transferLinear transferGamma transferColor matrixSaturationHue rotationColor managementPremultiplyUnpremultiplyDPI compensationOpacity metadataYCbCrHueToRgbRgbToHueLookup Table 3D

New 2D primitives

Inking

Inking

Windows 10

Composition

XAML Ink Canvas

Direct2D

Input

Ink Presenter

…Graphics

New Features:• Hardware accelerated• Low latency• High fidelity

Inking

Windows 10

Inking demo

Check out DirectInk talks here for more details.

Inking

Learn more

Gradients

Gradients

Windows 8.1

Two types of gradients:

Linear gradientbrush

Radial gradientbrush

Gradients

Windows 10

New, more flexible gradient type:

Gradient Mesh

Gradients

Gradient mesh patch:• 4 colors• 16 positional control

points

D2D1_GRADIENT_MESH patchList[] ={ D2D1::GradientMeshPatch( D2D1::Point2F(10, 110), // (bottom left corner) /* ... */ D2D1::Point2F(110, 10), // (upper right corner) D2D1::ColorF(D2D1::ColorF::Green), // (bottom left corner) /* ... */ D2D1::ColorF(D2D1::ColorF::Orange), // (upper right corner) D2D1_PATCH_EDGE_MODE_ANTIALIASED, D2D1_PATCH_EDGE_MODE_ANTIALIASED, D2D1_PATCH_EDGE_MODE_ANTIALIASED, D2D1_PATCH_EDGE_MODE_ALIASED)};

Gradients

void Setup(){ spD2dContext->CreateGradientMesh( patchList, ARRAYSIZE(patchList), &m_spGradientMesh ));}

void OnRender(){ spD2dContext->DrawGradientMesh(m_spGradientMesh);}

Gradients

Gradient mesh demo

In Windows 10, your DirectX application will be:

• Faster

• More maintainable

• More consistent across devices

• More beautiful

Summary

Direct2D Documentation: MSDNDirectWrite Documentation: MSDNFont Usage Documentation: MSDN

Resources and related sessions

# Title Speakers Time631 Introducing Win2D: DirectX-powered Drawing in C# Simon Tao Wed 2:00 –

3:00

681 Introducing Direct Ink: Learn how to Unlock New Opportunities Using Ink in Your App

Sriram Subramanian; Ryan Harris (Silicon Benders); Miles Harris (Silicon Benders)

Thurs 2:00 – 3:00

705 Harness the full power of Digital Inking in your Universal Windows app with Ink Recognition, Advanced Ink Processing and more

Francis Zhou; Xiao Tu Thurs 5:00 – 6:00

© 2015 Microsoft Corporation. All rights reserved.

top related