Bug 1135883 - Implement GetMaxTextureSize in the basic compositor. r=mattwoodrow, a=lsblakk
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -1147,16 +1147,18 @@ public:
static TemporaryRef<DrawEventRecorder>
CreateEventRecorderForFile(const char *aFilename);
static void SetGlobalEventRecorder(DrawEventRecorder *aRecorder);
// This is a little hacky at the moment, but we want to have this data. Bug 1068613.
static void SetLogForwarder(LogForwarder* aLogFwd);
+ static uint32_t GetMaxSurfaceSize(BackendType aType);
+
static LogForwarder* GetLogForwarder() { return mLogForwarder; }
private:
static LogForwarder* mLogForwarder;
public:
#ifdef USE_SKIA_GPU
static TemporaryRef<DrawTarget>
--- a/gfx/2d/DrawTargetCG.cpp
+++ b/gfx/2d/DrawTargetCG.cpp
@@ -1516,20 +1516,21 @@ bool
DrawTargetCG::Init(BackendType aType,
unsigned char* aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat)
{
// XXX: we should come up with some consistent semantics for dealing
// with zero area drawtargets
- if (aSize.width <= 0 || aSize.height <= 0 ||
- // 32767 is the maximum size supported by cairo
- // we clamp to that to make it easier to interoperate
- aSize.width > 32767 || aSize.height > 32767) {
+ if (aSize.width <= 0 ||
+ aSize.height <= 0 ||
+ aSize.width > GetMaxSurfaceSize() ||
+ aSize.height > GetMaxSurfaceSize())
+ {
gfxWarning() << "Failed to Init() DrawTargetCG because of bad size.";
mColorSpace = nullptr;
mCg = nullptr;
return false;
}
//XXX: handle SurfaceFormat
--- a/gfx/2d/DrawTargetCG.h
+++ b/gfx/2d/DrawTargetCG.h
@@ -178,16 +178,23 @@ public:
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const MOZ_OVERRIDE;
virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const MOZ_OVERRIDE;
CGContextRef GetCGContext() {
return mCg;
}
+
+ // 32767 is the maximum size supported by cairo. We clamp to that to make it
+ // easier to interoperate.
+ static size_t GetMaxSurfaceSize() {
+ return 32767;
+ }
+
private:
void MarkChanged();
IntSize mSize;
CGColorSpaceRef mColorSpace;
CGContextRef mCg;
/**
--- a/gfx/2d/DrawTargetCairo.h
+++ b/gfx/2d/DrawTargetCairo.h
@@ -165,16 +165,21 @@ public:
// Call to set up aContext for drawing (with the current transform, etc).
// Pass the path you're going to be using if you have one.
// Implicitly calls WillChange(aPath).
void PrepareForDrawing(cairo_t* aContext, const Path* aPath = nullptr);
static cairo_surface_t *GetDummySurface();
+ // Cairo hardcodes this as its maximum surface size.
+ static size_t GetMaxSurfaceSize() {
+ return 32767;
+ }
+
private: // methods
// Init cairo surface without doing a cairo_surface_reference() call.
bool InitAlreadyReferenced(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr);
enum DrawPatternType { DRAW_FILL, DRAW_STROKE };
void DrawPattern(const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions,
DrawPatternType aDrawType,
--- a/gfx/2d/DrawTargetD2D.h
+++ b/gfx/2d/DrawTargetD2D.h
@@ -144,16 +144,20 @@ public:
TemporaryRef<ID2D1Image> GetImageForSurface(SourceSurface *aSurface);
static ID2D1Factory *factory();
static void CleanupD2D();
static IDWriteFactory *GetDWriteFactory();
ID2D1RenderTarget *GetRT() { return mRT; }
+ static uint32_t GetMaxSurfaceSize() {
+ return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+ }
+
operator std::string() const {
std::stringstream stream;
stream << "DrawTargetD2D(" << this << ")";
return stream.str();
}
static uint64_t mVRAMUsageDT;
static uint64_t mVRAMUsageSS;
--- a/gfx/2d/DrawTargetD2D1.h
+++ b/gfx/2d/DrawTargetD2D1.h
@@ -143,16 +143,20 @@ public:
static IDWriteFactory *GetDWriteFactory();
operator std::string() const {
std::stringstream stream;
stream << "DrawTargetD2D 1.1 (" << this << ")";
return stream.str();
}
+ static uint32_t GetMaxSurfaceSize() {
+ return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+ }
+
static uint64_t mVRAMUsageDT;
static uint64_t mVRAMUsageSS;
private:
friend class SourceSurfaceD2D1;
#ifdef _MSC_VER
typedef stdext::hash_set<DrawTargetD2D1*> TargetSet;
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -444,16 +444,40 @@ Factory::DoesBackendSupportDataDrawtarge
case BackendType::COREGRAPHICS:
case BackendType::SKIA:
return true;
}
return false;
}
+uint32_t
+Factory::GetMaxSurfaceSize(BackendType aType)
+{
+ switch (aType) {
+ case BackendType::CAIRO:
+ case BackendType::COREGRAPHICS:
+ return DrawTargetCairo::GetMaxSurfaceSize();
+#ifdef XP_MACOSX
+ case BackendType::COREGRAPHICS_ACCELERATED:
+ return DrawTargetCG::GetMaxSurfaceSize();
+#endif
+ case BackendType::SKIA:
+ return INT_MAX;
+#ifdef WIN32
+ case BackendType::DIRECT2D:
+ return DrawTargetD2D::GetMaxSurfaceSize();
+ case BackendType::DIRECT2D1_1:
+ return DrawTargetD2D1::GetMaxSurfaceSize();
+#endif
+ default:
+ return 0;
+ }
+}
+
TemporaryRef<ScaledFont>
Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize)
{
switch (aNativeFont.mType) {
#ifdef WIN32
case NativeFontType::DWRITE_FONT_FACE:
{
return new ScaledFontDWrite(static_cast<IDWriteFontFace*>(aNativeFont.mFont), aSize);
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -64,23 +64,32 @@ public:
RefPtr<gfx::DataSourceSurface> mSurface;
};
BasicCompositor::BasicCompositor(nsIWidget *aWidget)
: mWidget(aWidget)
{
MOZ_COUNT_CTOR(BasicCompositor);
SetBackend(LayersBackend::LAYERS_BASIC);
+
+ mMaxTextureSize =
+ Factory::GetMaxSurfaceSize(gfxPlatform::GetPlatform()->GetContentBackend());
}
BasicCompositor::~BasicCompositor()
{
MOZ_COUNT_DTOR(BasicCompositor);
}
+int32_t
+BasicCompositor::GetMaxTextureSize() const
+{
+ return mMaxTextureSize;
+}
+
void
BasicCompositingRenderTarget::BindRenderTarget()
{
if (mClearOnBind) {
mDrawTarget->ClearRect(Rect(0, 0, mSize.width, mSize.height));
mClearOnBind = false;
}
}
--- a/gfx/layers/basic/BasicCompositor.h
+++ b/gfx/layers/basic/BasicCompositor.h
@@ -98,17 +98,17 @@ public:
virtual void EndFrame() MOZ_OVERRIDE;
virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) MOZ_OVERRIDE
{
NS_RUNTIMEABORT("We shouldn't ever hit this");
}
virtual bool SupportsPartialTextureUpdate() MOZ_OVERRIDE { return true; }
virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) MOZ_OVERRIDE { return true; }
- virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE { return INT32_MAX; }
+ virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE;
virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) MOZ_OVERRIDE { }
virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) MOZ_OVERRIDE {
}
virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) MOZ_OVERRIDE { }
virtual void PrepareViewport(const gfx::IntSize& aSize) MOZ_OVERRIDE { }
@@ -135,14 +135,16 @@ private:
// The final destination surface
RefPtr<gfx::DrawTarget> mDrawTarget;
// The current render target for drawing
RefPtr<BasicCompositingRenderTarget> mRenderTarget;
gfx::IntRect mInvalidRect;
nsIntRegion mInvalidRegion;
+
+ uint32_t mMaxTextureSize;
};
} // namespace layers
} // namespace mozilla
#endif /* MOZILLA_GFX_BASICCOMPOSITOR_H */
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -740,17 +740,17 @@ BufferTextureClient::AllocateForSurface(
MOZ_ASSERT(aSize.width > 0 && aSize.height > 0);
if (aSize.width <= 0 || aSize.height <= 0) {
gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x" << aSize.height;
return false;
}
uint32_t bufSize = ImageDataSerializer::ComputeMinBufferSize(aSize, mFormat);
- if (!Allocate(bufSize)) {
+ if (!bufSize || !Allocate(bufSize)) {
return false;
}
if (aFlags & ALLOC_CLEAR_BUFFER) {
memset(GetBuffer(), 0, bufSize);
}
if (aFlags & ALLOC_CLEAR_BUFFER_WHITE) {
memset(GetBuffer(), 0xFF, bufSize);