[guilib] fix labelcontrols with auto width always being marked as dirty if they speci...
[vuplus_xbmc] / xbmc / guilib / TextureDX.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "TextureDX.h"
22 #include "windowing/WindowingFactory.h"
23 #include "utils/log.h"
24
25 #ifdef HAS_DX
26
27 /************************************************************************/
28 /*    CDXTexture                                                       */
29 /************************************************************************/
30 CDXTexture::CDXTexture(unsigned int width, unsigned int height, unsigned int format)
31 : CBaseTexture(width, height, format)
32 {
33 }
34
35 CDXTexture::~CDXTexture()
36 {
37   DestroyTextureObject();
38 }
39
40 void CDXTexture::CreateTextureObject()
41 {
42   D3DFORMAT format = D3DFMT_UNKNOWN;
43
44   switch (m_format)
45   {
46   case XB_FMT_DXT1:
47     format = D3DFMT_DXT1;
48     break;
49   case XB_FMT_DXT3:
50     format = D3DFMT_DXT3;
51     break;
52   case XB_FMT_DXT5:
53   case XB_FMT_DXT5_YCoCg:
54     format = D3DFMT_DXT5;
55     break;
56   case XB_FMT_RGB8:
57   case XB_FMT_A8R8G8B8:
58     format = D3DFMT_A8R8G8B8;
59     break;
60   case XB_FMT_A8:
61     format = D3DFMT_A8;
62     break;
63   default:
64     return;
65   }
66
67   m_texture.Create(m_textureWidth, m_textureHeight, 1, g_Windowing.DefaultD3DUsage(), format, g_Windowing.DefaultD3DPool());
68 }
69
70 void CDXTexture::DestroyTextureObject()
71 {
72   m_texture.Release();
73 }
74
75 void CDXTexture::LoadToGPU()
76 {
77   if (!m_pixels)
78   {
79     // nothing to load - probably same image (no change)
80     return;
81   }
82
83   if (m_texture.Get() == NULL)
84   {
85     CreateTextureObject();
86     if (m_texture.Get() == NULL)
87     {
88       CLog::Log(LOGDEBUG, "CDXTexture::CDXTexture: Error creating new texture for size %d x %d", m_textureWidth, m_textureHeight);
89       return;
90     }
91   }
92
93   D3DLOCKED_RECT lr;
94   if (m_texture.LockRect( 0, &lr, NULL, D3DLOCK_DISCARD ))
95   {
96     unsigned char *dst = (unsigned char *)lr.pBits;
97     unsigned char *src = m_pixels;
98     unsigned int dstPitch = lr.Pitch;
99     unsigned int srcPitch = GetPitch();
100     unsigned int minPitch = std::min(srcPitch, dstPitch);
101
102     unsigned int rows = GetRows();
103     if (m_format == XB_FMT_RGB8)
104     {
105       for (unsigned int y = 0; y < rows; y++)
106       {
107         unsigned char *dst2 = dst;
108         unsigned char *src2 = src;
109         for (unsigned int x = 0; x < srcPitch / 3; x++, dst2 += 4, src2 += 3)
110         {
111           dst2[0] = src2[2];
112           dst2[1] = src2[1];
113           dst2[2] = src2[0];
114           dst2[3] = 0xff;
115         }
116         src += srcPitch;
117         dst += dstPitch;
118       }
119     }
120     else if (srcPitch == dstPitch)
121     {
122       memcpy(dst, src, srcPitch * rows);
123     }
124     else
125     {
126       for (unsigned int y = 0; y < rows; y++)
127       {
128         memcpy(dst, src, minPitch);
129         src += srcPitch;
130         dst += dstPitch;
131       }
132     }
133   }
134   else
135   {
136     CLog::Log(LOGERROR, __FUNCTION__" - failed to lock texture");
137   }
138   m_texture.UnlockRect(0);
139
140   delete [] m_pixels;
141   m_pixels = NULL;
142
143   m_loadedToGPU = true;
144 }
145
146 void CDXTexture::BindToUnit(unsigned int unit)
147 {
148   LPDIRECT3DDEVICE9 p3DDevice = g_Windowing.Get3DDevice();
149   p3DDevice->SetTexture( unit, m_texture.Get() );
150   p3DDevice->SetSamplerState( unit, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
151   p3DDevice->SetSamplerState( unit, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
152   p3DDevice->SetSamplerState( unit, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
153   p3DDevice->SetSamplerState( unit, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
154 }
155
156 #endif