Symbian3/PDK/Source/GUID-E2A886E1-39FD-517F-870E-3B1BCD49E8CD.dita
author Graeme Price <GRAEME.PRICE@NOKIA.COM>
Fri, 15 Oct 2010 14:32:18 +0100
changeset 15 307f4279f433
parent 14 578be2adaf3e
permissions -rw-r--r--
Initial contribution of the Adaptation Documentation.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-E2A886E1-39FD-517F-870E-3B1BCD49E8CD" xml:lang="en"><title>Off-Screen
Rendering with DirectGDI Tutorial</title><shortdesc>This tutorial shows how to create an image as a target for off-screen
DirectGDI rendering, create a DirectGDI graphics context and use it to issue
draw commands to the image and finally display the image in a Window Server
window. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
<p> <b>Target audience</b>: Device creators. </p>
<note type="note">DirectGDI is deprecated in Symbian^3.</note>
<section id="GUID-CF10022D-6CA1-43DC-8483-8FD62432885D"><title>Introduction</title> <p>In early versions of Symbian, off-screen
rendering was always performed by using <xref href="GUID-EAAD1719-C02C-5705-A5C3-993E36441BE6.dita">BitGDI</xref>.
This had the disadvantage that the rendering could not be hardware accelerated.
Later versions of Symbian introduced <xref href="GUID-AB93B01C-B6C2-5B24-ADEF-95706584D625.dita">OpenGL
ES</xref> (in v8.1) and <xref href="GUID-1B1C6D35-FFDF-55B3-BCE2-DD0295858E49.dita">OpenVG</xref> (in
v9.4), which provide alternative mechanisms for off-screen rendering that
can be hardware accelerated. However, these APIs are very different to the
BitGDI API. Therefore porting legacy code from BitGDI to OpenGL ES or OpenVG
in order to take advantage of graphics acceleration hardware is a considerable
task. </p> <p>DirectGDI can take advantage of graphics acceleration hardware
if it is available and (unlike OpenGL ES and OpenVG) provides an API that
is very similar to BitGDI. This means that porting legacy code to DirectGDI
is much easier than porting it to OpenGL ES or OpenVG. In addition, you typically
need to port legacy code only if it does off-screen rendering. Legacy code
that does on-screen rendering using <xref href="GUID-FF93C803-8E07-3753-BBA8-C9267D686C85.dita"><apiname>CWindowGc</apiname></xref> will
automatically be hardware accelerated if the Window Server's <xref href="GUID-3A2785D4-6185-50C3-8D7E-5D94CD2B7C98.dita">render
stage plug-in(s)</xref> are hardware accelerated. </p> <p>This tutorial shows
you how to perform off-screen rendering using DirectGDI. </p> </section>
<section id="GUID-F43861F5-F52F-43C3-BD34-C7255E81461A"><title>Required background</title> <p>This tutorial assumes a background
knowledge of the following: </p> <ul>
<li id="GUID-EB26018E-E6AC-5482-9569-CA7143770446"><p><xref href="GUID-CD4B8ECA-AFE7-593C-B095-5D642EA2EC61.dita">DirectGDI</xref>  </p> </li>
<li id="GUID-C14490E6-D646-5697-B0E9-77A63F6BC8DD"><p><xref href="GUID-59C9EF92-8207-5FA5-AA20-0DB00C211BF1.dita">Graphics
Resource Component</xref>  </p> </li>
<li id="GUID-CF71C104-6418-5902-A122-3A3F0E665853"><p><xref href="GUID-0C4B86B5-530A-5839-86C1-46E7ABE281E0.dita">Window
Server</xref>. </p> </li>
</ul> </section>
<section id="GUID-5C530A85-85E9-49A1-A36A-6031B05D7D5A"><title> Procedure</title> <p><b>1. Create the image to store the
results </b> </p> <p>The first step is to create the image (<xref href="GUID-EDC0E03F-37F6-3BEC-8FF3-D03C3CDB949C.dita"><apiname>RSgImage</apiname></xref>)
that we will use to store the results of the off-screen rendering. For example: </p> <codeblock id="GUID-8AA4CD71-A476-558C-BD31-CAF9484D592E" xml:space="preserve">// Create an image for off-screen DirectGDI rendering.
TSgImageInfo info;
info.iSizeInPixels = TSize(KWidth, KHeight); 
info.iPixelFormat = EUidPixelFormatARGB_8888_PRE;

// Usage is (1) to store results of DirectGDI rendering and 
// (2) display on screen through the Window Server.
info.iUsage = ESgUsageWindowGcSource | ESgUsageDirectGdiTarget; 

info.iShareable = ETrue; // Must be shared with the Window Server.
RSgImage image;
err = image.Create(info, NULL, 0); // Undefined initial contents.
User::LeaveIfError(err);</codeblock> <p>Notice that the <xref href="GUID-EDC0E03F-37F6-3BEC-8FF3-D03C3CDB949C.dita"><apiname>Create()</apiname></xref> function
takes a <xref href="GUID-FE0BB820-00B3-3E13-907A-FAFB2D20D43B.dita"><apiname>TSgImageInfo</apiname></xref> structure as an argument.
This specifies the pixel format and image usage. There are two ways to choose
the pixel format: </p> <ul>
<li id="GUID-16B2727E-1A63-5BCD-BDD9-D2CB7E5F876C"><p>Look up the document <xref href="GUID-29C7FBFB-2F33-58CA-86BE-978E3187E4D6.dita">image compatibility guarantees</xref> and
select an appropriate one. This is the approach that we use here. </p> </li>
<li id="GUID-C80BC79F-A583-504D-AEF3-14C8E985D519"><p>Call the static <xref href="GUID-EDC0E03F-37F6-3BEC-8FF3-D03C3CDB949C.dita#GUID-EDC0E03F-37F6-3BEC-8FF3-D03C3CDB949C/GUID-3A431525-E5D7-323B-95B4-1A910A0585D7"><apiname>RSgImage::GetPixelFormats()</apiname></xref> function to find out at runtime
which pixel formats are supported by the platform. </p> </li>
</ul> <p>Notice that we specify the usage not only as a target for DirectGDI
rendering but also as a source for the Window Server, because ultimately we
want to display the results on the screen. </p> <p> </p> <p><b>2. Draw using
DirectGDI </b> </p> <p>Now we have created the image, we need to set the image
as the target for DirectGDI rendering and then create a DirectGDI graphics
context and use it to draw to the image. Here are the steps: </p> <ol id="GUID-B30F723D-5893-5D8E-BE41-C2B7BBA239A3">
<li id="GUID-5F233DE0-D770-5D5E-9E0E-EF01E47F50D8"><p>Open the DirectGDI driver
for use in this thread: </p> <codeblock id="GUID-B06B6A61-544D-5A0D-99FE-279980B527CB" xml:space="preserve">err = CDirectGdiDriver::Open();
User::LeaveIfError(err);
CDirectGdiDriver* driver = CDirectGdiDriver::Static();</codeblock> </li>
<li id="GUID-83648812-B494-5E0D-9767-86E7D87AC84C"><p>Create the DirectGDI
rendering target using the image that we created earlier: </p> <codeblock id="GUID-06DFFE10-550B-5DE4-8F45-064ADEA31C21" xml:space="preserve">RDirectGdiImageTarget target(*driver);
err = target.Create(image);
User::LeaveIfError(err);</codeblock> </li>
<li id="GUID-4D65C671-85AC-5D97-9A6B-814B3B4D524A"><p>Create a DirectGDI context
and call <xref href="GUID-EDC0E03F-37F6-3BEC-8FF3-D03C3CDB949C.dita"><apiname>Activate()</apiname></xref> to bind our off-screen
rendering target with it: </p> <codeblock id="GUID-50BDCA46-3672-5FB1-9B11-334E2EE76E4C" xml:space="preserve">CDirectGdiContext* context = CDirectGdiContext::NewL(*driver);
err = context-&gt;Activate(target);
User::LeaveIfError(err);</codeblock> </li>
<li id="GUID-778AE617-7100-5E53-B710-5F90BCE81C9D"><p>Use the DirectGDI context's
draw commands to draw to our off-screen rendering target: </p> <codeblock id="GUID-8A0D3B1F-022D-5AAC-B8EE-DADA1DD7F561" xml:space="preserve">context-&gt;SetBrushColor(KRgbWhite);
context-&gt;SetDrawMode(DirectGdi::EDrawModeWriteAlpha);
context-&gt;Clear();
context-&gt;SetDrawMode(DirectGdi::EDrawModePEN);
context-&gt;SetPenColor(KRgbBlue);
context-&gt;SetPenStyle(DirectGdi::EDottedPen);
context-&gt;DrawEllipse(KEllipseRect);</codeblock> </li>
<li id="GUID-C2B1474C-8EA5-5ACF-8388-33619DE0BD0E"><p>Call <xref href="GUID-0C7CD826-95FD-3DD2-9394-3A20316C9C61.dita#GUID-0C7CD826-95FD-3DD2-9394-3A20316C9C61/GUID-619EE303-1D26-33FD-AFEB-C767E8BDD71F"><apiname>CDirectGdiDriver::Finish()</apiname></xref> to
ensure that all of the drawing commands have been processed: </p> <codeblock id="GUID-5391B93E-C8AA-5665-B39E-24AB2D49BF15" xml:space="preserve">driver-&gt;Finish();</codeblock> </li>
</ol> <p><b>3. Display the results on the screen </b> </p> <p>The final stage
is to display the image that we have used as our off-screen rendering target
on the screen. We do this by drawing the image to a Window Server window,
like this: </p> <ol id="GUID-8C268931-8505-5AAA-BA95-269F7899B659">
<li id="GUID-42C8F3B6-2500-5519-9126-7B629C3BEAE4"><p>Prepare the image for
use as a source in a Window Server context: </p> <codeblock id="GUID-69D359B5-C904-5FDE-B412-721C421FAD8D" xml:space="preserve">RWsSession&amp; wsSession = GetMyWsSession();
RWsDrawableSource source(wsSession);
err = source.Create(image, screenNumber);
User::LeaveIfError(err);</codeblock> </li>
<li id="GUID-ABCEF123-7786-5BE0-B7D2-748896379A75"><p>Use the Window Server
context to draw the image in a window: </p> <codeblock id="GUID-B29FEDA0-5316-56E3-8929-54C8574D7285" xml:space="preserve">CWindowGc* windowContext = ActivateMyWindowContext();
windowContext-&gt;DrawResource(TPoint(0, 0), source);</codeblock> </li>
</ol> </section>
</conbody><related-links>
<link href="GUID-59C9EF92-8207-5FA5-AA20-0DB00C211BF1.dita"><linktext>Graphics
Resource Overview</linktext></link>
<link href="GUID-29C7FBFB-2F33-58CA-86BE-978E3187E4D6.dita"><linktext>Image Compatibility
Guarantees</linktext></link>
<link href="GUID-CD4B8ECA-AFE7-593C-B095-5D642EA2EC61.dita"><linktext> DirectGDI
Overview</linktext></link>
</related-links></concept>