os/graphics/graphicsdeviceinterface/directgdiadaptation/hwsrc/directgdiimagetargetimpl.cpp
First public contribution.
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "directgdiadapter.h"
17 #include "directgdiimagetargetimpl.h"
18 #include "directgdidriverimpl.h"
19 #include "confighelper.h"
22 Constructs a CDirectGdiImageTargetImpl.
23 @param aDriver The driver implementation which created this target.
25 CDirectGdiImageTargetImpl::CDirectGdiImageTargetImpl(CDirectGdiDriverImpl& aDriver) :
27 iSurface(EGL_NO_SURFACE),
28 iContext(EGL_NO_CONTEXT)
33 Destructor for CDirectGdiImageTargetImpl - Destroys the EGL surface.
34 It will remove itself from the driver's image target array, before deleting itself.
36 CDirectGdiImageTargetImpl::~CDirectGdiImageTargetImpl()
38 #ifdef _DEBUG_DIRECTGDI
39 GRAPHICS_LOG_DEBUG("Destroying CDirectGdiImageTargetImpl");
41 if (iDriver.IsCurrentTarget(this))
43 iDriver.SetCurrentTarget(NULL);
46 if (iSurface != EGL_NO_SURFACE)
48 // If the surface being deleted is current to EGL, it will defer the destruction of the surface
49 // until something else is made current. Destruction would rather be immediate so that the
50 // associated native pixmap can be used again. In that case, the surface is dereferenced by making
51 // something else current.
52 if (eglGetCurrentSurface(EGL_DRAW) == iSurface)
54 eglMakeCurrent(iDriver.EglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
57 eglDestroySurface(iDriver.EglDisplay(), iSurface);
59 iDriver.UnregisterTargetImage(*this);
63 Two-phase construction of a CDirectGdiImageTargetImpl object.
64 @param aImage On success, holds a pointer to the newly-created image.
65 @param aDriver The driver to register this image with.
66 @param aSgImage The RSgImage which this image will be based upon.
67 @param aContexts A hash map of already-created EGLContext/Config pairs.
68 @param aConfigs A hash map of EGLConfig/Attribute pairs.
69 @param aSharedContext A reference to the current shared context.
70 @return KErrNone if successful, KErrNoMemory if not enough memory could be allocated, otherwise a return
71 value from Construct().
73 TInt CDirectGdiImageTargetImpl::New(CDirectGdiImageTargetImpl*& aImage,
74 CDirectGdiDriverImpl& aDriver,
75 const RSgImage& aSgImage,
76 RHashMap<TInt, EGLContext>& aContexts,
77 RHashMap<TInt, EGLConfig>& aConfigs,
78 EGLContext& aSharedContext)
80 CDirectGdiImageTargetImpl* image = new CDirectGdiImageTargetImpl(aDriver);
83 TInt err = image->Construct(aSgImage, aContexts, aConfigs, aSharedContext);
92 Gets the supplied image structure and sets the internal data. It creates a new image target by creating
93 an EGL context corresponding to a pixel type and an EGL config (if the EGLContext is not already created).
94 If it was already there, it fetches the EGL context from the hash map. Creates an EGL surface that is then
95 set for use by the new target object. Targets that are successfully created are added to an array of targets
96 so that they can be closed and deleted correctly at a later stage.
98 @param aSgImage The RSgImage to create the source image from.
99 @param aContexts A hash map of already-created EGLContext/Config pairs.
100 @param aConfigs A hash map of EGLConfig/Attribute pairs.
101 @param aSharedContext A reference to the current shared context.
102 @return KErrNone if successful, otherwise an error from CDirectGdiImageRef::Construct().
104 @panic DGDIAdapter 41, if a matching EGL config is not found for this RSgImage.
105 @panic DGDIAdapter 42, if an EGLSurface cannot be created.
106 @panic DGDIAdapter 43, if an EGLContext cannot be created.
108 TInt CDirectGdiImageTargetImpl::Construct(const RSgImage& aSgImage, RHashMap<TInt, EGLContext>& aContexts, RHashMap<TInt, EGLConfig>& aConfigs, EGLContext& aSharedContext)
111 EGLSurface surface = EGL_NO_SURFACE;
112 EGLContext* context = NULL;
113 EGLContext newContext = EGL_NO_CONTEXT;
114 TBool createdNewContext = EFalse;
115 TInt pixmapAttribs = 0;
116 const EGLDisplay display = iDriver.EglDisplay();
118 TInt err = CDirectGdiImageRef::Construct(aSgImage);
122 err = iSgImage.GetInfo(info);
127 // Create an EGL target surface.
128 // Get the right Config index for this RSgImage format.
129 pixmapAttribs = TConfigHelper::MatchPixelType(info.iPixelFormat);
130 EGLConfig* currentConfig = aConfigs.Find(pixmapAttribs);
131 GRAPHICS_ASSERT_ALWAYS(currentConfig, EDirectGdiPanicNoConfigFound);
133 // Set up the surface attribs.
134 const EGLint eglAlphaFormat = (info.iPixelFormat == EUidPixelFormatARGB_8888_PRE) ? EGL_VG_ALPHA_FORMAT_PRE : EGL_VG_ALPHA_FORMAT_NONPRE;
135 EGLint attributeList[] = {EGL_VG_ALPHA_FORMAT, eglAlphaFormat,
136 EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB,
139 // Create an EGL target surface.
140 surface = eglCreatePixmapSurface(display, *currentConfig, (RSgImage*)&iSgImage, attributeList);
141 GRAPHICS_ASSERT_ALWAYS(surface != EGL_NO_SURFACE, EDirectGdiPanicNoDrawingSurface);
143 // See if we have already created a context for this pixel format, create
144 // one if we haven't and save it for reuse later.
145 context = aContexts.Find(pixmapAttribs);
148 newContext = eglCreateContext(display, *currentConfig, aSharedContext, NULL);
149 GRAPHICS_ASSERT_ALWAYS(newContext != EGL_NO_CONTEXT, EDirectGdiPanicNoContext);
150 err = aContexts.Insert(pixmapAttribs, newContext);
152 context = &newContext;
153 createdNewContext = ETrue;
159 err = iDriver.RegisterTargetImage(*this);
164 // Everything went well.
167 if (createdNewContext)
168 aSharedContext = iContext;
174 if (surface != EGL_NO_SURFACE)
176 eglDestroySurface(display, surface);
178 if (createdNewContext)
182 eglDestroyContext(display, *context);
184 if (aContexts.Find(pixmapAttribs))
186 aContexts.Remove(pixmapAttribs);
195 Sets the passed EGLSurface as the current rendering target for EGL, sets the passed
196 EGLContext as the current context. The surface will be used for both read and write
197 operations. The previously current context will be flushed at this point.
199 @pre The target has been successfully constructed.
201 @return ETrue if activation was successful, otherwise EFalse.
203 TBool CDirectGdiImageTargetImpl::Activate()
205 return (EGL_TRUE == eglMakeCurrent(iDriver.EglDisplay(), iSurface, iSurface, iContext));