OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkGpuDevice.h" | 8 #include "SkGpuDevice.h" |
9 | 9 |
10 #include "effects/GrBicubicEffect.h" | 10 #include "effects/GrBicubicEffect.h" |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 static SkBitmap make_bitmap(GrContext* context, GrRenderTarget* renderTarget) { | 150 static SkBitmap make_bitmap(GrContext* context, GrRenderTarget* renderTarget) { |
151 bool isOpaque; | 151 bool isOpaque; |
152 SkBitmap::Config config = grConfig2skConfig(renderTarget->config(), &isOpaqu
e); | 152 SkBitmap::Config config = grConfig2skConfig(renderTarget->config(), &isOpaqu
e); |
153 | 153 |
154 SkBitmap bitmap; | 154 SkBitmap bitmap; |
155 bitmap.setConfig(config, renderTarget->width(), renderTarget->height(), 0, | 155 bitmap.setConfig(config, renderTarget->width(), renderTarget->height(), 0, |
156 isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); | 156 isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); |
157 return bitmap; | 157 return bitmap; |
158 } | 158 } |
159 | 159 |
160 /* | |
161 * Calling SkBitmapDevice with individual params asks it to allocate pixel memo
ry. | |
162 * We never want that, so we always need to call it with a bitmap argument | |
163 * (which says take my allocate (or lack thereof)). | |
164 * | |
165 * This is a REALLY good reason to finish the clean-up of SkBaseDevice, and hav
e | |
166 * SkGpuDevice inherit from that instead of SkBitmapDevice. | |
167 */ | |
168 static SkBitmap make_bitmap(SkBitmap::Config config, int width, int height, bool
isOpaque) { | |
169 SkBitmap bm; | |
170 bm.setConfig(config, width, height, isOpaque); | |
171 return bm; | |
172 } | |
173 | |
174 SkGpuDevice* SkGpuDevice::Create(GrSurface* surface) { | 160 SkGpuDevice* SkGpuDevice::Create(GrSurface* surface) { |
175 SkASSERT(NULL != surface); | 161 SkASSERT(NULL != surface); |
176 if (NULL == surface->asRenderTarget() || NULL == surface->getContext()) { | 162 if (NULL == surface->asRenderTarget() || NULL == surface->getContext()) { |
177 return NULL; | 163 return NULL; |
178 } | 164 } |
179 if (surface->asTexture()) { | 165 if (surface->asTexture()) { |
180 return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asTextur
e())); | 166 return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asTextur
e())); |
181 } else { | 167 } else { |
182 return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asRender
Target())); | 168 return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asRender
Target())); |
183 } | 169 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 surface = fRenderTarget; | 211 surface = fRenderTarget; |
226 } | 212 } |
227 | 213 |
228 SkImageInfo info; | 214 SkImageInfo info; |
229 surface->asImageInfo(&info); | 215 surface->asImageInfo(&info); |
230 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, surface, cached)); | 216 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, surface, cached)); |
231 | 217 |
232 this->setPixelRef(pr)->unref(); | 218 this->setPixelRef(pr)->unref(); |
233 } | 219 } |
234 | 220 |
| 221 SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo
, |
| 222 int sampleCount) { |
| 223 if (kUnknown_SkColorType == origInfo.colorType() || |
| 224 origInfo.width() < 0 || origInfo.height() < 0) { |
| 225 return NULL; |
| 226 } |
| 227 |
| 228 SkImageInfo info = origInfo; |
| 229 // TODO: perhas we can loosen this check now that colortype is more detailed |
| 230 // e.g. can we support both RGBA and BGRA here? |
| 231 if (kRGB_565_SkColorType == info.colorType()) { |
| 232 info.fAlphaType = kOpaque_SkAlphaType; // force this setting |
| 233 } else { |
| 234 info.fColorType = kPMColor_SkColorType; |
| 235 if (kOpaque_SkAlphaType != info.alphaType()) { |
| 236 info.fAlphaType = kPremul_SkAlphaType; // force this setting |
| 237 } |
| 238 } |
| 239 |
| 240 GrTextureDesc desc; |
| 241 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
| 242 desc.fWidth = info.width(); |
| 243 desc.fHeight = info.height(); |
| 244 desc.fConfig = SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType())
; |
| 245 desc.fSampleCnt = sampleCount; |
| 246 |
| 247 SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0
)); |
| 248 if (!texture.get()) { |
| 249 return NULL; |
| 250 } |
| 251 |
| 252 return SkNEW_ARGS(SkGpuDevice, (context, texture.get())); |
| 253 } |
| 254 |
| 255 #ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG |
| 256 static SkBitmap make_bitmap(SkBitmap::Config config, int width, int height) { |
| 257 SkBitmap bm; |
| 258 bm.setConfig(SkImageInfo::Make(width, height, |
| 259 SkBitmapConfigToColorType(config), |
| 260 kPremul_SkAlphaType)); |
| 261 return bm; |
| 262 } |
235 SkGpuDevice::SkGpuDevice(GrContext* context, | 263 SkGpuDevice::SkGpuDevice(GrContext* context, |
236 SkBitmap::Config config, | 264 SkBitmap::Config config, |
237 int width, | 265 int width, |
238 int height, | 266 int height, |
239 int sampleCount) | 267 int sampleCount) |
240 : SkBitmapDevice(make_bitmap(config, width, height, false /*isOpaque*/)) | 268 : SkBitmapDevice(make_bitmap(config, width, height)) |
241 { | 269 { |
242 fDrawProcs = NULL; | 270 fDrawProcs = NULL; |
243 | 271 |
244 fContext = context; | 272 fContext = context; |
245 fContext->ref(); | 273 fContext->ref(); |
246 | 274 |
247 #if SK_DISTANCEFIELD_FONTS | 275 #if SK_DISTANCEFIELD_FONTS |
248 fMainTextContext = SkNEW_ARGS(GrDistanceFieldTextContext, (fContext, fLeakyP
roperties)); | 276 fMainTextContext = SkNEW_ARGS(GrDistanceFieldTextContext, (fContext, fLeakyP
roperties)); |
249 fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProp
erties)); | 277 fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProp
erties)); |
250 #else | 278 #else |
251 fMainTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperti
es)); | 279 fMainTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperti
es)); |
252 fFallbackTextContext = NULL; | 280 fFallbackTextContext = NULL; |
253 #endif | 281 #endif |
254 | 282 |
255 fRenderTarget = NULL; | 283 fRenderTarget = NULL; |
256 fNeedClear = false; | 284 fNeedClear = false; |
257 | 285 |
258 if (config != SkBitmap::kRGB_565_Config) { | 286 if (config != SkBitmap::kRGB_565_Config) { |
259 config = SkBitmap::kARGB_8888_Config; | 287 config = SkBitmap::kARGB_8888_Config; |
260 } | 288 } |
261 | 289 |
262 GrTextureDesc desc; | 290 GrTextureDesc desc; |
263 desc.fFlags = kRenderTarget_GrTextureFlagBit; | 291 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
264 desc.fWidth = width; | 292 desc.fWidth = width; |
265 desc.fHeight = height; | 293 desc.fHeight = height; |
266 desc.fConfig = SkBitmapConfig2GrPixelConfig(config); | 294 desc.fConfig = SkBitmapConfig2GrPixelConfig(config); |
267 desc.fSampleCnt = sampleCount; | 295 desc.fSampleCnt = sampleCount; |
268 | 296 |
269 SkImageInfo info; | 297 SkImageInfo info; |
270 if (!GrPixelConfig2ColorType(desc.fConfig, &info.fColorType)) { | 298 if (!GrPixelConfig2ColorType(desc.fConfig, &info.fColorType)) { |
271 sk_throw(); | 299 sk_throw(); |
272 } | 300 } |
273 info.fWidth = width; | 301 info.fWidth = width; |
274 info.fHeight = height; | 302 info.fHeight = height; |
275 info.fAlphaType = kPremul_SkAlphaType; | 303 info.fAlphaType = kPremul_SkAlphaType; |
276 | 304 |
277 SkAutoTUnref<GrTexture> texture(fContext->createUncachedTexture(desc, NULL,
0)); | 305 SkAutoTUnref<GrTexture> texture(fContext->createUncachedTexture(desc, NULL,
0)); |
278 | 306 |
279 if (NULL != texture) { | 307 if (NULL != texture) { |
280 fRenderTarget = texture->asRenderTarget(); | 308 fRenderTarget = texture->asRenderTarget(); |
281 fRenderTarget->ref(); | 309 fRenderTarget->ref(); |
282 | 310 |
283 SkASSERT(NULL != fRenderTarget); | 311 SkASSERT(NULL != fRenderTarget); |
284 | 312 |
285 // wrap the bitmap with a pixelref to expose our texture | 313 // wrap the bitmap with a pixelref to expose our texture |
286 SkGrPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, texture)); | 314 SkGrPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, texture)); |
287 this->setPixelRef(pr)->unref(); | 315 this->setPixelRef(pr)->unref(); |
288 } else { | 316 } else { |
289 GrPrintf("--- failed to create gpu-offscreen [%d %d]\n", | 317 GrPrintf("--- failed to create gpu-offscreen [%d %d]\n", |
290 width, height); | 318 width, height); |
291 SkASSERT(false); | 319 SkASSERT(false); |
292 } | 320 } |
293 } | 321 } |
| 322 #endif |
294 | 323 |
295 SkGpuDevice::~SkGpuDevice() { | 324 SkGpuDevice::~SkGpuDevice() { |
296 if (fDrawProcs) { | 325 if (fDrawProcs) { |
297 delete fDrawProcs; | 326 delete fDrawProcs; |
298 } | 327 } |
299 | 328 |
300 delete fMainTextContext; | 329 delete fMainTextContext; |
301 delete fFallbackTextContext; | 330 delete fFallbackTextContext; |
302 | 331 |
303 // The GrContext takes a ref on the target. We don't want to cause the rende
r | 332 // The GrContext takes a ref on the target. We don't want to cause the rende
r |
(...skipping 1570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1874 return false; | 1903 return false; |
1875 } | 1904 } |
1876 | 1905 |
1877 void SkGpuDevice::flush() { | 1906 void SkGpuDevice::flush() { |
1878 DO_DEFERRED_CLEAR(); | 1907 DO_DEFERRED_CLEAR(); |
1879 fContext->resolveRenderTarget(fRenderTarget); | 1908 fContext->resolveRenderTarget(fRenderTarget); |
1880 } | 1909 } |
1881 | 1910 |
1882 /////////////////////////////////////////////////////////////////////////////// | 1911 /////////////////////////////////////////////////////////////////////////////// |
1883 | 1912 |
1884 SkBaseDevice* SkGpuDevice::onCreateCompatibleDevice(SkBitmap::Config config, | 1913 SkBaseDevice* SkGpuDevice::onCreateDevice(const SkImageInfo& info, Usage usage)
{ |
1885 int width, int height, | |
1886 bool isOpaque, | |
1887 Usage usage) { | |
1888 GrTextureDesc desc; | 1914 GrTextureDesc desc; |
1889 desc.fConfig = fRenderTarget->config(); | 1915 desc.fConfig = fRenderTarget->config(); |
1890 desc.fFlags = kRenderTarget_GrTextureFlagBit; | 1916 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
1891 desc.fWidth = width; | 1917 desc.fWidth = info.width(); |
1892 desc.fHeight = height; | 1918 desc.fHeight = info.height(); |
1893 desc.fSampleCnt = fRenderTarget->numSamples(); | 1919 desc.fSampleCnt = fRenderTarget->numSamples(); |
1894 | 1920 |
1895 SkAutoTUnref<GrTexture> texture; | 1921 SkAutoTUnref<GrTexture> texture; |
1896 // Skia's convention is to only clear a device if it is non-opaque. | 1922 // Skia's convention is to only clear a device if it is non-opaque. |
1897 bool needClear = !isOpaque; | 1923 bool needClear = !info.isOpaque(); |
1898 | 1924 |
1899 #if CACHE_COMPATIBLE_DEVICE_TEXTURES | 1925 #if CACHE_COMPATIBLE_DEVICE_TEXTURES |
1900 // layers are never draw in repeat modes, so we can request an approx | 1926 // layers are never draw in repeat modes, so we can request an approx |
1901 // match and ignore any padding. | 1927 // match and ignore any padding. |
1902 const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == usage) ? | 1928 const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == usage) ? |
1903 GrContext::kApprox_ScratchTexMat
ch : | 1929 GrContext::kApprox_ScratchTexMat
ch : |
1904 GrContext::kExact_ScratchTexMatc
h; | 1930 GrContext::kExact_ScratchTexMatc
h; |
1905 texture.reset(fContext->lockAndRefScratchTexture(desc, match)); | 1931 texture.reset(fContext->lockAndRefScratchTexture(desc, match)); |
1906 #else | 1932 #else |
1907 texture.reset(fContext->createUncachedTexture(desc, NULL, 0)); | 1933 texture.reset(fContext->createUncachedTexture(desc, NULL, 0)); |
1908 #endif | 1934 #endif |
1909 if (NULL != texture.get()) { | 1935 if (NULL != texture.get()) { |
1910 return SkNEW_ARGS(SkGpuDevice,(fContext, texture, needClear)); | 1936 return SkNEW_ARGS(SkGpuDevice,(fContext, texture, needClear)); |
1911 } else { | 1937 } else { |
1912 GrPrintf("---- failed to create compatible device texture [%d %d]\n", wi
dth, height); | 1938 GrPrintf("---- failed to create compatible device texture [%d %d]\n", |
| 1939 info.width(), info.height()); |
1913 return NULL; | 1940 return NULL; |
1914 } | 1941 } |
1915 } | 1942 } |
1916 | 1943 |
1917 SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info) { | 1944 SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info) { |
1918 return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples(
)); | 1945 return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples(
)); |
1919 } | 1946 } |
1920 | 1947 |
1921 SkGpuDevice::SkGpuDevice(GrContext* context, | 1948 SkGpuDevice::SkGpuDevice(GrContext* context, |
1922 GrTexture* texture, | 1949 GrTexture* texture, |
1923 bool needClear) | 1950 bool needClear) |
1924 : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) { | 1951 : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) { |
1925 | 1952 |
1926 SkASSERT(texture && texture->asRenderTarget()); | 1953 SkASSERT(texture && texture->asRenderTarget()); |
1927 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture | 1954 // This constructor is called from onCreateDevice. It has locked the RT in t
he texture |
1928 // cache. We pass true for the third argument so that it will get unlocked. | 1955 // cache. We pass true for the third argument so that it will get unlocked. |
1929 this->initFromRenderTarget(context, texture->asRenderTarget(), true); | 1956 this->initFromRenderTarget(context, texture->asRenderTarget(), true); |
1930 fNeedClear = needClear; | 1957 fNeedClear = needClear; |
1931 } | 1958 } |
OLD | NEW |