void CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { AutoRemoveTexture autoRemove(this); if (mBuffer && (mBuffer->IsImmutable() || mBuffer->GetSize() != aSize)) { autoRemove.mTexture = mBuffer; mBuffer = nullptr; } bool bufferCreated = false; if (!mBuffer) { bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE); gfxContentType contentType = isOpaque ? gfxContentType::COLOR : gfxContentType::COLOR_ALPHA; gfxImageFormat format = gfxPlatform::GetPlatform()->OptimalFormatForContent(contentType); TextureFlags flags = TextureFlags::DEFAULT; if (mTextureFlags & TextureFlags::NEEDS_Y_FLIP) { flags |= TextureFlags::NEEDS_Y_FLIP; } gfx::SurfaceFormat surfaceFormat = gfx::ImageFormatToSurfaceFormat(format); mBuffer = CreateTextureClientForCanvas(surfaceFormat, aSize, flags, aLayer); MOZ_ASSERT(mBuffer->CanExposeDrawTarget()); mBuffer->AllocateForSurface(aSize); bufferCreated = true; } if (!mBuffer->Lock(OpenMode::OPEN_WRITE_ONLY)) { mBuffer = nullptr; return; } bool updated = false; { // Restrict drawTarget to a scope so that terminates before Unlock. RefPtr<DrawTarget> target = mBuffer->BorrowDrawTarget(); if (target) { aLayer->UpdateTarget(target); updated = true; } } mBuffer->Unlock(); if (bufferCreated && !AddTextureClient(mBuffer)) { mBuffer = nullptr; return; } if (updated) { GetForwarder()->UpdatedTexture(this, mBuffer, nullptr); GetForwarder()->UseTexture(this, mBuffer); } }
void CanvasClientSharedSurface::Updated() { if (!mNewFront) { return; } auto forwarder = GetForwarder(); #ifndef MOZ_WIDGET_GONK if (mFront) { if (mFront->GetFlags() & TextureFlags::RECYCLE) { mFront->WaitForCompositorRecycle(); } } #else // AutoRemoveTexture does the followings. // - Ensure to deliver FenceHandle from TextureHost to TextureClient, before // next TextureClient usage. // - Control TextureClient's recycling timing. // - Call RemoveTexture() after newFront's UseTextures() call. // It could improve performance of Host side's EGL handling on gonk AutoRemoveTexture autoRemove(this); if (mFront && mFront != mNewFront) { autoRemove.mTexture = mFront; } #endif mFront = mNewFront; mNewFront = nullptr; // Add the new TexClient. MOZ_ALWAYS_TRUE( AddTextureClient(mFront) ); AutoTArray<CompositableForwarder::TimedTextureClient,1> textures; CompositableForwarder::TimedTextureClient* t = textures.AppendElement(); t->mTextureClient = mFront; t->mPictureRect = nsIntRect(nsIntPoint(0, 0), mFront->GetSize()); t->mFrameID = mFrameID; // XXX TODO - This reference to VRManagerChild will be moved with the // implementation of the WebVR 1.0 API, which will enable // the inputFrameID to be passed through Javascript with // the new VRDisplay API. t->mInputFrameID = VRManagerChild::Get()->GetInputFrameID(); forwarder->UseTextures(this, textures); }
void CanvasClientSharedSurface::Updated() { if (!mNewFront) { return; } auto forwarder = GetForwarder(); #ifndef MOZ_WIDGET_GONK if (mFront) { if (mFront->GetFlags() & TextureFlags::RECYCLE) { mFront->WaitForCompositorRecycle(); } } #else // AutoRemoveTexture does the followings. // - Ensure to deliver FenceHandle from TextureHost to TextureClient, before // next TextureClient usage. // - Control TextureClient's recycling timing. // - Call RemoveTexture() after newFront's UseTextures() call. // It could improve performance of Host side's EGL handling on gonk AutoRemoveTexture autoRemove(this); if (mFront && mFront != mNewFront) { autoRemove.mTexture = mFront; } #endif mFront = mNewFront; mNewFront = nullptr; // Add the new TexClient. MOZ_ALWAYS_TRUE( AddTextureClient(mFront) ); nsAutoTArray<CompositableForwarder::TimedTextureClient,1> textures; CompositableForwarder::TimedTextureClient* t = textures.AppendElement(); t->mTextureClient = mFront; t->mPictureRect = nsIntRect(nsIntPoint(0, 0), mFront->GetSize()); t->mFrameID = mFrameID; forwarder->UseTextures(this, textures); }
void CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { AutoRemoveTexture autoRemove(this); if (mBuffer && (mBuffer->IsImmutable() || mBuffer->GetSize() != aSize)) { autoRemove.mTexture = mBuffer; mBuffer = nullptr; } bool bufferCreated = false; if (!mBuffer) { bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE); gfxContentType contentType = isOpaque ? gfxContentType::COLOR : gfxContentType::COLOR_ALPHA; gfx::SurfaceFormat surfaceFormat = gfxPlatform::GetPlatform()->Optimal2DFormatForContent(contentType); TextureFlags flags = TextureFlags::DEFAULT; if (mTextureFlags & TextureFlags::ORIGIN_BOTTOM_LEFT) { flags |= TextureFlags::ORIGIN_BOTTOM_LEFT; } mBuffer = CreateTextureClientForCanvas(surfaceFormat, aSize, flags, aLayer); if (!mBuffer) { NS_WARNING("Failed to allocate the TextureClient"); return; } MOZ_ASSERT(mBuffer->CanExposeDrawTarget()); bufferCreated = true; } bool updated = false; { TextureClientAutoLock autoLock(mBuffer, OpenMode::OPEN_WRITE_ONLY); if (!autoLock.Succeeded()) { mBuffer = nullptr; return; } RefPtr<DrawTarget> target = mBuffer->BorrowDrawTarget(); if (target) { aLayer->UpdateTarget(target); updated = true; } } if (bufferCreated && !AddTextureClient(mBuffer)) { mBuffer = nullptr; return; } if (updated) { nsAutoTArray<CompositableForwarder::TimedTextureClient,1> textures; CompositableForwarder::TimedTextureClient* t = textures.AppendElement(); t->mTextureClient = mBuffer; t->mPictureRect = nsIntRect(nsIntPoint(0, 0), mBuffer->GetSize()); t->mFrameID = mFrameID; GetForwarder()->UseTextures(this, textures); mBuffer->SyncWithObject(GetForwarder()->GetSyncObject()); } }
NS_IMETHODIMP IDBDatabase::CreateObjectStore(const nsAString& aName, const jsval& aOptions, JSContext* aCx, nsIIDBObjectStore** _retval) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); IDBTransaction* transaction = AsyncConnectionHelper::GetCurrentTransaction(); if (!transaction || transaction->Mode() != nsIIDBTransaction::VERSION_CHANGE) { return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR; } DatabaseInfo* databaseInfo = transaction->DBInfo(); mozilla::dom::IDBObjectStoreParameters params; nsString keyPath; keyPath.SetIsVoid(true); nsTArray<nsString> keyPathArray; if (!JSVAL_IS_VOID(aOptions) && !JSVAL_IS_NULL(aOptions)) { nsresult rv = params.Init(aCx, &aOptions); NS_ENSURE_SUCCESS(rv, rv); // Get keyPath jsval val = params.keyPath; if (!JSVAL_IS_VOID(val) && !JSVAL_IS_NULL(val)) { if (!JSVAL_IS_PRIMITIVE(val) && JS_IsArrayObject(aCx, JSVAL_TO_OBJECT(val))) { JSObject* obj = JSVAL_TO_OBJECT(val); jsuint length; if (!JS_GetArrayLength(aCx, obj, &length)) { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } if (!length) { return NS_ERROR_DOM_SYNTAX_ERR; } keyPathArray.SetCapacity(length); for (jsuint index = 0; index < length; index++) { jsval val; JSString* jsstr; nsDependentJSString str; if (!JS_GetElement(aCx, obj, index, &val) || !(jsstr = JS_ValueToString(aCx, val)) || !str.init(aCx, jsstr)) { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } if (!IDBObjectStore::IsValidKeyPath(aCx, str)) { return NS_ERROR_DOM_SYNTAX_ERR; } keyPathArray.AppendElement(str); } NS_ASSERTION(!keyPathArray.IsEmpty(), "This shouldn't have happened!"); } else { JSString* jsstr; nsDependentJSString str; if (!(jsstr = JS_ValueToString(aCx, val)) || !str.init(aCx, jsstr)) { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } if (!IDBObjectStore::IsValidKeyPath(aCx, str)) { return NS_ERROR_DOM_SYNTAX_ERR; } keyPath = str; } } } if (databaseInfo->ContainsStoreName(aName)) { return NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR; } if (params.autoIncrement && ((!keyPath.IsVoid() && keyPath.IsEmpty()) || !keyPathArray.IsEmpty())) { return NS_ERROR_DOM_INVALID_ACCESS_ERR; } nsRefPtr<ObjectStoreInfo> newInfo(new ObjectStoreInfo()); newInfo->name = aName; newInfo->id = databaseInfo->nextObjectStoreId++; newInfo->keyPath = keyPath; newInfo->keyPathArray = keyPathArray; newInfo->nextAutoIncrementId = params.autoIncrement ? 1 : 0; newInfo->comittedAutoIncrementId = newInfo->nextAutoIncrementId; if (!databaseInfo->PutObjectStore(newInfo)) { NS_WARNING("Put failed!"); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } // Don't leave this in the hash if we fail below! AutoRemoveObjectStore autoRemove(databaseInfo, aName); nsRefPtr<IDBObjectStore> objectStore = transaction->GetOrCreateObjectStore(aName, newInfo); NS_ENSURE_TRUE(objectStore, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); nsRefPtr<CreateObjectStoreHelper> helper = new CreateObjectStoreHelper(transaction, objectStore); nsresult rv = helper->DispatchToTransactionPool(); NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); autoRemove.forget(); objectStore.forget(_retval); return NS_OK; }