void AndroidPixelRef::globalRef(void* localref) { if (fWrappedPixelRef) { // delegate java obj management to the wrapped ref fWrappedPixelRef->globalRef(localref); // Note: we only ref and unref the wrapped AndroidPixelRef so that // bitmap->pixelRef()->globalRef() and globalUnref() can be used in a pair, even if // the bitmap has its underlying AndroidPixelRef swapped out/wrapped return; } if (fOnJavaHeap && sk_atomic_inc(&fGlobalRefCnt) == 0) { JNIEnv *env = vm2env(fVM); // If JNI ref was passed, it is always used if (localref) fStorageObj = (jbyteArray) localref; if (fStorageObj == NULL) { SkDebugf("No valid local ref to create a JNI global ref\n"); sk_throw(); } if (fHasGlobalRef) { // This should never happen SkDebugf("Already holding a JNI global ref"); sk_throw(); } fStorageObj = (jbyteArray) env->NewGlobalRef(fStorageObj); // TODO: Check for failure here fHasGlobalRef = true; } ref(); }
static SkFaceRec* ref_ft_face(uint32_t fontID) { SkFaceRec* rec = gFaceRecHead; while (rec) { if (rec->fFontID == fontID) { SkASSERT(rec->fFace); rec->fRefCnt += 1; return rec; } rec = rec->fNext; } SkStream* strm = SkFontHost::OpenStream(fontID); if (NULL == strm) { SkDEBUGF(("SkFontHost::OpenStream failed opening %x\n", fontID)); sk_throw(); return 0; } // this passes ownership of strm to the rec rec = SkNEW_ARGS(SkFaceRec, (strm, fontID)); FT_Open_Args args; memset(&args, 0, sizeof(args)); const void* memoryBase = strm->getMemoryBase(); if (NULL != memoryBase) { //printf("mmap(%s)\n", keyString.c_str()); args.flags = FT_OPEN_MEMORY; args.memory_base = (const FT_Byte*)memoryBase; args.memory_size = strm->getLength(); } else { //printf("fopen(%s)\n", keyString.c_str()); args.flags = FT_OPEN_STREAM; args.stream = &rec->fFTStream; } FT_Error err = FT_Open_Face(gFTLibrary, &args, 0, &rec->fFace); if (err) { // bad filename, try the default font fprintf(stderr, "ERROR: unable to open font '%x'\n", fontID); SkDELETE(rec); sk_throw(); return 0; } else { SkASSERT(rec->fFace); //fprintf(stderr, "Opened font '%s'\n", filename.c_str()); rec->fNext = gFaceRecHead; gFaceRecHead = rec; rec->fRefCnt = 1; return rec; } }
void init_skin_anim(const char path[], SkAnimator* anim) { SkASSERT(path && anim); SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); if (!stream.get()) { SkDEBUGF(("init_skin_anim: loading skin failed <%s>\n", path)); sk_throw(); } if (!anim->decodeStream(stream)) { SkDEBUGF(("init_skin_anim: decoding skin failed <%s>\n", path)); sk_throw(); } }
SkFlattenable* SkFlattenableReadBuffer::readFlattenable() { SkFlattenable::Factory factory = NULL; if (fFactoryCount > 0) { uint32_t index = this->readU32(); if (index > 0) { index -= 1; SkASSERT(index < (unsigned)fFactoryCount); factory = fFactoryArray[index]; // if we recorded an index, but failed to get a factory, we need // to skip the flattened data in the buffer if (NULL == factory) { uint32_t size = this->readU32(); this->skip(size); // fall through and return NULL for the object } } } else { factory = (SkFlattenable::Factory)readFunctionPtr(); } SkFlattenable* obj = NULL; if (factory) { uint32_t sizeRecorded = this->readU32(); uint32_t offset = this->offset(); obj = (*factory)(*this); // check that we read the amount we expected uint32_t sizeRead = this->offset() - offset; if (sizeRecorded != sizeRead) { // we could try to fix up the offset... sk_throw(); } } return obj; }
JavaMemoryUsageReporter::JavaMemoryUsageReporter(JNIEnv* env) : fTotalSize(0) { if (env->GetJavaVM(&fVM) != JNI_OK) { SkDebugf("------ [%p] env->GetJavaVM failed\n", env); sk_throw(); } }
void* sk_malloc_flags(size_t size, unsigned flags) { void* p; #if defined(ANDROID) // Android doesn't have std::set_new_handler. p = malloc(size); #else if (!(flags & SK_MALLOC_THROW)) { #if defined(OS_MACOSX) && !defined(OS_IOS) p = base::UncheckedMalloc(size); #else SkAutoMutexAcquire lock(gSkNewHandlerMutex); std::new_handler old_handler = std::set_new_handler(NULL); p = malloc(size); std::set_new_handler(old_handler); #endif } else { p = malloc(size); } #endif if (p == NULL) { if (flags & SK_MALLOC_THROW) { sk_throw(); } } return p; }
SkFlattenable* SkFlattenableReadBuffer::readFlattenable() { SkFlattenable::Factory factory = NULL; if (fFactoryCount > 0) { int32_t index = this->readU32(); if (0 == index) { return NULL; // writer failed to give us the flattenable } index = -index; // we stored the negative of the index index -= 1; // we stored the index-base-1 SkASSERT(index < fFactoryCount); factory = fFactoryArray[index]; } else if (fFactoryTDArray) { const int32_t* peek = (const int32_t*)this->peek(); if (*peek <= 0) { int32_t index = this->readU32(); if (0 == index) { return NULL; // writer failed to give us the flattenable } index = -index; // we stored the negative of the index index -= 1; // we stored the index-base-1 factory = (*fFactoryTDArray)[index]; } else { const char* name = this->readString(); factory = SkFlattenable::NameToFactory(name); if (factory) { SkASSERT(fFactoryTDArray->find(factory) < 0); *fFactoryTDArray->append() = factory; } else { // SkDebugf("can't find factory for [%s]\n", name); } // if we didn't find a factory, that's our failure, not the writer's, // so we fall through, so we can skip the sizeRecorded data. } } else { factory = (SkFlattenable::Factory)readFunctionPtr(); if (NULL == factory) { return NULL; // writer failed to give us the flattenable } } // if we get here, factory may still be null, but if that is the case, the // failure was ours, not the writer. SkFlattenable* obj = NULL; uint32_t sizeRecorded = this->readU32(); if (factory) { uint32_t offset = this->offset(); obj = (*factory)(*this); // check that we read the amount we expected uint32_t sizeRead = this->offset() - offset; if (sizeRecorded != sizeRead) { // we could try to fix up the offset... sk_throw(); } } else { // we must skip the remaining data this->skip(sizeRecorded); } return obj; }
SkTypeface* SkFontHost::Deserialize(SkStream* stream) { #if 0 load_system_fonts(); int style = stream->readU8(); int len = stream->readPackedUInt(); if (len > 0) { SkString str; str.resize(len); stream->read(str.writable_str(), len); const FontInitRec* rec = gSystemFonts; for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { if (strcmp(rec[i].fFileName, str.c_str()) == 0) { // backup until we hit the fNames for (int j = i; j >= 0; --j) { if (rec[j].fNames != NULL) { return SkFontHost::CreateTypeface(NULL, rec[j].fNames[0], NULL, 0, (SkTypeface::Style)style); } } } } } return SkFontHost::CreateTypeface(NULL, NULL, NULL, 0, (SkTypeface::Style)style); #endif sk_throw(); return NULL; }
JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env, bool reportSizeToVM) : fReportSizeToVM(reportSizeToVM) { if (env->GetJavaVM(&fVM) != JNI_OK) { SkDebugf("------ [%p] env->GetJavaVM failed\n", env); sk_throw(); } }
static void load_system_fonts() { // check if we've already be called if (NULL != gDefaultNormal) { return; } SkString baseDirectory(SK_FONT_FILE_PREFIX); unsigned int count = 0; load_directory_fonts(baseDirectory, &count); if (0 == count) { SkNEW(EmptyTypeface); } // do this after all fonts are loaded. This is our default font, and it // acts as a sentinel so we only execute load_system_fonts() once static const char* gDefaultNames[] = { #if defined(__LB_SHELL__) "Droid Sans", // our preferred default #endif "Arial", "Verdana", "Times New Roman", NULL }; const char** names = gDefaultNames; while (*names) { SkTypeface* tf = find_typeface(*names++, SkTypeface::kNormal); if (tf) { gDefaultNormal = tf; break; } } // check if we found *something* if (NULL == gDefaultNormal) { if (NULL == gFamilyHead) { sk_throw(); } for (int i = 0; i < 4; i++) { if ((gDefaultNormal = gFamilyHead->fFaces[i]) != NULL) { break; } } } if (NULL == gDefaultNormal) { sk_throw(); } gFallBackTypeface = gDefaultNormal; gDefaultFamily = find_family(gDefaultNormal); }
JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env) : fStorageObj(NULL), fAllocCount(0) { if (env->GetJavaVM(&fVM) != JNI_OK) { SkDebugf("------ [%p] env->GetJavaVM failed\n", env); sk_throw(); } }
void* sk_malloc_flags(size_t size, unsigned flags) { void* p = MALLOC(size | ALLOC_NO_ZMEM); if (p == NULL) { if (flags & SK_MALLOC_THROW) { sk_throw(); } } return p; }
void init_skin_anim(const char path[], SkAnimator* anim) { SkASSERT(path && anim); SkFILEStream stream(path); if (!stream.isValid()) { SkDEBUGF(("init_skin_anim: loading skin failed <%s>\n", path)); sk_throw(); } if (!anim->decodeStream(&stream)) { SkDEBUGF(("init_skin_anim: decoding skin failed <%s>\n", path)); sk_throw(); } }
SkLocalMatrixShader::SkLocalMatrixShader(SkReadBuffer& buffer) : INHERITED(buffer) { if (buffer.isVersionLT(SkReadBuffer::kSimplifyLocalMatrix_Version)) { buffer.readMatrix(&(INHERITED::fLocalMatrix)); } fProxyShader.reset(buffer.readShader()); if (NULL == fProxyShader.get()) { sk_throw(); } }
static void sk_new_handler() { if (SkGraphics::SetFontCacheUsed(0)) return; if (gPrevNewHandler) gPrevNewHandler(); else sk_throw(); }
SkImageInfo GrSurface::info(SkAlphaType alphaType) const { SkColorType colorType; SkColorProfileType profileType; if (!GrPixelConfig2ColorAndProfileType(this->config(), &colorType, &profileType)) { sk_throw(); } return SkImageInfo::Make(this->width(), this->height(), colorType, alphaType, profileType); }
SkImageInfo GrSurface::info() const { SkImageInfo info; if (!GrPixelConfig2ColorType(this->config(), &info.fColorType)) { sk_throw(); } info.fWidth = this->width(); info.fHeight = this->height(); info.fAlphaType = kPremul_SkAlphaType; return info; }
/** Allocate the specified buffer for pixels. The memory is freed when the last owner of this pixelref is gone. Our caller has already informed the VM of our allocation. */ AndroidPixelRef(JNIEnv* env, void* storage, size_t size, SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable) { SkASSERT(storage); SkASSERT(env); if (env->GetJavaVM(&fVM) != JNI_OK) { SkDebugf("------ [%p] env->GetJavaVM failed\n", env); sk_throw(); } }
void* sk_realloc_throw(void* addr, size_t size) { void* p = REALLOC(addr, size | ALLOC_NO_ZMEM); if (size == 0) { return p; } if (p == NULL) { sk_throw(); } return p; }
static JNIEnv* vm2env(JavaVM* vm) { JNIEnv* env = NULL; if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK || NULL == env) { SkDebugf("------- [%p] vm->GetEnv() failed\n", vm); sk_throw(); } return env; }
void* sk_realloc_throw(void* addr, size_t size) { void* p = realloc(addr, size); if (size == 0) { return p; } if (p == NULL) { sk_throw(); } return p; }
void* sk_realloc_throw(void* addr, size_t size) { gSkMemStats.updateBytes(size - gSkMemStats.getBlockSize(addr)); void* p = realloc(addr, size); if (size == 0) { return p; } if (p == NULL) { sk_throw(); } return p; }
AutoJavaIntArray::AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength) : fEnv(env), fArray(array), fPtr(NULL), fLen(0) { SkASSERT(env); if (array) { fLen = env->GetArrayLength(array); if (fLen < minLength) { sk_throw(); } fPtr = env->GetIntArrayElements(array, NULL); } }
static void ConvertTwoElemFloatArray( /* [out] */ ArrayOf<Float>* array, /* [in] */ SkScalar* src) { assert(array != NULL); if (array->GetLength() < 2) { sk_throw(); } (*array)[0] = SkScalarToFloat(src[0]); (*array)[1] = SkScalarToFloat(src[1]); }
/* * Modulo internal errors, this should always succeed *if* the matrix is downscaling * (in this case, we have the inverse, so it succeeds if fInvMatrix is upscaling) */ bool SkDefaultBitmapControllerState::processMediumRequest(const SkBitmapProvider& provider) { SkASSERT(fQuality <= kMedium_SkFilterQuality); if (fQuality != kMedium_SkFilterQuality) { return false; } // Our default return state is to downgrade the request to Low, w/ or w/o setting fBitmap // to a valid bitmap. fQuality = kLow_SkFilterQuality; SkSize invScaleSize; if (!fInvMatrix.decomposeScale(&invScaleSize, nullptr)) { return false; } // Use the largest (non-inverse) scale, to ensure anisotropic consistency. SkASSERT(invScaleSize.width() >= 0 && invScaleSize.height() >= 0); const SkScalar invScale = SkTMin(invScaleSize.width(), invScaleSize.height()); if (invScale > SK_Scalar1) { fCurrMip.reset(SkMipMapCache::FindAndRef(provider.makeCacheDesc())); if (nullptr == fCurrMip.get()) { SkBitmap orig; if (!provider.asBitmap(&orig)) { return false; } fCurrMip.reset(SkMipMapCache::AddAndRef(orig)); if (nullptr == fCurrMip.get()) { return false; } } // diagnostic for a crasher... if (nullptr == fCurrMip->data()) { sk_throw(); } SkScalar levelScale = SkScalarInvert(invScale); SkMipMap::Level level; if (fCurrMip->extractLevel(levelScale, &level)) { const SkSize& invScaleFixup = level.fScale; fInvMatrix.postScale(invScaleFixup.width(), invScaleFixup.height()); // todo: if we could wrap the fCurrMip in a pixelref, then we could just install // that here, and not need to explicitly track it ourselves. return fResultBitmap.installPixels(level.fPixmap); } else { // failed to extract, so release the mipmap fCurrMip.reset(nullptr); } } return false; }
AutoJavaShortArray::AutoJavaShortArray(JNIEnv* env, jshortArray array, int minLength, JNIAccess access) : fEnv(env), fArray(array), fPtr(NULL), fLen(0) { SkASSERT(env); if (array) { fLen = env->GetArrayLength(array); if (fLen < minLength) { sk_throw(); } fPtr = env->GetShortArrayElements(array, NULL); } fReleaseMode = (access == kRO_JNIAccess) ? JNI_ABORT : 0; }
void AndroidPixelRef::globalUnref() { if (fOnJavaHeap && sk_atomic_dec(&fGlobalRefCnt) == 1) { JNIEnv *env = vm2env(fVM); if (!fHasGlobalRef) { SkDebugf("We don't have a global ref!"); sk_throw(); } env->DeleteGlobalRef(fStorageObj); fStorageObj = NULL; fHasGlobalRef = false; } unref(); }
void AndroidPixelRef::globalRef(void* localref) { if (fOnJavaHeap && sk_atomic_inc(&fGlobalRefCnt) == 0) { JNIEnv *env = vm2env(fVM); // If JNI ref was passed, it is always used if (localref) fStorageObj = (jbyteArray) localref; if (fStorageObj == NULL) { SkDebugf("No valid local ref to create a JNI global ref\n"); sk_throw(); } if (fHasGlobalRef) { // This should never happen SkDebugf("Already holding a JNI global ref"); sk_throw(); } fStorageObj = (jbyteArray) env->NewGlobalRef(fStorageObj); // TODO: Check for failure here fHasGlobalRef = true; } ref(); }
SkPicture::SkPicture(SkStream* stream) : SkRefCnt() { if (stream->readU32() != PICTURE_VERSION) { sk_throw(); } fWidth = stream->readU32(); fHeight = stream->readU32(); fRecord = NULL; fPlayback = NULL; if (stream->readBool()) { fPlayback = SkNEW_ARGS(SkPicturePlayback, (stream)); } }
AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes, jbyteArray storageObj, SkColorTable* ctable) : SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)), fWrappedPixelRef(NULL) { SkASSERT(storage); SkASSERT(storageObj); SkASSERT(env); if (env->GetJavaVM(&fVM) != JNI_OK) { SkDebugf("------ [%p] env->GetJavaVM failed\n", env); sk_throw(); } fStorageObj = (jbyteArray) env->NewGlobalRef(storageObj); }