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