/** * GetEncodedData() runs as a state machine, starting with mState set to * GET_METADDATA, the procedure should be as follow: * * While non-stop * If mState is GET_METADDATA * Get the meta data from audio/video encoder * If a meta data is generated * Get meta data from audio/video encoder * Set mState to ENCODE_TRACK * Return the final container data * * If mState is ENCODE_TRACK * Get encoded track data from audio/video encoder * If a packet of track data is generated * Insert encoded track data into the container stream of writer * If the final container data is copied to aOutput * Return the copy of final container data * If this is the last packet of input stream * Set mState to ENCODE_DONE * * If mState is ENCODE_DONE or ENCODE_ERROR * Stop the loop */ void MediaEncoder::GetEncodedData(nsTArray<nsTArray<uint8_t> >* aOutputBufs, nsAString& aMIMEType) { MOZ_ASSERT(!NS_IsMainThread()); aMIMEType = mMIMEType; PROFILER_LABEL("MediaEncoder", "GetEncodedData", js::ProfileEntry::Category::OTHER); bool reloop = true; while (reloop) { switch (mState) { case ENCODE_METADDATA: { LOG(LogLevel::Debug, ("ENCODE_METADDATA TimeStamp = %f", GetEncodeTimeStamp())); nsresult rv = CopyMetadataToMuxer(mAudioEncoder.get()); if (NS_FAILED(rv)) { LOG(LogLevel::Error, ("Error! Fail to Set Audio Metadata")); break; } rv = CopyMetadataToMuxer(mVideoEncoder.get()); if (NS_FAILED(rv)) { LOG(LogLevel::Error, ("Error! Fail to Set Video Metadata")); break; } rv = mWriter->GetContainerData(aOutputBufs, ContainerWriter::GET_HEADER); if (aOutputBufs != nullptr) { mSizeOfBuffer = aOutputBufs->ShallowSizeOfExcludingThis(MallocSizeOf); } if (NS_FAILED(rv)) { LOG(LogLevel::Error,("Error! writer fail to generate header!")); mState = ENCODE_ERROR; break; } LOG(LogLevel::Debug, ("Finish ENCODE_METADDATA TimeStamp = %f", GetEncodeTimeStamp())); mState = ENCODE_TRACK; break; } case ENCODE_TRACK: { LOG(LogLevel::Debug, ("ENCODE_TRACK TimeStamp = %f", GetEncodeTimeStamp())); EncodedFrameContainer encodedData; nsresult rv = NS_OK; rv = WriteEncodedDataToMuxer(mAudioEncoder.get()); if (NS_FAILED(rv)) { LOG(LogLevel::Error, ("Error! Fail to write audio encoder data to muxer")); break; } LOG(LogLevel::Debug, ("Audio encoded TimeStamp = %f", GetEncodeTimeStamp())); rv = WriteEncodedDataToMuxer(mVideoEncoder.get()); if (NS_FAILED(rv)) { LOG(LogLevel::Error, ("Fail to write video encoder data to muxer")); break; } LOG(LogLevel::Debug, ("Video encoded TimeStamp = %f", GetEncodeTimeStamp())); // In audio only or video only case, let unavailable track's flag to be true. bool isAudioCompleted = (mAudioEncoder && mAudioEncoder->IsEncodingComplete()) || !mAudioEncoder; bool isVideoCompleted = (mVideoEncoder && mVideoEncoder->IsEncodingComplete()) || !mVideoEncoder; rv = mWriter->GetContainerData(aOutputBufs, isAudioCompleted && isVideoCompleted ? ContainerWriter::FLUSH_NEEDED : 0); if (aOutputBufs != nullptr) { mSizeOfBuffer = aOutputBufs->ShallowSizeOfExcludingThis(MallocSizeOf); } if (NS_SUCCEEDED(rv)) { // Successfully get the copy of final container data from writer. reloop = false; } mState = (mWriter->IsWritingComplete()) ? ENCODE_DONE : ENCODE_TRACK; LOG(LogLevel::Debug, ("END ENCODE_TRACK TimeStamp = %f " "mState = %d aComplete %d vComplete %d", GetEncodeTimeStamp(), mState, isAudioCompleted, isVideoCompleted)); break; } case ENCODE_DONE: case ENCODE_ERROR: LOG(LogLevel::Debug, ("MediaEncoder has been shutdown.")); mSizeOfBuffer = 0; mShutdown = true; reloop = false; break; default: MOZ_CRASH("Invalid encode state"); } } }
bool GLLibraryEGL::EnsureInitialized() { if (mInitialized) { return true; } mozilla::ScopedGfxFeatureReporter reporter("EGL"); #ifdef MOZ_B2G if (!sCurrentContext.init()) MOZ_CRASH("Tls init failed"); #endif #ifdef XP_WIN if (!mEGLLibrary) { // On Windows, the GLESv2, EGL and DXSDK libraries are shipped with libxul and // we should look for them there. We have to load the libs in this // order, because libEGL.dll depends on libGLESv2.dll which depends on the DXSDK // libraries. This matters especially for WebRT apps which are in a different directory. // See bug 760323 and bug 749459 // Also note that we intentionally leak the libs we load. do { // Windows 8.1 has d3dcompiler_47.dll in the system directory. // Try it first. Note that _46 will never be in the system // directory and we ship with at least _43. So there is no point // trying _46 and _43 in the system directory. if (LoadLibrarySystem32(L"d3dcompiler_47.dll")) break; #ifdef MOZ_D3DCOMPILER_VISTA_DLL if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_VISTA_DLL)))) break; #endif #ifdef MOZ_D3DCOMPILER_XP_DLL if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_XP_DLL)))) break; #endif MOZ_ASSERT(false, "d3dcompiler DLL loading failed."); } while (false); LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libGLESv2.dll")); mEGLLibrary = LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libEGL.dll")); if (!mEGLLibrary) return false; } #else // !Windows // On non-Windows (Android) we use system copies of libEGL. We look for // the APITrace lib, libEGL.so, and libEGL.so.1 in that order. #if defined(ANDROID) if (!mEGLLibrary) mEGLLibrary = LoadApitraceLibrary(); #endif if (!mEGLLibrary) { printf_stderr("Attempting load of libEGL.so\n"); mEGLLibrary = PR_LoadLibrary("libEGL.so"); } #if defined(XP_UNIX) if (!mEGLLibrary) { mEGLLibrary = PR_LoadLibrary("libEGL.so.1"); } #endif if (!mEGLLibrary) { NS_WARNING("Couldn't load EGL LIB."); return false; } #endif // !Windows #define SYMBOL(name) \ { (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, nullptr } } GLLibraryLoader::SymLoadStruct earlySymbols[] = { SYMBOL(GetDisplay), SYMBOL(Terminate), SYMBOL(GetCurrentSurface), SYMBOL(GetCurrentContext), SYMBOL(MakeCurrent), SYMBOL(DestroyContext), SYMBOL(CreateContext), SYMBOL(DestroySurface), SYMBOL(CreateWindowSurface), SYMBOL(CreatePbufferSurface), SYMBOL(CreatePixmapSurface), SYMBOL(BindAPI), SYMBOL(Initialize), SYMBOL(ChooseConfig), SYMBOL(GetError), SYMBOL(GetConfigs), SYMBOL(GetConfigAttrib), SYMBOL(WaitNative), SYMBOL(GetProcAddress), SYMBOL(SwapBuffers), SYMBOL(CopyBuffers), SYMBOL(QueryString), SYMBOL(QueryContext), SYMBOL(BindTexImage), SYMBOL(ReleaseTexImage), SYMBOL(QuerySurface), { nullptr, { nullptr } } }; if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) { NS_WARNING("Couldn't find required entry points in EGL library (early init)"); return false; } GLLibraryLoader::SymLoadStruct optionalSymbols[] = { // On Android 4.3 and up, certain features like ANDROID_native_fence_sync // can only be queried by using a special eglQueryString. { (PRFuncPtr*) &mSymbols.fQueryStringImplementationANDROID, { "_Z35eglQueryStringImplementationANDROIDPvi", nullptr } }, { nullptr, { nullptr } } }; // Do not warn about the failure to load this - see bug 1092191 GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0], nullptr, nullptr, false); #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18 MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID, "Couldn't find eglQueryStringImplementationANDROID"); #endif mEGLDisplay = GetAndInitDisplay(*this, EGL_DEFAULT_DISPLAY); const char* vendor = (char*)fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR); if (vendor && (strstr(vendor, "TransGaming") != 0 || strstr(vendor, "Google Inc.") != 0)) { mIsANGLE = true; } if (mIsANGLE) { EGLDisplay newDisplay = EGL_NO_DISPLAY; // D3D11 ANGLE only works with OMTC; there's a bug in the non-OMTC layer // manager, and it's pointless to try to fix it. We also don't try // D3D11 ANGLE if the layer manager is prefering D3D9 (hrm, do we care?) if (gfxPrefs::LayersOffMainThreadCompositionEnabled() && !gfxPrefs::LayersPreferD3D9()) { if (gfxPrefs::WebGLANGLEForceD3D11()) { newDisplay = GetAndInitDisplay(*this, LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE); } else if (gfxPrefs::WebGLANGLETryD3D11() && gfxPlatform::CanUseDirect3D11ANGLE()) { newDisplay = GetAndInitDisplay(*this, LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE); } } if (newDisplay != EGL_NO_DISPLAY) { DebugOnly<EGLBoolean> success = fTerminate(mEGLDisplay); MOZ_ASSERT(success == LOCAL_EGL_TRUE); mEGLDisplay = newDisplay; vendor = (char*)fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR); } } InitExtensions(); GLLibraryLoader::PlatformLookupFunction lookupFunction = (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress; if (IsExtensionSupported(KHR_lock_surface)) { GLLibraryLoader::SymLoadStruct lockSymbols[] = { { (PRFuncPtr*) &mSymbols.fLockSurface, { "eglLockSurfaceKHR", nullptr } }, { (PRFuncPtr*) &mSymbols.fUnlockSurface, { "eglUnlockSurfaceKHR", nullptr } }, { nullptr, { nullptr } } }; bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary, &lockSymbols[0], lookupFunction); if (!success) { NS_ERROR("EGL supports KHR_lock_surface without exposing its functions!"); MarkExtensionUnsupported(KHR_lock_surface); mSymbols.fLockSurface = nullptr; mSymbols.fUnlockSurface = nullptr; } } if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) { GLLibraryLoader::SymLoadStruct d3dSymbols[] = { { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", nullptr } }, { nullptr, { nullptr } } }; bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary, &d3dSymbols[0], lookupFunction); if (!success) { NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!"); MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle); mSymbols.fQuerySurfacePointerANGLE = nullptr; } } //XXX: use correct extension name if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) { GLLibraryLoader::SymLoadStruct d3dSymbols[] = { { (PRFuncPtr*)&mSymbols.fSurfaceReleaseSyncANGLE, { "eglSurfaceReleaseSyncANGLE", nullptr } }, { nullptr, { nullptr } } }; bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary, &d3dSymbols[0], lookupFunction); if (!success) { NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!"); MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle); mSymbols.fSurfaceReleaseSyncANGLE = nullptr; } } if (IsExtensionSupported(KHR_fence_sync)) { GLLibraryLoader::SymLoadStruct syncSymbols[] = { { (PRFuncPtr*) &mSymbols.fCreateSync, { "eglCreateSyncKHR", nullptr } }, { (PRFuncPtr*) &mSymbols.fDestroySync, { "eglDestroySyncKHR", nullptr } }, { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "eglClientWaitSyncKHR", nullptr } }, { (PRFuncPtr*) &mSymbols.fGetSyncAttrib, { "eglGetSyncAttribKHR", nullptr } }, { nullptr, { nullptr } } }; bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary, &syncSymbols[0], lookupFunction); if (!success) { NS_ERROR("EGL supports KHR_fence_sync without exposing its functions!"); MarkExtensionUnsupported(KHR_fence_sync); mSymbols.fCreateSync = nullptr; mSymbols.fDestroySync = nullptr; mSymbols.fClientWaitSync = nullptr; mSymbols.fGetSyncAttrib = nullptr; } } if (IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base)) { GLLibraryLoader::SymLoadStruct imageSymbols[] = { { (PRFuncPtr*) &mSymbols.fCreateImage, { "eglCreateImageKHR", nullptr } }, { (PRFuncPtr*) &mSymbols.fDestroyImage, { "eglDestroyImageKHR", nullptr } }, { nullptr, { nullptr } } }; bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary, &imageSymbols[0], lookupFunction); if (!success) { NS_ERROR("EGL supports KHR_image(_base) without exposing its functions!"); MarkExtensionUnsupported(KHR_image); MarkExtensionUnsupported(KHR_image_base); MarkExtensionUnsupported(KHR_image_pixmap); mSymbols.fCreateImage = nullptr; mSymbols.fDestroyImage = nullptr; } } else { MarkExtensionUnsupported(KHR_image_pixmap); } if (IsExtensionSupported(ANDROID_native_fence_sync)) { GLLibraryLoader::SymLoadStruct nativeFenceSymbols[] = { { (PRFuncPtr*) &mSymbols.fDupNativeFenceFDANDROID, { "eglDupNativeFenceFDANDROID", nullptr } }, { nullptr, { nullptr } } }; bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary, &nativeFenceSymbols[0], lookupFunction); if (!success) { NS_ERROR("EGL supports ANDROID_native_fence_sync without exposing its functions!"); MarkExtensionUnsupported(ANDROID_native_fence_sync); mSymbols.fDupNativeFenceFDANDROID = nullptr; } } mInitialized = true; reporter.SetSuccessful(); return true; }
// We should never write to the fanotify fd. virtual void OnFileCanWriteWithoutBlocking(int aFd) { MOZ_CRASH("Must not write to fanotify fd"); }
void CanvasLayerD3D10::UpdateSurface() { if (!IsDirty()) return; Painted(); if (mDrawTarget) { mDrawTarget->Flush(); } else if (mIsD2DTexture) { return; } if (!mTexture) { return; } if (mGLContext) { SharedSurface_GL* surf = mGLContext->RequestFrame(); if (!surf) { return; } switch (surf->Type()) { case SharedSurfaceType::EGLSurfaceANGLE: { SharedSurface_ANGLEShareHandle* shareSurf = SharedSurface_ANGLEShareHandle::Cast(surf); mSRView = shareSurf->GetSRV(); return; } case SharedSurfaceType::Basic: { SharedSurface_Basic* shareSurf = SharedSurface_Basic::Cast(surf); // WebGL reads entire surface. D3D10_MAPPED_TEXTURE2D map; HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map); if (FAILED(hr)) { NS_WARNING("Failed to map CanvasLayer texture."); return; } DataSourceSurface* frameData = shareSurf->GetData(); // Scope for DrawTarget, so it's destroyed before Unmap. { IntSize boundsSize(mBounds.width, mBounds.height); RefPtr<DrawTarget> mapDt = Factory::CreateDrawTargetForData(BackendType::CAIRO, (uint8_t*)map.pData, boundsSize, map.RowPitch, SurfaceFormat::B8G8R8A8); Rect drawRect(0, 0, frameData->GetSize().width, frameData->GetSize().height); mapDt->DrawSurface(frameData, drawRect, drawRect, DrawSurfaceOptions(), DrawOptions(1.0F, CompositionOp::OP_SOURCE)); mapDt->Flush(); } mTexture->Unmap(0); mSRView = mUploadSRView; break; } default: MOZ_CRASH("Unhandled SharedSurfaceType."); } } else if (mSurface) { D3D10_MAPPED_TEXTURE2D map; HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map); if (FAILED(hr)) { NS_WARNING("Failed to lock CanvasLayer texture."); return; } RefPtr<DrawTarget> destTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture, SurfaceFormat::R8G8B8A8); Rect r(Point(0, 0), ToRect(mBounds).Size()); destTarget->DrawSurface(mSurface, r, r, DrawSurfaceOptions(), DrawOptions(1.0F, CompositionOp::OP_SOURCE)); mTexture->Unmap(0); mSRView = mUploadSRView; } }
bool StreamTextureSourceOGL::RetrieveTextureFromStream() { gl()->MakeCurrent(); SharedSurface* sharedSurf = mStream->SwapConsumer(); if (!sharedSurf) { // We don't have a valid surf to show yet. return false; } gl()->MakeCurrent(); mSize = IntSize(sharedSurf->Size().width, sharedSurf->Size().height); DataSourceSurface* toUpload = nullptr; switch (sharedSurf->Type()) { case SharedSurfaceType::GLTextureShare: { SharedSurface_GLTexture* glTexSurf = SharedSurface_GLTexture::Cast(sharedSurf); mTextureHandle = glTexSurf->ConsTexture(gl()); mTextureTarget = glTexSurf->ConsTextureTarget(); MOZ_ASSERT(mTextureHandle); mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8; break; } case SharedSurfaceType::EGLImageShare: { SharedSurface_EGLImage* eglImageSurf = SharedSurface_EGLImage::Cast(sharedSurf); eglImageSurf->AcquireConsumerTexture(gl(), &mTextureHandle, &mTextureTarget); MOZ_ASSERT(mTextureHandle); mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8; break; } #ifdef XP_MACOSX case SharedSurfaceType::IOSurface: { SharedSurface_IOSurface* glTexSurf = SharedSurface_IOSurface::Cast(sharedSurf); mTextureHandle = glTexSurf->ConsTexture(gl()); mTextureTarget = glTexSurf->ConsTextureTarget(); MOZ_ASSERT(mTextureHandle); mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8; break; } #endif case SharedSurfaceType::Basic: { toUpload = SharedSurface_Basic::Cast(sharedSurf)->GetData(); MOZ_ASSERT(toUpload); break; } default: MOZ_CRASH("Invalid SharedSurface type."); } if (toUpload) { // mBounds seems to end up as (0,0,0,0) a lot, so don't use it? nsIntSize size(ThebesIntSize(toUpload->GetSize())); nsIntRect rect(nsIntPoint(0,0), size); nsIntRegion bounds(rect); mFormat = UploadSurfaceToTexture(gl(), toUpload, bounds, mUploadTexture, true); mTextureHandle = mUploadTexture; mTextureTarget = LOCAL_GL_TEXTURE_2D; } MOZ_ASSERT(mTextureHandle); gl()->fBindTexture(mTextureTarget, mTextureHandle); gl()->fTexParameteri(mTextureTarget, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE); gl()->fTexParameteri(mTextureTarget, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE); ClearCachedFilter(); return true; }
uint32_t MozBaseAssembler::PlaceConstantPoolBarrier(int offset) { MOZ_CRASH("PlaceConstantPoolBarrier"); }
TimeStamp OfflineClockDriver::GetCurrentTimeStamp() { MOZ_CRASH("This driver does not support getting the current timestamp."); return TimeStamp(); }
void OriginAttributes::CreateSuffix(nsACString& aStr) const { UniquePtr<URLParams> params(new URLParams()); nsAutoString value; // // Important: While serializing any string-valued attributes, perform a // release-mode assertion to make sure that they don't contain characters that // will break the quota manager when it uses the serialization for file // naming (see addonId below). // if (mAppId != nsIScriptSecurityManager::NO_APP_ID) { value.AppendInt(mAppId); params->Set(NS_LITERAL_STRING("appId"), value); } if (mInIsolatedMozBrowser) { params->Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1")); } if (!mAddonId.IsEmpty()) { if (mAddonId.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) != kNotFound) { #ifdef MOZ_CRASHREPORTER CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Crash_AddonId"), NS_ConvertUTF16toUTF8(mAddonId)); #endif MOZ_CRASH(); } params->Set(NS_LITERAL_STRING("addonId"), mAddonId); } if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) { value.Truncate(); value.AppendInt(mUserContextId); params->Set(NS_LITERAL_STRING("userContextId"), value); } if (!mSignedPkg.IsEmpty()) { MOZ_RELEASE_ASSERT(mSignedPkg.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound); params->Set(NS_LITERAL_STRING("signedPkg"), mSignedPkg); } if (mPrivateBrowsingId) { value.Truncate(); value.AppendInt(mPrivateBrowsingId); params->Set(NS_LITERAL_STRING("privateBrowsingId"), value); } if (!mFirstPartyDomain.IsEmpty()) { MOZ_RELEASE_ASSERT(mFirstPartyDomain.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound); params->Set(NS_LITERAL_STRING("firstPartyDomain"), mFirstPartyDomain); } aStr.Truncate(); params->Serialize(value); if (!value.IsEmpty()) { aStr.AppendLiteral("^"); aStr.Append(NS_ConvertUTF16toUTF8(value)); } // In debug builds, check the whole string for illegal characters too (just in case). #ifdef DEBUG nsAutoCString str; str.Assign(aStr); MOZ_ASSERT(str.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound); #endif }
nsresult GetDirectoryListingTaskParent::IOWork() { MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!"); MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!"); if (mFileSystem->IsShutdown()) { return NS_ERROR_FAILURE; } bool exists; nsresult rv = mTargetPath->Exists(&exists); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (!exists) { if (!mFileSystem->ShouldCreateDirectory()) { return NS_ERROR_DOM_FILE_NOT_FOUND_ERR; } rv = mTargetPath->Create(nsIFile::DIRECTORY_TYPE, 0777); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } // Get isDirectory. bool isDir; rv = mTargetPath->IsDirectory(&isDir); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (!isDir) { return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR; } nsCOMPtr<nsISimpleEnumerator> entries; rv = mTargetPath->GetDirectoryEntries(getter_AddRefs(entries)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } bool filterOutSensitive = false; { HTMLSplitOnSpacesTokenizer tokenizer(mFilters, ';'); nsAutoString token; while (tokenizer.hasMoreTokens()) { token = tokenizer.nextToken(); if (token.EqualsLiteral("filter-out-sensitive")) { filterOutSensitive = true; } else { MOZ_CRASH("Unrecognized filter"); } } } for (;;) { bool hasMore = false; if (NS_WARN_IF(NS_FAILED(entries->HasMoreElements(&hasMore))) || !hasMore) { break; } nsCOMPtr<nsISupports> supp; if (NS_WARN_IF(NS_FAILED(entries->GetNext(getter_AddRefs(supp))))) { break; } nsCOMPtr<nsIFile> currFile = do_QueryInterface(supp); MOZ_ASSERT(currFile); bool isLink, isSpecial, isFile; if (NS_WARN_IF(NS_FAILED(currFile->IsSymlink(&isLink)) || NS_FAILED(currFile->IsSpecial(&isSpecial))) || isLink || isSpecial) { continue; } if (NS_WARN_IF(NS_FAILED(currFile->IsFile(&isFile)) || NS_FAILED(currFile->IsDirectory(&isDir))) || !(isFile || isDir)) { continue; } if (filterOutSensitive) { bool isHidden; if (NS_WARN_IF(NS_FAILED(currFile->IsHidden(&isHidden))) || isHidden) { continue; } nsAutoString leafName; if (NS_WARN_IF(NS_FAILED(currFile->GetLeafName(leafName)))) { continue; } if (leafName[0] == char16_t('.')) { continue; } } nsAutoString path; if (NS_WARN_IF(NS_FAILED(currFile->GetPath(path)))) { continue; } Directory::FileOrDirectoryPath element; element.mPath = path; element.mType = isDir ? Directory::FileOrDirectoryPath::eDirectoryPath : Directory::FileOrDirectoryPath::eFilePath; if (!mTargetData.AppendElement(element, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } } return NS_OK; }
bool BluetoothServiceChildProcess::UpdateSdpRecords(const nsAString& aDeviceAddress, BluetoothProfileManagerBase* aManager) { MOZ_CRASH("This should never be called!"); }
nsresult BluetoothServiceChildProcess::SendInputMessage(const nsAString& aDeviceAddresses, const nsAString& aMessage) { MOZ_CRASH("This should never be called!"); }
bool ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm) { // Guard that R0 is an integer and R1 is an integer. Label failure; masm.branchTestInt32(Assembler::NotEqual, R0, &failure); masm.branchTestInt32(Assembler::NotEqual, R1, &failure); Label revertRegister, maybeNegZero; switch(op_) { case JSOP_ADD: masm.unboxInt32(R0, ExtractTemp0); // Just jump to failure on overflow. R0 and R1 are preserved, so we can just jump to // the next stub. masm.addl(R1.valueReg(), ExtractTemp0); masm.j(Assembler::Overflow, &failure); // Box the result masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg()); break; case JSOP_SUB: masm.unboxInt32(R0, ExtractTemp0); masm.subl(R1.valueReg(), ExtractTemp0); masm.j(Assembler::Overflow, &failure); masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg()); break; case JSOP_MUL: masm.unboxInt32(R0, ExtractTemp0); masm.imull(R1.valueReg(), ExtractTemp0); masm.j(Assembler::Overflow, &failure); masm.branchTest32(Assembler::Zero, ExtractTemp0, ExtractTemp0, &maybeNegZero); masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg()); break; case JSOP_DIV: { MOZ_ASSERT(R2.scratchReg() == rax); MOZ_ASSERT(R0.valueReg() != rdx); MOZ_ASSERT(R1.valueReg() != rdx); masm.unboxInt32(R0, eax); masm.unboxInt32(R1, ExtractTemp0); // Prevent division by 0. masm.branchTest32(Assembler::Zero, ExtractTemp0, ExtractTemp0, &failure); // Prevent negative 0 and -2147483648 / -1. masm.branch32(Assembler::Equal, eax, Imm32(INT32_MIN), &failure); Label notZero; masm.branch32(Assembler::NotEqual, eax, Imm32(0), ¬Zero); masm.branchTest32(Assembler::Signed, ExtractTemp0, ExtractTemp0, &failure); masm.bind(¬Zero); // Sign extend eax into edx to make (edx:eax), since idiv is 64-bit. masm.cdq(); masm.idiv(ExtractTemp0); // A remainder implies a double result. masm.branchTest32(Assembler::NonZero, edx, edx, &failure); masm.boxValue(JSVAL_TYPE_INT32, eax, R0.valueReg()); break; } case JSOP_MOD: { MOZ_ASSERT(R2.scratchReg() == rax); MOZ_ASSERT(R0.valueReg() != rdx); MOZ_ASSERT(R1.valueReg() != rdx); masm.unboxInt32(R0, eax); masm.unboxInt32(R1, ExtractTemp0); // x % 0 always results in NaN. masm.branchTest32(Assembler::Zero, ExtractTemp0, ExtractTemp0, &failure); // Prevent negative 0 and -2147483648 % -1. masm.branchTest32(Assembler::Zero, eax, Imm32(0x7fffffff), &failure); // Sign extend eax into edx to make (edx:eax), since idiv is 64-bit. masm.cdq(); masm.idiv(ExtractTemp0); // Fail when we would need a negative remainder. Label done; masm.branchTest32(Assembler::NonZero, edx, edx, &done); masm.orl(ExtractTemp0, eax); masm.branchTest32(Assembler::Signed, eax, eax, &failure); masm.bind(&done); masm.boxValue(JSVAL_TYPE_INT32, edx, R0.valueReg()); break; } case JSOP_BITOR: // We can overide R0, because the instruction is unfailable. // Because the tag bits are the same, we don't need to retag. masm.orq(R1.valueReg(), R0.valueReg()); break; case JSOP_BITXOR: masm.xorl(R1.valueReg(), R0.valueReg()); masm.tagValue(JSVAL_TYPE_INT32, R0.valueReg(), R0); break; case JSOP_BITAND: masm.andq(R1.valueReg(), R0.valueReg()); break; case JSOP_LSH: masm.unboxInt32(R0, ExtractTemp0); masm.unboxInt32(R1, ecx); // Unboxing R1 to ecx, clobbers R0. masm.shll_cl(ExtractTemp0); masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg()); break; case JSOP_RSH: masm.unboxInt32(R0, ExtractTemp0); masm.unboxInt32(R1, ecx); masm.sarl_cl(ExtractTemp0); masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg()); break; case JSOP_URSH: if (!allowDouble_) masm.movq(R0.valueReg(), ScratchReg); masm.unboxInt32(R0, ExtractTemp0); masm.unboxInt32(R1, ecx); // This clobbers R0 masm.shrl_cl(ExtractTemp0); masm.test32(ExtractTemp0, ExtractTemp0); if (allowDouble_) { Label toUint; masm.j(Assembler::Signed, &toUint); // Box and return. masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg()); EmitReturnFromIC(masm); masm.bind(&toUint); masm.convertUInt32ToDouble(ExtractTemp0, ScratchDoubleReg); masm.boxDouble(ScratchDoubleReg, R0); } else { masm.j(Assembler::Signed, &revertRegister); masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg()); } break; default: MOZ_CRASH("Unhandled op in BinaryArith_Int32"); } // Return from stub. EmitReturnFromIC(masm); if (op_ == JSOP_MUL) { masm.bind(&maybeNegZero); // Result is -0 if exactly one of lhs or rhs is negative. masm.movl(R0.valueReg(), ScratchReg); masm.orl(R1.valueReg(), ScratchReg); masm.j(Assembler::Signed, &failure); // Result is +0. masm.moveValue(Int32Value(0), R0); EmitReturnFromIC(masm); } // Revert the content of R0 in the fallible >>> case. if (op_ == JSOP_URSH && !allowDouble_) { masm.bind(&revertRegister); // Restore tag and payload. masm.movq(ScratchReg, R0.valueReg()); // Fall through to failure. } // Failure case - jump to next stub masm.bind(&failure); EmitStubGuardFailure(masm); return true; }
void HTMLTextAreaElement::SetRangeText(const nsAString& aReplacement, uint32_t aStart, uint32_t aEnd, const SelectionMode& aSelectMode, ErrorResult& aRv, int32_t aSelectionStart, int32_t aSelectionEnd) { if (aStart > aEnd) { aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return; } nsAutoString value; GetValueInternal(value, false); uint32_t inputValueLength = value.Length(); if (aStart > inputValueLength) { aStart = inputValueLength; } if (aEnd > inputValueLength) { aEnd = inputValueLength; } if (aSelectionStart == -1 && aSelectionEnd == -1) { aRv = GetSelectionRange(&aSelectionStart, &aSelectionEnd); if (aRv.Failed()) { if (mState.IsSelectionCached()) { aSelectionStart = mState.GetSelectionProperties().GetStart(); aSelectionEnd = mState.GetSelectionProperties().GetEnd(); aRv = NS_OK; } } } if (aStart <= aEnd) { value.Replace(aStart, aEnd - aStart, aReplacement); nsresult rv = SetValueInternal(value, nsTextEditorState::eSetValue_ByContent); if (NS_FAILED(rv)) { aRv.Throw(rv); return; } } uint32_t newEnd = aStart + aReplacement.Length(); int32_t delta = aReplacement.Length() - (aEnd - aStart); switch (aSelectMode) { case mozilla::dom::SelectionMode::Select: { aSelectionStart = aStart; aSelectionEnd = newEnd; } break; case mozilla::dom::SelectionMode::Start: { aSelectionStart = aSelectionEnd = aStart; } break; case mozilla::dom::SelectionMode::End: { aSelectionStart = aSelectionEnd = newEnd; } break; case mozilla::dom::SelectionMode::Preserve: { if ((uint32_t)aSelectionStart > aEnd) { aSelectionStart += delta; } else if ((uint32_t)aSelectionStart > aStart) { aSelectionStart = aStart; } if ((uint32_t)aSelectionEnd > aEnd) { aSelectionEnd += delta; } else if ((uint32_t)aSelectionEnd > aStart) { aSelectionEnd = newEnd; } } break; default: MOZ_CRASH("Unknown mode!"); } Optional<nsAString> direction; SetSelectionRange(aSelectionStart, aSelectionEnd, direction, aRv); }
WebGLContext::FakeBlackTexture::FakeBlackTexture(gl::GLContext* gl, TexTarget target, FakeBlackType type) : mGL(gl) , mGLName(CreateGLTexture(gl)) { GLenum texFormat; switch (type) { case FakeBlackType::RGBA0000: texFormat = LOCAL_GL_RGBA; break; case FakeBlackType::RGBA0001: texFormat = LOCAL_GL_RGB; break; default: MOZ_CRASH("bad type"); } gl::ScopedBindTexture scopedBind(mGL, mGLName, target.get()); mGL->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST); mGL->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST); // We allocate our zeros on the heap, and we overallocate (16 bytes instead of 4) to // minimize the risk of running into a driver bug in texImage2D, as it is a bit // unusual maybe to create 1x1 textures, and the stack may not have the alignment that // TexImage2D expects. const webgl::DriverUnpackInfo dui = {texFormat, texFormat, LOCAL_GL_UNSIGNED_BYTE}; UniqueBuffer zeros = moz_xcalloc(1, 16); // Infallible allocation. MOZ_ASSERT(gl->IsCurrent()); if (target == LOCAL_GL_TEXTURE_CUBE_MAP) { for (int i = 0; i < 6; ++i) { const TexImageTarget curTarget = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; const GLenum error = DoTexImage(mGL, curTarget.get(), 0, &dui, 1, 1, 1, zeros.get()); if (error) { const nsPrintfCString text("DoTexImage failed with `error`: 0x%04x, " "for `curTarget`: 0x%04x, " "`dui`: {0x%04x, 0x%04x, 0x%04x}.", error, curTarget.get(), dui.internalFormat, dui.unpackFormat, dui.unpackType); gfxCriticalError() << text.BeginReading(); MOZ_CRASH("Unexpected error during cube map FakeBlack creation."); } } } else { const GLenum error = DoTexImage(mGL, target.get(), 0, &dui, 1, 1, 1, zeros.get()); if (error) { const nsPrintfCString text("DoTexImage failed with `error`: 0x%04x, " "for `target`: 0x%04x, " "`dui`: {0x%04x, 0x%04x, 0x%04x}.", error, target.get(), dui.internalFormat, dui.unpackFormat, dui.unpackType); gfxCriticalError() << text.BeginReading(); MOZ_CRASH("Unexpected error during FakeBlack creation."); } } }
/* * The meat of our exception handler. This thread waits for an exception * message, annotates the exception if needed, then forwards it to the * previously installed handler (which will likely terminate the process). */ static void MachExceptionHandler() { kern_return_t ret; MachExceptionParameters& current = sMachExceptionState.current; MachExceptionParameters& previous = sMachExceptionState.previous; // We use the simplest kind of 64-bit exception message here. ExceptionRequest64 request = {}; request.header.msgh_local_port = current.port; request.header.msgh_size = static_cast<mach_msg_size_t>(sizeof(request)); ret = mach_msg(&request.header, MACH_RCV_MSG, 0, request.header.msgh_size, current.port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); // Restore the previous handler. We're going to forward to it // anyway, and if we crash while doing so we don't want to hang. task_set_exception_ports(mach_task_self(), previous.mask, previous.port, previous.behavior, previous.flavor); // If we failed even receiving the message, just give up. if (ret != MACH_MSG_SUCCESS) MOZ_CRASH("MachExceptionHandler: mach_msg failed to receive a message!"); // Terminate the thread if we're shutting down. if (request.header.msgh_id == sIDQuit) return; // The only other valid message ID is the one associated with the // EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES behavior we chose. if (request.header.msgh_id != sIDRequest64) MOZ_CRASH("MachExceptionHandler: Unexpected Message ID!"); // Make sure we can understand the exception we received. if (request.exception != EXC_BAD_ACCESS || request.code_count != 2) MOZ_CRASH("MachExceptionHandler: Unexpected exception type!"); // Get the address that the offending code tried to access. uintptr_t address = uintptr_t(request.code[1]); // If the faulting address is inside one of our protected regions, we // want to annotate the crash to make it stand out from the crowd. if (sProtectedRegions.isProtected(address)) { ReportCrashIfDebug("Hit MOZ_CRASH(Tried to access a protected region!)\n"); MOZ_CRASH_ANNOTATE("MOZ_CRASH(Tried to access a protected region!)"); } // Forward to the previous handler which may be a debugger, the unix // signal handler, the crash reporter or something else entirely. if (previous.port != MACH_PORT_NULL) { mach_msg_type_number_t stateCount; thread_state_data_t state; if ((uint32_t(previous.behavior) & ~MACH_EXCEPTION_CODES) != EXCEPTION_DEFAULT) { // If the previous handler requested thread state, get it here. stateCount = THREAD_STATE_MAX; ret = thread_get_state(request.thread.name, previous.flavor, state, &stateCount); if (ret != KERN_SUCCESS) MOZ_CRASH("MachExceptionHandler: Could not get the thread state to forward!"); } // Depending on the behavior of the previous handler, the forwarded // exception message will have a different set of fields. // Of particular note is that exception handlers that lack // MACH_EXCEPTION_CODES will get 32-bit fields even on 64-bit // systems. It appears that OSX simply truncates these fields. ExceptionRequestUnion forward; switch (uint32_t(previous.behavior)) { case EXCEPTION_DEFAULT: CopyExceptionRequest32(request, forward.r32); break; case EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES: CopyExceptionRequest64(request, forward.r64); break; case EXCEPTION_STATE: CopyExceptionRequestState32(request, forward.rs32, previous.flavor, stateCount, state); break; case EXCEPTION_STATE | MACH_EXCEPTION_CODES: CopyExceptionRequestState64(request, forward.rs64, previous.flavor, stateCount, state); break; case EXCEPTION_STATE_IDENTITY: CopyExceptionRequestStateIdentity32(request, forward.rsi32, previous.flavor, stateCount, state); break; case EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES: CopyExceptionRequestStateIdentity64(request, forward.rsi64, previous.flavor, stateCount, state); break; default: MOZ_CRASH("MachExceptionHandler: Unknown previous handler behavior!"); } // Forward the generated message to the old port. The local and remote // port fields *and their rights* are swapped on arrival, so we need to // swap them back first. forward.header.msgh_bits = (request.header.msgh_bits & ~MACH_MSGH_BITS_PORTS_MASK) | MACH_MSGH_BITS(MACH_MSGH_BITS_LOCAL(request.header.msgh_bits), MACH_MSGH_BITS_REMOTE(request.header.msgh_bits)); forward.header.msgh_local_port = forward.header.msgh_remote_port; forward.header.msgh_remote_port = previous.port; ret = mach_msg(&forward.header, MACH_SEND_MSG, forward.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (ret != MACH_MSG_SUCCESS) MOZ_CRASH("MachExceptionHandler: Failed to forward to the previous handler!"); } else { // There was no previous task-level exception handler, so defer to the // host level one instead. We set the return code to KERN_FAILURE to // indicate that we did not handle the exception. // The reply message ID is always the request ID + 100. ExceptionReply reply = {}; reply.header.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(request.header.msgh_bits), 0); reply.header.msgh_size = static_cast<mach_msg_size_t>(sizeof(reply)); reply.header.msgh_remote_port = request.header.msgh_remote_port; reply.header.msgh_local_port = MACH_PORT_NULL; reply.header.msgh_id = request.header.msgh_id + 100; reply.NDR = request.NDR; reply.RetCode = KERN_FAILURE; ret = mach_msg(&reply.header, MACH_SEND_MSG, reply.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (ret != MACH_MSG_SUCCESS) MOZ_CRASH("MachExceptionHandler: Failed to forward to the host level!"); } }
NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, nsresult aResult) { MOZ_CRASH("DoomFileHelper::OnDataWritten should not be called!"); return NS_ERROR_UNEXPECTED; }
bool ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm) { // Guard that R0 is an integer and R1 is an integer. Label failure; masm.branchTestInt32(Assembler::NotEqual, R0, &failure); masm.branchTestInt32(Assembler::NotEqual, R1, &failure); // Add R0 and R1. Don't need to explicitly unbox, just use R2's payloadReg. Register scratchReg = R2.payloadReg(); // DIV and MOD need an extra non-volatile ValueOperand to hold R0. AllocatableGeneralRegisterSet savedRegs(availableGeneralRegs(2)); savedRegs.set() = GeneralRegisterSet::Intersect(GeneralRegisterSet::NonVolatile(), savedRegs.set()); Label goodMul, divTest1, divTest2; switch(op_) { case JSOP_ADD: // We know R0.typeReg() already contains the integer tag. No boxing // required. masm.ma_addTestOverflow(scratchReg, R0.payloadReg(), R1.payloadReg(), &failure); masm.move32(scratchReg, R0.payloadReg()); break; case JSOP_SUB: masm.ma_subTestOverflow(scratchReg, R0.payloadReg(), R1.payloadReg(), &failure); masm.move32(scratchReg, R0.payloadReg()); break; case JSOP_MUL: { masm.ma_mul_branch_overflow(scratchReg, R0.payloadReg(), R1.payloadReg(), &failure); masm.ma_b(scratchReg, Imm32(0), &goodMul, Assembler::NotEqual, ShortJump); // Result is -0 if operands have different signs. masm.as_xor(t8, R0.payloadReg(), R1.payloadReg()); masm.ma_b(t8, Imm32(0), &failure, Assembler::LessThan, ShortJump); masm.bind(&goodMul); masm.move32(scratchReg, R0.payloadReg()); break; } case JSOP_DIV: case JSOP_MOD: { // Check for INT_MIN / -1, it results in a double. masm.ma_b(R0.payloadReg(), Imm32(INT_MIN), &divTest1, Assembler::NotEqual, ShortJump); masm.ma_b(R1.payloadReg(), Imm32(-1), &failure, Assembler::Equal, ShortJump); masm.bind(&divTest1); // Check for division by zero masm.ma_b(R1.payloadReg(), Imm32(0), &failure, Assembler::Equal, ShortJump); // Check for 0 / X with X < 0 (results in -0). masm.ma_b(R0.payloadReg(), Imm32(0), &divTest2, Assembler::NotEqual, ShortJump); masm.ma_b(R1.payloadReg(), Imm32(0), &failure, Assembler::LessThan, ShortJump); masm.bind(&divTest2); masm.as_div(R0.payloadReg(), R1.payloadReg()); if (op_ == JSOP_DIV) { // Result is a double if the remainder != 0. masm.as_mfhi(scratchReg); masm.ma_b(scratchReg, Imm32(0), &failure, Assembler::NotEqual, ShortJump); masm.as_mflo(scratchReg); masm.tagValue(JSVAL_TYPE_INT32, scratchReg, R0); } else { Label done; // If X % Y == 0 and X < 0, the result is -0. masm.as_mfhi(scratchReg); masm.ma_b(scratchReg, Imm32(0), &done, Assembler::NotEqual, ShortJump); masm.ma_b(R0.payloadReg(), Imm32(0), &failure, Assembler::LessThan, ShortJump); masm.bind(&done); masm.tagValue(JSVAL_TYPE_INT32, scratchReg, R0); } break; } case JSOP_BITOR: masm.ma_or(R0.payloadReg() , R0.payloadReg(), R1.payloadReg()); break; case JSOP_BITXOR: masm.ma_xor(R0.payloadReg() , R0.payloadReg(), R1.payloadReg()); break; case JSOP_BITAND: masm.ma_and(R0.payloadReg() , R0.payloadReg(), R1.payloadReg()); break; case JSOP_LSH: // MIPS will only use 5 lowest bits in R1 as shift offset. masm.ma_sll(R0.payloadReg(), R0.payloadReg(), R1.payloadReg()); break; case JSOP_RSH: masm.ma_sra(R0.payloadReg(), R0.payloadReg(), R1.payloadReg()); break; case JSOP_URSH: masm.ma_srl(scratchReg, R0.payloadReg(), R1.payloadReg()); if (allowDouble_) { Label toUint; masm.ma_b(scratchReg, Imm32(0), &toUint, Assembler::LessThan, ShortJump); // Move result and box for return. masm.move32(scratchReg, R0.payloadReg()); EmitReturnFromIC(masm); masm.bind(&toUint); masm.convertUInt32ToDouble(scratchReg, FloatReg1); masm.boxDouble(FloatReg1, R0); } else { masm.ma_b(scratchReg, Imm32(0), &failure, Assembler::LessThan, ShortJump); // Move result for return. masm.move32(scratchReg, R0.payloadReg()); } break; default: MOZ_CRASH("Unhandled op for BinaryArith_Int32."); } EmitReturnFromIC(masm); // Failure case - jump to next stub masm.bind(&failure); EmitStubGuardFailure(masm); return true; }
NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) { MOZ_CRASH("DoomFileHelper::OnEOFSet should not be called!"); return NS_ERROR_UNEXPECTED; }
void FileBlobImpl::SetLastModified(int64_t aLastModified) { MOZ_CRASH("SetLastModified of a real file is not allowed!"); }
NS_IMETHOD OnMetadataRead(nsresult aResult) { MOZ_CRASH("MetadataListenerHelper::OnMetadataRead should not be called!"); return NS_ERROR_UNEXPECTED; }
MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams) : mInvalidReason(nullptr) { bool isBrowser = false; uint32_t ownAppId = NO_APP_ID; uint32_t containingAppId = NO_APP_ID; const IPCTabAppBrowserContext& appBrowser = aParams.appBrowserContext(); switch(appBrowser.type()) { case IPCTabAppBrowserContext::TPopupIPCTabContext: { const PopupIPCTabContext &ipcContext = appBrowser.get_PopupIPCTabContext(); TabContext *context; if (ipcContext.openerParent()) { context = static_cast<TabParent*>(ipcContext.openerParent()); if (context->IsBrowserElement() && !ipcContext.isBrowserElement()) { // If the TabParent corresponds to a browser element, then it can only // open other browser elements, for security reasons. We should have // checked this before calling the TabContext constructor, so this is // a fatal error. mInvalidReason = "Child is-browser process tried to " "open a non-browser tab."; return; } } else if (ipcContext.openerChild()) { context = static_cast<TabChild*>(ipcContext.openerChild()); } else { // This should be unreachable because PopupIPCTabContext::opener is not a // nullable field. mInvalidReason = "PopupIPCTabContext::opener was null (?!)."; return; } // Browser elements can't nest other browser elements. So if // our opener is browser element, we must be a new DOM window // opened by it. In that case we inherit our containing app ID // (if any). // // Otherwise, we're a new app window and we inherit from our // opener app. if (ipcContext.isBrowserElement()) { isBrowser = true; ownAppId = NO_APP_ID; containingAppId = context->OwnOrContainingAppId(); } else { isBrowser = false; ownAppId = context->mOwnAppId; containingAppId = context->mContainingAppId; } break; } case IPCTabAppBrowserContext::TAppFrameIPCTabContext: { const AppFrameIPCTabContext &ipcContext = appBrowser.get_AppFrameIPCTabContext(); isBrowser = false; ownAppId = ipcContext.ownAppId(); containingAppId = ipcContext.appFrameOwnerAppId(); break; } case IPCTabAppBrowserContext::TBrowserFrameIPCTabContext: { const BrowserFrameIPCTabContext &ipcContext = appBrowser.get_BrowserFrameIPCTabContext(); isBrowser = true; ownAppId = NO_APP_ID; containingAppId = ipcContext.browserFrameOwnerAppId(); break; } case IPCTabAppBrowserContext::TVanillaFrameIPCTabContext: { isBrowser = false; ownAppId = NO_APP_ID; containingAppId = NO_APP_ID; break; } default: { MOZ_CRASH(); } } nsCOMPtr<mozIApplication> ownApp = GetAppForId(ownAppId); if ((ownApp == nullptr) != (ownAppId == NO_APP_ID)) { mInvalidReason = "Got an ownAppId that didn't correspond to an app."; return; } nsCOMPtr<mozIApplication> containingApp = GetAppForId(containingAppId); if ((containingApp == nullptr) != (containingAppId == NO_APP_ID)) { mInvalidReason = "Got a containingAppId that didn't correspond to an app."; return; } bool rv; if (isBrowser) { rv = mTabContext.SetTabContextForBrowserFrame(containingApp, aParams.scrollingBehavior()); } else { rv = mTabContext.SetTabContextForAppFrame(ownApp, containingApp, aParams.scrollingBehavior()); } if (!rv) { mInvalidReason = "Couldn't initialize TabContext."; } }
nsresult CacheFile::OnChunkUpdated(CacheFileChunk *aChunk) { MOZ_CRASH("CacheFile::OnChunkUpdated should not be called!"); return NS_ERROR_UNEXPECTED; }
bool GMPChild::RecvCrashPluginNow() { MOZ_CRASH(); return true; }
nsresult CacheFile::OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult) { MOZ_CRASH("CacheFile::OnDataRead should not be called!"); return NS_ERROR_UNEXPECTED; }
already_AddRefed<nsIPrincipal> PrincipalInfoToPrincipal(const PrincipalInfo& aPrincipalInfo, nsresult* aOptionalResult) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aPrincipalInfo.type() != PrincipalInfo::T__None); nsresult stackResult; nsresult& rv = aOptionalResult ? *aOptionalResult : stackResult; nsCOMPtr<nsIScriptSecurityManager> secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; } nsCOMPtr<nsIPrincipal> principal; switch (aPrincipalInfo.type()) { case PrincipalInfo::TSystemPrincipalInfo: { rv = secMan->GetSystemPrincipal(getter_AddRefs(principal)); if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; } return principal.forget(); } case PrincipalInfo::TNullPrincipalInfo: { principal = do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID, &rv); if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; } return principal.forget(); } case PrincipalInfo::TContentPrincipalInfo: { const ContentPrincipalInfo& info = aPrincipalInfo.get_ContentPrincipalInfo(); nsCOMPtr<nsIURI> uri; rv = NS_NewURI(getter_AddRefs(uri), info.spec()); if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; } if (info.appId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) { rv = secMan->GetSimpleCodebasePrincipal(uri, getter_AddRefs(principal)); } else { rv = secMan->GetAppCodebasePrincipal(uri, info.appId(), info.isInBrowserElement(), getter_AddRefs(principal)); } if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; } return principal.forget(); } case PrincipalInfo::TExpandedPrincipalInfo: { const ExpandedPrincipalInfo& info = aPrincipalInfo.get_ExpandedPrincipalInfo(); nsTArray< nsCOMPtr<nsIPrincipal> > whitelist; nsCOMPtr<nsIPrincipal> wlPrincipal; for (uint32_t i = 0; i < info.whitelist().Length(); i++) { wlPrincipal = PrincipalInfoToPrincipal(info.whitelist()[i], &rv); if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; } // append that principal to the whitelist whitelist.AppendElement(wlPrincipal); } nsRefPtr<nsExpandedPrincipal> expandedPrincipal = new nsExpandedPrincipal(whitelist); if (!expandedPrincipal) { NS_WARNING("could not instantiate expanded principal"); return nullptr; } principal = expandedPrincipal; return principal.forget(); } default: MOZ_CRASH("Unknown PrincipalInfo type!"); } MOZ_CRASH("Should never get here!"); }
nsresult CacheFile::OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) { MOZ_CRASH("CacheFile::OnEOFSet should not be called!"); return NS_ERROR_UNEXPECTED; }
static already_AddRefed<const webgl::LinkedProgramInfo> QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl) { RefPtr<webgl::LinkedProgramInfo> info(new webgl::LinkedProgramInfo(prog)); GLuint maxAttribLenWithNull = 0; gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, (GLint*)&maxAttribLenWithNull); if (maxAttribLenWithNull < 1) maxAttribLenWithNull = 1; GLuint maxUniformLenWithNull = 0; gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_UNIFORM_MAX_LENGTH, (GLint*)&maxUniformLenWithNull); if (maxUniformLenWithNull < 1) maxUniformLenWithNull = 1; GLuint maxUniformBlockLenWithNull = 0; if (gl->IsSupported(gl::GLFeature::uniform_buffer_object)) { gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, (GLint*)&maxUniformBlockLenWithNull); if (maxUniformBlockLenWithNull < 1) maxUniformBlockLenWithNull = 1; } #ifdef DUMP_SHADERVAR_MAPPINGS printf_stderr("maxAttribLenWithNull: %d\n", maxAttribLenWithNull); printf_stderr("maxUniformLenWithNull: %d\n", maxUniformLenWithNull); printf_stderr("maxUniformBlockLenWithNull: %d\n", maxUniformBlockLenWithNull); #endif // Attribs GLuint numActiveAttribs = 0; gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_ATTRIBUTES, (GLint*)&numActiveAttribs); for (GLuint i = 0; i < numActiveAttribs; i++) { nsAutoCString mappedName; mappedName.SetLength(maxAttribLenWithNull - 1); GLsizei lengthWithoutNull = 0; GLint elemCount = 0; // `size` GLenum elemType = 0; // `type` gl->fGetActiveAttrib(prog->mGLName, i, mappedName.Length()+1, &lengthWithoutNull, &elemCount, &elemType, mappedName.BeginWriting()); mappedName.SetLength(lengthWithoutNull); // Collect ActiveInfos: // Attribs can't be arrays, so we can skip some of the mess we have in the Uniform // path. nsDependentCString userName; if (!prog->FindAttribUserNameByMappedName(mappedName, &userName)) userName.Rebind(mappedName, 0); #ifdef DUMP_SHADERVAR_MAPPINGS printf_stderr("[attrib %i] %s/%s\n", i, mappedName.BeginReading(), userName.BeginReading()); printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull); #endif const bool isArray = false; AddActiveInfo(prog->Context(), elemCount, elemType, isArray, userName, mappedName, &info->activeAttribs, &info->attribMap); // Collect active locations: GLint loc = gl->fGetAttribLocation(prog->mGLName, mappedName.BeginReading()); if (loc == -1) MOZ_CRASH("Active attrib has no location."); info->activeAttribLocs.insert(loc); } // Uniforms const bool needsCheckForArrays = gl->WorkAroundDriverBugs(); GLuint numActiveUniforms = 0; gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_UNIFORMS, (GLint*)&numActiveUniforms); for (GLuint i = 0; i < numActiveUniforms; i++) { nsAutoCString mappedName; mappedName.SetLength(maxUniformLenWithNull - 1); GLsizei lengthWithoutNull = 0; GLint elemCount = 0; // `size` GLenum elemType = 0; // `type` gl->fGetActiveUniform(prog->mGLName, i, mappedName.Length()+1, &lengthWithoutNull, &elemCount, &elemType, mappedName.BeginWriting()); mappedName.SetLength(lengthWithoutNull); nsAutoCString baseMappedName; bool isArray; size_t arrayIndex; if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex)) MOZ_CRASH("Failed to parse `mappedName` received from driver."); // Note that for good drivers, `isArray` should already be correct. // However, if FindUniform succeeds, it will be validator-guaranteed correct. nsAutoCString baseUserName; if (!prog->FindUniformByMappedName(baseMappedName, &baseUserName, &isArray)) { baseUserName = baseMappedName; if (needsCheckForArrays && !isArray) { // By GLES 3, GetUniformLocation("foo[0]") should return -1 if `foo` is // not an array. Our current linux Try slaves return the location of `foo` // anyways, though. std::string mappedNameStr = baseMappedName.BeginReading(); mappedNameStr += "[0]"; GLint loc = gl->fGetUniformLocation(prog->mGLName, mappedNameStr.c_str()); if (loc != -1) isArray = true; } } #ifdef DUMP_SHADERVAR_MAPPINGS printf_stderr("[uniform %i] %s/%i/%s/%s\n", i, mappedName.BeginReading(), (int)isArray, baseMappedName.BeginReading(), baseUserName.BeginReading()); printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull); printf_stderr(" isArray: %d\n", (int)isArray); #endif AddActiveInfo(prog->Context(), elemCount, elemType, isArray, baseUserName, baseMappedName, &info->activeUniforms, &info->uniformMap); } // Uniform Blocks if (gl->IsSupported(gl::GLFeature::uniform_buffer_object)) { GLuint numActiveUniformBlocks = 0; gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_UNIFORM_BLOCKS, (GLint*)&numActiveUniformBlocks); for (GLuint i = 0; i < numActiveUniformBlocks; i++) { nsAutoCString mappedName; mappedName.SetLength(maxUniformBlockLenWithNull - 1); GLint lengthWithoutNull; gl->fGetActiveUniformBlockiv(prog->mGLName, i, LOCAL_GL_UNIFORM_BLOCK_NAME_LENGTH, &lengthWithoutNull); gl->fGetActiveUniformBlockName(prog->mGLName, i, maxUniformBlockLenWithNull, &lengthWithoutNull, mappedName.BeginWriting()); mappedName.SetLength(lengthWithoutNull); nsAutoCString baseMappedName; bool isArray; size_t arrayIndex; if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex)) MOZ_CRASH("Failed to parse `mappedName` received from driver."); nsAutoCString baseUserName; if (!prog->FindUniformBlockByMappedName(baseMappedName, &baseUserName, &isArray)) { baseUserName = baseMappedName; if (needsCheckForArrays && !isArray) { std::string mappedNameStr = baseMappedName.BeginReading(); mappedNameStr += "[0]"; GLuint loc = gl->fGetUniformBlockIndex(prog->mGLName, mappedNameStr.c_str()); if (loc != LOCAL_GL_INVALID_INDEX) isArray = true; } } #ifdef DUMP_SHADERVAR_MAPPINGS printf_stderr("[uniform block %i] %s/%i/%s/%s\n", i, mappedName.BeginReading(), (int)isArray, baseMappedName.BeginReading(), baseUserName.BeginReading()); printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull); printf_stderr(" isArray: %d\n", (int)isArray); #endif AddActiveBlockInfo(baseUserName, baseMappedName, &info->uniformBlocks); } } return info.forget(); }
void SpeechRecognition::Transition(SpeechEvent* aEvent) { switch (mCurrentState) { case STATE_IDLE: switch (aEvent->mType) { case EVENT_START: // TODO: may want to time out if we wait too long // for user to approve WaitForAudioData(aEvent); break; case EVENT_STOP: case EVENT_ABORT: case EVENT_AUDIO_DATA: case EVENT_RECOGNITIONSERVICE_INTERMEDIATE_RESULT: case EVENT_RECOGNITIONSERVICE_FINAL_RESULT: DoNothing(aEvent); break; case EVENT_AUDIO_ERROR: case EVENT_RECOGNITIONSERVICE_ERROR: AbortError(aEvent); break; case EVENT_COUNT: MOZ_CRASH("Invalid event EVENT_COUNT"); } break; case STATE_STARTING: switch (aEvent->mType) { case EVENT_AUDIO_DATA: StartedAudioCapture(aEvent); break; case EVENT_AUDIO_ERROR: case EVENT_RECOGNITIONSERVICE_ERROR: AbortError(aEvent); break; case EVENT_ABORT: AbortSilently(aEvent); break; case EVENT_STOP: Reset(); break; case EVENT_RECOGNITIONSERVICE_INTERMEDIATE_RESULT: case EVENT_RECOGNITIONSERVICE_FINAL_RESULT: DoNothing(aEvent); break; case EVENT_START: SR_LOG("STATE_STARTING: Unhandled event %s", GetName(aEvent)); MOZ_CRASH(); case EVENT_COUNT: MOZ_CRASH("Invalid event EVENT_COUNT"); } break; case STATE_ESTIMATING: switch (aEvent->mType) { case EVENT_AUDIO_DATA: WaitForEstimation(aEvent); break; case EVENT_STOP: StopRecordingAndRecognize(aEvent); break; case EVENT_ABORT: AbortSilently(aEvent); break; case EVENT_RECOGNITIONSERVICE_INTERMEDIATE_RESULT: case EVENT_RECOGNITIONSERVICE_FINAL_RESULT: case EVENT_RECOGNITIONSERVICE_ERROR: DoNothing(aEvent); break; case EVENT_AUDIO_ERROR: AbortError(aEvent); break; case EVENT_START: SR_LOG("STATE_ESTIMATING: Unhandled event %d", aEvent->mType); MOZ_CRASH(); case EVENT_COUNT: MOZ_CRASH("Invalid event EVENT_COUNT"); } break; case STATE_WAITING_FOR_SPEECH: switch (aEvent->mType) { case EVENT_AUDIO_DATA: DetectSpeech(aEvent); break; case EVENT_STOP: StopRecordingAndRecognize(aEvent); break; case EVENT_ABORT: AbortSilently(aEvent); break; case EVENT_AUDIO_ERROR: AbortError(aEvent); break; case EVENT_RECOGNITIONSERVICE_INTERMEDIATE_RESULT: case EVENT_RECOGNITIONSERVICE_FINAL_RESULT: case EVENT_RECOGNITIONSERVICE_ERROR: DoNothing(aEvent); break; case EVENT_START: SR_LOG("STATE_STARTING: Unhandled event %s", GetName(aEvent)); MOZ_CRASH(); case EVENT_COUNT: MOZ_CRASH("Invalid event EVENT_COUNT"); } break; case STATE_RECOGNIZING: switch (aEvent->mType) { case EVENT_AUDIO_DATA: WaitForSpeechEnd(aEvent); break; case EVENT_STOP: StopRecordingAndRecognize(aEvent); break; case EVENT_AUDIO_ERROR: case EVENT_RECOGNITIONSERVICE_ERROR: AbortError(aEvent); break; case EVENT_ABORT: AbortSilently(aEvent); break; case EVENT_RECOGNITIONSERVICE_FINAL_RESULT: case EVENT_RECOGNITIONSERVICE_INTERMEDIATE_RESULT: DoNothing(aEvent); break; case EVENT_START: SR_LOG("STATE_RECOGNIZING: Unhandled aEvent %s", GetName(aEvent)); MOZ_CRASH(); case EVENT_COUNT: MOZ_CRASH("Invalid event EVENT_COUNT"); } break; case STATE_WAITING_FOR_RESULT: switch (aEvent->mType) { case EVENT_STOP: DoNothing(aEvent); break; case EVENT_AUDIO_ERROR: case EVENT_RECOGNITIONSERVICE_ERROR: AbortError(aEvent); break; case EVENT_RECOGNITIONSERVICE_FINAL_RESULT: NotifyFinalResult(aEvent); break; case EVENT_AUDIO_DATA: DoNothing(aEvent); break; case EVENT_ABORT: AbortSilently(aEvent); break; case EVENT_START: case EVENT_RECOGNITIONSERVICE_INTERMEDIATE_RESULT: SR_LOG("STATE_WAITING_FOR_RESULT: Unhandled aEvent %s", GetName(aEvent)); MOZ_CRASH(); case EVENT_COUNT: MOZ_CRASH("Invalid event EVENT_COUNT"); } break; case STATE_COUNT: MOZ_CRASH("Invalid state STATE_COUNT"); } return; }
void ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) { gl->MakeCurrent(); MOZ_ASSERT(dest->GetSize() != gfxIntSize(0, 0)); /* gfxImageFormat::ARGB32: * RGBA+UByte: be[RGBA], le[ABGR] * RGBA+UInt: le[RGBA] * BGRA+UInt: le[BGRA] * BGRA+UIntRev: le[ARGB] * * gfxImageFormat::RGB16_565: * RGB+UShort: le[rrrrrggg,gggbbbbb] */ bool hasAlpha = dest->Format() == gfxImageFormat::ARGB32; int destPixelSize; GLenum destFormat; GLenum destType; switch (dest->Format()) { case gfxImageFormat::RGB24: // XRGB case gfxImageFormat::ARGB32: destPixelSize = 4; // Needs host (little) endian ARGB. destFormat = LOCAL_GL_BGRA; destType = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV; break; case gfxImageFormat::RGB16_565: destPixelSize = 2; destFormat = LOCAL_GL_RGB; destType = LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV; break; default: MOZ_CRASH("Bad format."); } MOZ_ASSERT(dest->Stride() == dest->Width() * destPixelSize); GLenum readFormat = destFormat; GLenum readType = destType; bool needsTempSurf = !GetActualReadFormats(gl, destFormat, destType, readFormat, readType); nsAutoPtr<gfxImageSurface> tempSurf; gfxImageSurface* readSurf = nullptr; int readPixelSize = 0; if (needsTempSurf) { if (gl->DebugMode()) { NS_WARNING("Needing intermediary surface for ReadPixels. This will be slow!"); } SurfaceFormat readFormatGFX; switch (readFormat) { case LOCAL_GL_RGBA: case LOCAL_GL_BGRA: { readFormatGFX = hasAlpha ? SurfaceFormat::B8G8R8A8 : SurfaceFormat::B8G8R8X8; break; } case LOCAL_GL_RGB: { MOZ_ASSERT(readPixelSize == 2); MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV); readFormatGFX = SurfaceFormat::R5G6B5; break; } default: { MOZ_CRASH("Bad read format."); } } switch (readType) { case LOCAL_GL_UNSIGNED_BYTE: { MOZ_ASSERT(readFormat == LOCAL_GL_RGBA); readPixelSize = 4; break; } case LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV: { MOZ_ASSERT(readFormat == LOCAL_GL_BGRA); readPixelSize = 4; break; } case LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV: { MOZ_ASSERT(readFormat == LOCAL_GL_RGB); readPixelSize = 2; break; } default: { MOZ_CRASH("Bad read type."); } } tempSurf = new gfxImageSurface(dest->GetSize(), SurfaceFormatToImageFormat(readFormatGFX), false); readSurf = tempSurf; } else { readPixelSize = destPixelSize; readSurf = dest; } MOZ_ASSERT(readPixelSize); GLint currentPackAlignment = 0; gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, ¤tPackAlignment); if (currentPackAlignment != readPixelSize) gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, readPixelSize); GLsizei width = dest->Width(); GLsizei height = dest->Height(); readSurf->Flush(); gl->fReadPixels(0, 0, width, height, readFormat, readType, readSurf->Data()); readSurf->MarkDirty(); if (currentPackAlignment != readPixelSize) gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment); if (readSurf != dest) { MOZ_ASSERT(readFormat == LOCAL_GL_RGBA); MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_BYTE); // So we just copied in RGBA in big endian, or le: 0xAABBGGRR. // We want 0xAARRGGBB, so swap R and B: dest->Flush(); RefPtr<DataSourceSurface> readDSurf = Factory::CreateWrappingDataSourceSurface(readSurf->Data(), readSurf->Stride(), ToIntSize(readSurf->GetSize()), ImageFormatToSurfaceFormat(readSurf->Format())); SwapRAndBComponents(readDSurf); dest->MarkDirty(); gfxContext ctx(dest); ctx.SetOperator(gfxContext::OPERATOR_SOURCE); ctx.SetSource(readSurf); ctx.Paint(); } // Check if GL is giving back 1.0 alpha for // RGBA reads to RGBA images from no-alpha buffers. #ifdef XP_MACOSX if (gl->WorkAroundDriverBugs() && gl->Vendor() == gl::GLVendor::NVIDIA && dest->Format() == gfxImageFormat::ARGB32 && width && height) { GLint alphaBits = 0; gl->fGetIntegerv(LOCAL_GL_ALPHA_BITS, &alphaBits); if (!alphaBits) { const uint32_t alphaMask = gfxPackedPixelNoPreMultiply(0xff,0,0,0); dest->Flush(); uint32_t* itr = (uint32_t*)dest->Data(); uint32_t testPixel = *itr; if ((testPixel & alphaMask) != alphaMask) { // We need to set the alpha channel to 1.0 manually. uint32_t* itrEnd = itr + width*height; // Stride is guaranteed to be width*4. for (; itr != itrEnd; itr++) { *itr |= alphaMask; } } dest->MarkDirty(); } } #endif }
JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) { if (IsContextLost()) return JS::NullValue(); MakeContextCurrent(); if (MinCapabilityMode()) { switch(pname) { //////////////////////////// // Single-value params // int case LOCAL_GL_MAX_VERTEX_ATTRIBS: return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_ATTRIBS); case LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS: return JS::Int32Value(MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS); case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS: return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS); case LOCAL_GL_MAX_VARYING_VECTORS: return JS::Int32Value(MINVALUE_GL_MAX_VARYING_VECTORS); case LOCAL_GL_MAX_TEXTURE_SIZE: return JS::Int32Value(MINVALUE_GL_MAX_TEXTURE_SIZE); case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE: return JS::Int32Value(MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE); case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS: return JS::Int32Value(MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS); case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS); case LOCAL_GL_MAX_RENDERBUFFER_SIZE: return JS::Int32Value(MINVALUE_GL_MAX_RENDERBUFFER_SIZE); default: // Return the real value; we're not overriding this one break; } } if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) { if (pname == LOCAL_GL_MAX_COLOR_ATTACHMENTS) { return JS::Int32Value(mImplMaxColorAttachments); } else if (pname == LOCAL_GL_MAX_DRAW_BUFFERS) { return JS::Int32Value(mImplMaxDrawBuffers); } else if (pname >= LOCAL_GL_DRAW_BUFFER0 && pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mImplMaxDrawBuffers)) { GLint iv = 0; gl->fGetIntegerv(pname, &iv); if (mBoundDrawFramebuffer) return JS::Int32Value(iv); const GLint index = (pname - LOCAL_GL_DRAW_BUFFER0); if (iv == LOCAL_GL_COLOR_ATTACHMENT0 + index) return JS::Int32Value(LOCAL_GL_BACK); return JS::Int32Value(LOCAL_GL_NONE); } } if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) { if (pname == LOCAL_GL_VERTEX_ARRAY_BINDING) { WebGLVertexArray* vao = (mBoundVertexArray != mDefaultVertexArray) ? mBoundVertexArray.get() : nullptr; return WebGLObjectAsJSValue(cx, vao, rv); } } if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) { if (pname == LOCAL_GL_TIMESTAMP_EXT) { GLuint64 iv = 0; gl->fGetInteger64v(pname, (GLint64*) &iv); // TODO: JS doesn't support 64-bit integers. Be lossy and // cast to double (53 bits) return JS::NumberValue(static_cast<double>(iv)); } else if (pname == LOCAL_GL_GPU_DISJOINT_EXT) { // When disjoint isn't supported, leave as false. realGLboolean disjoint = LOCAL_GL_FALSE; if (gl->IsExtensionSupported(gl::GLContext::EXT_disjoint_timer_query)) { gl->fGetBooleanv(pname, &disjoint); } return JS::BooleanValue(bool(disjoint)); } } // Privileged string params exposed by WEBGL_debug_renderer_info. // The privilege check is done in WebGLContext::IsExtensionSupported. // So here we just have to check that the extension is enabled. if (IsExtensionEnabled(WebGLExtensionID::WEBGL_debug_renderer_info)) { switch (pname) { case UNMASKED_VENDOR_WEBGL: case UNMASKED_RENDERER_WEBGL: { const char* overridePref = nullptr; GLenum driverEnum = LOCAL_GL_NONE; switch (pname) { case UNMASKED_RENDERER_WEBGL: overridePref = "webgl.renderer-string-override"; driverEnum = LOCAL_GL_RENDERER; break; case UNMASKED_VENDOR_WEBGL: overridePref = "webgl.vendor-string-override"; driverEnum = LOCAL_GL_VENDOR; break; default: MOZ_CRASH("bad `pname`"); } bool hasRetVal = false; nsAutoString ret; if (overridePref) { nsresult res = Preferences::GetString(overridePref, &ret); if (NS_SUCCEEDED(res) && ret.Length() > 0) hasRetVal = true; } if (!hasRetVal) { const char* chars = reinterpret_cast<const char*>(gl->fGetString(driverEnum)); ret = NS_ConvertASCIItoUTF16(chars); hasRetVal = true; } return StringValue(cx, ret, rv); } } } if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::OES_standard_derivatives)) { if (pname == LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT) { GLint i = 0; gl->fGetIntegerv(pname, &i); return JS::Int32Value(i); } } if (IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic)) { if (pname == LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) { GLfloat f = 0.f; gl->fGetFloatv(pname, &f); return JS::NumberValue(f); } } switch (pname) { // // String params // case LOCAL_GL_VENDOR: case LOCAL_GL_RENDERER: return StringValue(cx, "Mozilla", rv); case LOCAL_GL_VERSION: return StringValue(cx, "WebGL 1.0", rv); case LOCAL_GL_SHADING_LANGUAGE_VERSION: return StringValue(cx, "WebGL GLSL ES 1.0", rv); //////////////////////////////// // Single-value params // unsigned int case LOCAL_GL_CULL_FACE_MODE: case LOCAL_GL_FRONT_FACE: case LOCAL_GL_ACTIVE_TEXTURE: case LOCAL_GL_STENCIL_FUNC: case LOCAL_GL_STENCIL_FAIL: case LOCAL_GL_STENCIL_PASS_DEPTH_FAIL: case LOCAL_GL_STENCIL_PASS_DEPTH_PASS: case LOCAL_GL_STENCIL_BACK_FUNC: case LOCAL_GL_STENCIL_BACK_FAIL: case LOCAL_GL_STENCIL_BACK_PASS_DEPTH_FAIL: case LOCAL_GL_STENCIL_BACK_PASS_DEPTH_PASS: case LOCAL_GL_DEPTH_FUNC: case LOCAL_GL_BLEND_SRC_RGB: case LOCAL_GL_BLEND_SRC_ALPHA: case LOCAL_GL_BLEND_DST_RGB: case LOCAL_GL_BLEND_DST_ALPHA: case LOCAL_GL_BLEND_EQUATION_RGB: case LOCAL_GL_BLEND_EQUATION_ALPHA: case LOCAL_GL_GENERATE_MIPMAP_HINT: { GLint i = 0; gl->fGetIntegerv(pname, &i); return JS::NumberValue(uint32_t(i)); } case LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE: { if (mBoundReadFramebuffer) { nsCString fbStatusInfoIgnored; const auto status = mBoundReadFramebuffer->CheckFramebufferStatus(&fbStatusInfoIgnored); if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) { ErrorInvalidOperation("getParameter: Read framebuffer must be" " complete before querying" " IMPLEMENTATION_COLOR_READ_TYPE."); return JS::NullValue(); } } GLint i = 0; if (gl->IsSupported(gl::GLFeature::ES2_compatibility)) { gl->fGetIntegerv(pname, &i); } else { i = LOCAL_GL_UNSIGNED_BYTE; } return JS::NumberValue(uint32_t(i)); } case LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT: { if (mBoundReadFramebuffer) { nsCString fbStatusInfoIgnored; const auto status = mBoundReadFramebuffer->CheckFramebufferStatus(&fbStatusInfoIgnored); if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) { ErrorInvalidOperation("getParameter: Read framebuffer must be" " complete before querying" " IMPLEMENTATION_COLOR_READ_FORMAT."); return JS::NullValue(); } } GLint i = 0; if (gl->IsSupported(gl::GLFeature::ES2_compatibility)) { gl->fGetIntegerv(pname, &i); } else { i = LOCAL_GL_RGBA; } // OpenGL ES 3.0.4 p112 Table 3.2 shows that read format SRGB_ALPHA is // not supported. And if internal format of fbo is SRGB8_ALPHA8, then // IMPLEMENTATION_COLOR_READ_FORMAT is SRGB_ALPHA which is not supported // by ReadPixels. So, just return RGBA here. if (i == LOCAL_GL_SRGB_ALPHA) i = LOCAL_GL_RGBA; return JS::NumberValue(uint32_t(i)); } // int case LOCAL_GL_STENCIL_REF: case LOCAL_GL_STENCIL_BACK_REF: { GLint stencilBits = 0; if (!GetStencilBits(&stencilBits)) return JS::NullValue(); // Assuming stencils have 8 bits const GLint stencilMask = (1 << stencilBits) - 1; GLint refValue = 0; gl->fGetIntegerv(pname, &refValue); return JS::Int32Value(refValue & stencilMask); } case LOCAL_GL_STENCIL_BITS: { GLint stencilBits = 0; GetStencilBits(&stencilBits); return JS::Int32Value(stencilBits); } case LOCAL_GL_STENCIL_CLEAR_VALUE: case LOCAL_GL_UNPACK_ALIGNMENT: case LOCAL_GL_PACK_ALIGNMENT: case LOCAL_GL_SUBPIXEL_BITS: case LOCAL_GL_SAMPLE_BUFFERS: case LOCAL_GL_SAMPLES: case LOCAL_GL_MAX_VERTEX_ATTRIBS: case LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS: case LOCAL_GL_RED_BITS: case LOCAL_GL_GREEN_BITS: case LOCAL_GL_BLUE_BITS: { GLint i = 0; gl->fGetIntegerv(pname, &i); return JS::Int32Value(i); } case LOCAL_GL_DEPTH_BITS: { GLint i = 0; if (!mNeedsFakeNoDepth) { gl->fGetIntegerv(pname, &i); } return JS::Int32Value(i); } case LOCAL_GL_ALPHA_BITS: { GLint i = 0; if (!mNeedsFakeNoAlpha) { gl->fGetIntegerv(pname, &i); } return JS::Int32Value(i); } case LOCAL_GL_MAX_TEXTURE_SIZE: return JS::Int32Value(mImplMaxTextureSize); case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE: return JS::Int32Value(mImplMaxCubeMapTextureSize); case LOCAL_GL_MAX_RENDERBUFFER_SIZE: return JS::Int32Value(mImplMaxRenderbufferSize); case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS: return JS::Int32Value(mGLMaxVertexUniformVectors); case LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS: return JS::Int32Value(mGLMaxFragmentUniformVectors); case LOCAL_GL_MAX_VARYING_VECTORS: return JS::Int32Value(mGLMaxVaryingVectors); case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS: { uint32_t length = mCompressedTextureFormats.Length(); JSObject* obj = dom::Uint32Array::Create(cx, this, length, mCompressedTextureFormats.Elements()); if (!obj) { rv = NS_ERROR_OUT_OF_MEMORY; } return JS::ObjectOrNullValue(obj); } // unsigned int. here we may have to return very large values like 2^32-1 that can't be represented as // javascript integer values. We just return them as doubles and javascript doesn't care. case LOCAL_GL_STENCIL_BACK_VALUE_MASK: return JS::DoubleValue(mStencilValueMaskBack); // pass as FP value to allow large values such as 2^32-1. case LOCAL_GL_STENCIL_BACK_WRITEMASK: return JS::DoubleValue(mStencilWriteMaskBack); case LOCAL_GL_STENCIL_VALUE_MASK: return JS::DoubleValue(mStencilValueMaskFront); case LOCAL_GL_STENCIL_WRITEMASK: return JS::DoubleValue(mStencilWriteMaskFront); // float case LOCAL_GL_DEPTH_CLEAR_VALUE: case LOCAL_GL_LINE_WIDTH: case LOCAL_GL_POLYGON_OFFSET_FACTOR: case LOCAL_GL_POLYGON_OFFSET_UNITS: case LOCAL_GL_SAMPLE_COVERAGE_VALUE: { GLfloat f = 0.f; gl->fGetFloatv(pname, &f); return JS::DoubleValue(f); } // bool case LOCAL_GL_BLEND: case LOCAL_GL_DEPTH_TEST: case LOCAL_GL_STENCIL_TEST: case LOCAL_GL_CULL_FACE: case LOCAL_GL_DITHER: case LOCAL_GL_POLYGON_OFFSET_FILL: case LOCAL_GL_SCISSOR_TEST: case LOCAL_GL_SAMPLE_COVERAGE_INVERT: case LOCAL_GL_DEPTH_WRITEMASK: { realGLboolean b = 0; gl->fGetBooleanv(pname, &b); return JS::BooleanValue(bool(b)); } // bool, WebGL-specific case UNPACK_FLIP_Y_WEBGL: return JS::BooleanValue(mPixelStore_FlipY); case UNPACK_PREMULTIPLY_ALPHA_WEBGL: return JS::BooleanValue(mPixelStore_PremultiplyAlpha); // uint, WebGL-specific case UNPACK_COLORSPACE_CONVERSION_WEBGL: return JS::NumberValue(uint32_t(mPixelStore_ColorspaceConversion)); //////////////////////////////// // Complex values // 2 floats case LOCAL_GL_DEPTH_RANGE: case LOCAL_GL_ALIASED_POINT_SIZE_RANGE: case LOCAL_GL_ALIASED_LINE_WIDTH_RANGE: { GLfloat fv[2] = { 0 }; gl->fGetFloatv(pname, fv); JSObject* obj = dom::Float32Array::Create(cx, this, 2, fv); if (!obj) { rv = NS_ERROR_OUT_OF_MEMORY; } return JS::ObjectOrNullValue(obj); } // 4 floats case LOCAL_GL_COLOR_CLEAR_VALUE: case LOCAL_GL_BLEND_COLOR: { GLfloat fv[4] = { 0 }; gl->fGetFloatv(pname, fv); JSObject* obj = dom::Float32Array::Create(cx, this, 4, fv); if (!obj) { rv = NS_ERROR_OUT_OF_MEMORY; } return JS::ObjectOrNullValue(obj); } // 2 ints case LOCAL_GL_MAX_VIEWPORT_DIMS: { GLint iv[2] = { 0 }; gl->fGetIntegerv(pname, iv); JSObject* obj = dom::Int32Array::Create(cx, this, 2, iv); if (!obj) { rv = NS_ERROR_OUT_OF_MEMORY; } return JS::ObjectOrNullValue(obj); } // 4 ints case LOCAL_GL_SCISSOR_BOX: case LOCAL_GL_VIEWPORT: { GLint iv[4] = { 0 }; gl->fGetIntegerv(pname, iv); JSObject* obj = dom::Int32Array::Create(cx, this, 4, iv); if (!obj) { rv = NS_ERROR_OUT_OF_MEMORY; } return JS::ObjectOrNullValue(obj); } // 4 bools case LOCAL_GL_COLOR_WRITEMASK: { realGLboolean gl_bv[4] = { 0 }; gl->fGetBooleanv(pname, gl_bv); bool vals[4] = { bool(gl_bv[0]), bool(gl_bv[1]), bool(gl_bv[2]), bool(gl_bv[3]) }; JS::Rooted<JS::Value> arr(cx); if (!dom::ToJSValue(cx, vals, &arr)) { rv = NS_ERROR_OUT_OF_MEMORY; } return arr; } case LOCAL_GL_ARRAY_BUFFER_BINDING: { return WebGLObjectAsJSValue(cx, mBoundArrayBuffer.get(), rv); } case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING: { return WebGLObjectAsJSValue(cx, mBoundVertexArray->mElementArrayBuffer.get(), rv); } case LOCAL_GL_RENDERBUFFER_BINDING: { return WebGLObjectAsJSValue(cx, mBoundRenderbuffer.get(), rv); } // DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING. case LOCAL_GL_FRAMEBUFFER_BINDING: { return WebGLObjectAsJSValue(cx, mBoundDrawFramebuffer.get(), rv); } case LOCAL_GL_CURRENT_PROGRAM: { return WebGLObjectAsJSValue(cx, mCurrentProgram.get(), rv); } case LOCAL_GL_TEXTURE_BINDING_2D: { return WebGLObjectAsJSValue(cx, mBound2DTextures[mActiveTexture].get(), rv); } case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP: { return WebGLObjectAsJSValue(cx, mBoundCubeMapTextures[mActiveTexture].get(), rv); } default: break; } ErrorInvalidEnumInfo("getParameter: parameter", pname); return JS::NullValue(); }