Bug 1101685 - Optionally assert in loggers, default to true on gfxCriticalError. Clean up the calls where large texture sizes were triggering the asserts in tests. r=nical

This commit is contained in:
Milan Sreckovic 2014-12-17 17:54:04 -05:00
Родитель 29d0ae087c
Коммит 8445ba0749
7 изменённых файлов: 96 добавлений и 31 удалений

Просмотреть файл

@ -1075,6 +1075,11 @@ public:
*/
static bool CheckSurfaceSize(const IntSize &sz, int32_t limit = 0);
/** Make sure the given dimension satisfies the CheckSurfaceSize and is
* within 8k limit. The 8k value is chosen a bit randomly.
*/
static bool ReasonableSurfaceSize(const IntSize &aSize);
static TemporaryRef<DrawTarget> CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr);
static TemporaryRef<DrawTarget>

Просмотреть файл

@ -1484,7 +1484,7 @@ DrawTargetCairo::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFo
}
}
gfxCriticalError() << "Failed to create similar cairo surface! Size: " << aSize << " Status: " << cairo_surface_status(similar);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "Failed to create similar cairo surface! Size: " << aSize << " Status: " << cairo_surface_status(similar);
return nullptr;
}

Просмотреть файл

@ -76,7 +76,7 @@ public:
HRESULT hr = mDT->mDevice->CreateTexture2D(&desc, nullptr, byRef(tmpTexture));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D] CreateTexture2D failure " << size << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(size))) << "[D2D] 1 CreateTexture2D failure " << size << " Code: " << hexa(hr);
return;
}
mDT->mDevice->CopyResource(tmpTexture, mDT->mTexture);
@ -531,7 +531,7 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
hr = mDevice->CreateTexture2D(&desc, nullptr, byRef(mipTexture));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D] CreateTexture2D failure " << aSurface->GetSize() << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSurface->GetSize()))) << "[D2D] 2 CreateTexture2D failure " << aSurface->GetSize() << " Code: " << hexa(hr);
return;
}
@ -558,7 +558,7 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
hr = mDevice->CreateTexture2D(&desc, nullptr, byRef(tmpDSTexture));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D] CreateTexture2D failure " << dsSize << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(dsSize))) << "[D2D] 3 CreateTexture2D failure " << dsSize << " Code: " << hexa(hr);
return;
}
@ -1361,7 +1361,7 @@ DrawTargetD2D::Init(const IntSize &aSize, SurfaceFormat aFormat)
hr = mDevice->CreateTexture2D(&desc, nullptr, byRef(mTexture));
if (FAILED(hr)) {
gfxCriticalError() << "Failed to init Direct2D DrawTarget. Size: " << mSize << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "Failed to init Direct2D DrawTarget. Size: " << mSize << " Code: " << hexa(hr);
return false;
}

Просмотреть файл

@ -653,7 +653,7 @@ DrawTargetD2D1::CreateSourceSurfaceFromData(unsigned char *aData,
byRef(bitmap));
if (FAILED(hr) || !bitmap) {
gfxCriticalError() << "[D2D1.1] CreateBitmap failure " << aSize << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D2D1.1] 1CreateBitmap failure " << aSize << " Code: " << hexa(hr);
return nullptr;
}
@ -742,7 +742,7 @@ DrawTargetD2D1::Init(ID3D11Texture2D* aTexture, SurfaceFormat aFormat)
hr = Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC));
if (FAILED(hr)) {
gfxCriticalError() <<"[D2D1.1] Failed to create a DeviceContext, code: " << hexa(hr);
gfxCriticalError() <<"[D2D1.1] 1Failed to create a DeviceContext, code: " << hexa(hr);
return false;
}
@ -779,7 +779,7 @@ DrawTargetD2D1::Init(ID3D11Texture2D* aTexture, SurfaceFormat aFormat)
hr = mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mTempBitmap));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D1.1] CreateBitmap failure " << mSize << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(mSize))) << "[D2D1.1] 2CreateBitmap failure " << mSize << " Code: " << hexa(hr);
return false;
}
@ -797,14 +797,14 @@ DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat)
hr = Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC));
if (FAILED(hr)) {
gfxCriticalError() <<"[D2D1.1] Failed to create a DeviceContext, code: " << hexa(hr);
gfxCriticalError() <<"[D2D1.1] 2Failed to create a DeviceContext, code: " << hexa(hr);
return false;
}
if (mDC->GetMaximumBitmapSize() < UINT32(aSize.width) ||
mDC->GetMaximumBitmapSize() < UINT32(aSize.height)) {
// This is 'ok'
gfxCriticalError() << "[D2D1.1] Attempt to use unsupported surface size " << aSize;
// This is 'ok', so don't assert
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "[D2D1.1] Attempt to use unsupported surface size " << aSize;
return false;
}
@ -817,7 +817,7 @@ DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat)
hr = mDC->CreateBitmap(D2DIntSize(aSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mBitmap));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D1.1] CreateBitmap failure " << aSize << " Code: " << hexa(hr);
gfxCriticalError() << "[D2D1.1] 3CreateBitmap failure " << aSize << " Code: " << hexa(hr);
return false;
}
@ -1345,7 +1345,7 @@ DrawTargetD2D1::OptimizeSourceSurface(SourceSurface* aSurface) const
byRef(bitmap));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D1.1] CreateBitmap failure " << data->GetSize() << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(data->GetSize()))) << "[D2D1.1] 4CreateBitmap failure " << data->GetSize() << " Code: " << hexa(hr);
}
data->Unmap();

Просмотреть файл

@ -216,11 +216,24 @@ Factory::HasSSE2()
#endif
}
// If the size is "reasonable", we want gfxCriticalError to assert, so
// this is the option set up for it.
inline int LoggerOptionsBasedOnSize(const IntSize& aSize)
{
return CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize));
}
bool
Factory::ReasonableSurfaceSize(const IntSize &aSize)
{
return Factory::CheckSurfaceSize(aSize,8192);
}
bool
Factory::CheckSurfaceSize(const IntSize &sz, int32_t limit)
{
if (sz.width < 0 || sz.height < 0) {
gfxDebug() << "Surface width or height < 0!";
if (sz.width <= 0 || sz.height <= 0) {
gfxDebug() << "Surface width or height <= 0!";
return false;
}
@ -265,7 +278,7 @@ TemporaryRef<DrawTarget>
Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat)
{
if (!CheckSurfaceSize(aSize)) {
gfxCriticalError() << "Failed to allocate a surface due to invalid size " << aSize;
gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "Failed to allocate a surface due to invalid size " << aSize;
return nullptr;
}
@ -337,9 +350,9 @@ Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFor
if (!retVal) {
// Failed
gfxCriticalError() << "Failed to create DrawTarget, Type: " << int(aBackend) << " Size: " << aSize;
gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "Failed to create DrawTarget, Type: " << int(aBackend) << " Size: " << aSize;
}
return retVal.forget();
}
@ -350,15 +363,15 @@ Factory::CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT
}
TemporaryRef<DrawTarget>
Factory::CreateDrawTargetForData(BackendType aBackend,
unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
Factory::CreateDrawTargetForData(BackendType aBackend,
unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat)
{
MOZ_ASSERT(aData);
if (!CheckSurfaceSize(aSize)) {
gfxCriticalError() << "Failed to allocate a surface due to invalid size " << aSize;
gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "Failed to allocate a surface due to invalid size " << aSize;
return nullptr;
}
@ -786,7 +799,7 @@ Factory::CreateDataSourceSurface(const IntSize &aSize,
bool aZero)
{
if (!CheckSurfaceSize(aSize)) {
gfxCriticalError() << "Failed to allocate a surface due to invalid size " << aSize;
gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "Failed to allocate a surface due to invalid size " << aSize;
return nullptr;
}
@ -806,7 +819,7 @@ Factory::CreateDataSourceSurfaceWithStride(const IntSize &aSize,
bool aZero)
{
if (aStride < aSize.width * BytesPerPixel(aFormat)) {
gfxCriticalError() << "CreateDataSourceSurfaceWithStride failed with bad stride";
gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "CreateDataSourceSurfaceWithStride failed with bad stride " << aStride << ", " << aSize << ", " << aFormat;
return nullptr;
}
@ -815,7 +828,7 @@ Factory::CreateDataSourceSurfaceWithStride(const IntSize &aSize,
return newSurf.forget();
}
gfxCriticalError() << "CreateDataSourceSurfaceWithStride failed to initialize";
gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "CreateDataSourceSurfaceWithStride failed to initialize " << aSize << ", " << aFormat << ", " << aStride << ", " << aZero;
return nullptr;
}

Просмотреть файл

@ -112,6 +112,34 @@ private:
static PreferenceAccess* sAccess;
};
/// Graphics logging is available in both debug and release builds and is
/// controlled with a gfx.logging.level preference. If not set, the default
/// for the preference is 5 in the debug builds, 1 in the release builds.
///
/// gfxDebug only works in the debug builds, and is used for information
/// level messages, helping with debugging. In addition to only working
/// in the debug builds, the value of the above preference of 3 or higher
/// is required.
///
/// gfxWarning messages are available in both debug and release builds,
/// on by default in the debug builds, and off by default in the release builds.
/// Setting the preference gfx.logging.level to a value of 2 or higher will
/// show the warnings.
///
/// gfxCriticalError is available in debug and release builds by default.
/// It is only unavailable if gfx.logging.level is set to 0 (or less.)
/// It outputs the message to stderr or equivalent, like gfxWarning.
/// In the event of a crash, the crash report is annotated with first and
/// the last few of these errors, under the key GraphicsCriticalError.
/// The total number of errors stored in the crash report is controlled
/// by preference gfx.logging.crash.length (default is six, so by default,
/// the first as well as the last five would show up in the crash log.)
///
/// On platforms that support PR_LOGGING, the story is slightly more involved.
/// In that case, unless gfx.logging.level is set to 4 or higher, the output
/// is further controlled by "gfx2d" PR logging module. However, in the case
/// where such module would disable the output, in all but gfxDebug cases,
/// we will still send a printf.
struct BasicLogger
{
// For efficiency, this method exists and copies the logic of the
@ -192,7 +220,8 @@ public:
MOZ_BEGIN_ENUM_CLASS(LogOptions, int)
NoNewline = 0x01,
AutoPrefix = 0x02
AutoPrefix = 0x02,
AssertOnCall = 0x04
MOZ_END_ENUM_CLASS(LogOptions)
template<typename T>
@ -207,12 +236,27 @@ template<int L, typename Logger = BasicLogger>
class Log
{
public:
explicit Log(int aOptions = (int)LogOptions::AutoPrefix)
// The default is to have the prefix, have the new line, and for critical
// logs assert on each call.
static int DefaultOptions(bool aWithAssert = true) {
return (int(LogOptions::AutoPrefix) |
(aWithAssert ? int(LogOptions::AssertOnCall) : 0));
}
// Note that we're calling BasicLogger::ShouldOutputMessage, rather than
// Logger::ShouldOutputMessage. Since we currently don't have a different
// version of that method for different loggers, this is OK. Once we do,
// change BasicLogger::ShouldOutputMessage to Logger::ShouldOutputMessage.
explicit Log(int aOptions = Log::DefaultOptions(L == LOG_CRITICAL))
: mOptions(aOptions)
, mLogIt(BasicLogger::ShouldOutputMessage(L))
{
if (mLogIt && AutoPrefix()) {
mMessage << "[GFX" << L << "]: ";
if (mOptions & int(LogOptions::AssertOnCall)) {
mMessage << "[GFX" << L << "]: ";
} else {
mMessage << "[GFX" << L << "-]: ";
}
}
}
~Log() {
@ -433,6 +477,9 @@ private:
void WriteLog(const std::string &aString) {
if (MOZ_UNLIKELY(LogIt())) {
Logger::OutputMessage(aString, L, NoNewline());
if (mOptions & int(LogOptions::AssertOnCall)) {
MOZ_ASSERT(false, "An assert from the graphics logger");
}
}
}

Просмотреть файл

@ -306,7 +306,7 @@ TextureClientD3D11::Unlock()
HRESULT hr = device->CreateTexture2D(&desc, nullptr, byRef(tex));
if (FAILED(hr)) {
gfxCriticalError() << "[D3D11] CreateTexture2D failure " << mSize << " Code: " << gfx::hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(mSize))) << "[D3D11] CreateTexture2D failure " << mSize << " Code: " << gfx::hexa(hr);
return;
}
@ -394,7 +394,7 @@ TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlag
}
if (FAILED(hr)) {
gfxCriticalError() << "[D3D11] CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D3D11] 2 CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr);
return false;
}