Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / renderer / d3d / d3d9 / RenderTarget9.cpp
1 //
2 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // RenderTarget9.cpp: Implements a D3D9-specific wrapper for IDirect3DSurface9
8 // pointers retained by renderbuffers.
9
10 #include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
11 #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
12 #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
13 #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
14 #include "libGLESv2/main.h"
15
16 namespace rx
17 {
18
19 // TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being given.
20 RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface)
21 {
22     mRenderer = Renderer9::makeRenderer9(renderer);
23     mRenderTarget = surface;
24
25     if (mRenderTarget)
26     {
27         D3DSURFACE_DESC description;
28         mRenderTarget->GetDesc(&description);
29
30         mWidth = description.Width;
31         mHeight = description.Height;
32         mDepth = 1;
33
34         const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(description.Format);
35         mInternalFormat = d3dFormatInfo.internalFormat;
36         mActualFormat = d3dFormatInfo.internalFormat;
37         mSamples = d3d9_gl::GetSamplesCount(description.MultiSampleType);
38     }
39 }
40
41 RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples)
42 {
43     mRenderer = Renderer9::makeRenderer9(renderer);
44     mRenderTarget = NULL;
45
46     const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalFormat);
47     const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.renderFormat);
48
49     const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat);
50     GLuint supportedSamples = textureCaps.getNearestSamples(samples);
51
52     HRESULT result = D3DERR_INVALIDCALL;
53
54     if (width > 0 && height > 0)
55     {
56         IDirect3DDevice9 *device = mRenderer->getDevice();
57
58         bool requiresInitialization = false;
59
60         const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
61         if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
62         {
63             result = device->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat,
64                                                        gl_d3d9::GetMultisampleType(supportedSamples),
65                                                        0, FALSE, &mRenderTarget, NULL);
66         }
67         else
68         {
69             requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL);
70             result = device->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat,
71                                                 gl_d3d9::GetMultisampleType(supportedSamples),
72                                                 0, FALSE, &mRenderTarget, NULL);
73         }
74
75         if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
76         {
77             gl::error(GL_OUT_OF_MEMORY);
78
79             return;
80         }
81
82         ASSERT(SUCCEEDED(result));
83
84         if (requiresInitialization)
85         {
86             // This format requires that the data be initialized before the render target can be used
87             // Unfortunately this requires a Get call on the d3d device but it is far better than having
88             // to mark the render target as lockable and copy data to the gpu.
89             IDirect3DSurface9 *prevRenderTarget = NULL;
90             device->GetRenderTarget(0, &prevRenderTarget);
91             device->SetRenderTarget(0, mRenderTarget);
92             device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0);
93             device->SetRenderTarget(0, prevRenderTarget);
94         }
95     }
96
97     mWidth = width;
98     mHeight = height;
99     mDepth = 1;
100     mInternalFormat = internalFormat;
101     mSamples = supportedSamples;
102     mActualFormat = d3dFormatInfo.internalFormat;
103 }
104
105 RenderTarget9::~RenderTarget9()
106 {
107     SafeRelease(mRenderTarget);
108 }
109
110 RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target)
111 {
112     ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget9*, target));
113     return static_cast<rx::RenderTarget9*>(target);
114 }
115
116 void RenderTarget9::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
117 {
118     // Currently a no-op
119 }
120
121 IDirect3DSurface9 *RenderTarget9::getSurface()
122 {
123     // Caller is responsible for releasing the returned surface reference.
124     // TODO: remove the AddRef to match RenderTarget11
125     if (mRenderTarget)
126     {
127         mRenderTarget->AddRef();
128     }
129
130     return mRenderTarget;
131 }
132
133 }