| 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 |