void gfxQuartzNativeDrawing::EndNativeDrawing() { NS_ASSERTION(mCGContext, "EndNativeDrawing called without BeginNativeDrawing"); MOZ_ASSERT(!mContext->IsCairo(), "BeginNativeDrawing succeeded with cairo context?"); mBorrowedContext.Finish(); if (mDrawTarget) { DrawTarget *dest = mContext->GetDrawTarget(); RefPtr<SourceSurface> source = mDrawTarget->Snapshot(); IntSize backingSize(NSToIntFloor(mNativeRect.width * mBackingScale), NSToIntFloor(mNativeRect.height * mBackingScale)); Matrix oldTransform = dest->GetTransform(); Matrix newTransform = oldTransform; newTransform.Translate(mNativeRect.x, mNativeRect.y); newTransform.Scale(1.0f / mBackingScale, 1.0f / mBackingScale); dest->SetTransform(newTransform); dest->DrawSurface(source, gfx::Rect(0, 0, backingSize.width, backingSize.height), gfx::Rect(0, 0, backingSize.width, backingSize.height)); dest->SetTransform(oldTransform); } }
void DrawBlur(gfxContext* aDestinationCtx, SourceSurface* aBlur, const IntPoint& aTopLeft, const Rect* aDirtyRect) { DrawTarget *dest = aDestinationCtx->GetDrawTarget(); nsRefPtr<gfxPattern> thebesPat = aDestinationCtx->GetPattern(); Pattern* pat = thebesPat->GetPattern(dest, nullptr); Matrix oldTransform = dest->GetTransform(); Matrix newTransform = oldTransform; newTransform.Translate(aTopLeft.x, aTopLeft.y); // Avoid a semi-expensive clip operation if we can, otherwise // clip to the dirty rect if (aDirtyRect) { dest->PushClipRect(*aDirtyRect); } dest->SetTransform(newTransform); dest->MaskSurface(*pat, aBlur, Point(0, 0)); dest->SetTransform(oldTransform); if (aDirtyRect) { dest->PopClip(); } }
void ClientLayerManager::MakeSnapshotIfRequired() { if (!mShadowTarget) { return; } if (mWidget) { if (CompositorBridgeChild* remoteRenderer = GetRemoteRenderer()) { // The compositor doesn't draw to a different sized surface // when there's a rotation. Instead we rotate the result // when drawing into dt LayoutDeviceIntRect outerBounds; mWidget->GetBounds(outerBounds); IntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents()); if (mTargetRotation) { bounds = RotateRect(bounds, outerBounds.ToUnknownRect(), mTargetRotation); } SurfaceDescriptor inSnapshot; if (!bounds.IsEmpty() && mForwarder->AllocSurfaceDescriptor(bounds.Size(), gfxContentType::COLOR_ALPHA, &inSnapshot)) { // Make a copy of |inSnapshot| because the call to send it over IPC // will call forget() on the Shmem inside, and zero it out. SurfaceDescriptor outSnapshot = inSnapshot; if (remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) { RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(outSnapshot); DrawTarget* dt = mShadowTarget->GetDrawTarget(); Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height); Rect srcRect(0, 0, bounds.width, bounds.height); gfx::Matrix rotate = ComputeTransformForUnRotation(outerBounds.ToUnknownRect(), mTargetRotation); gfx::Matrix oldMatrix = dt->GetTransform(); dt->SetTransform(rotate * oldMatrix); dt->DrawSurface(surf, dstRect, srcRect, DrawSurfaceOptions(), DrawOptions(1.0f, CompositionOp::OP_OVER)); dt->SetTransform(oldMatrix); } mForwarder->DestroySurfaceDescriptor(&outSnapshot); } } } mShadowTarget = nullptr; }
virtual void ProcessReadback(gfx::DataSourceSurface *aSourceSurface) { SourceRotatedBuffer rotBuffer(aSourceSurface, nullptr, mBufferRect, mBufferRotation); for (uint32_t i = 0; i < mReadbackUpdates.Length(); ++i) { ReadbackProcessor::Update& update = mReadbackUpdates[i]; nsIntPoint offset = update.mLayer->GetBackgroundLayerOffset(); ReadbackSink* sink = update.mLayer->GetSink(); if (!sink) { continue; } if (!aSourceSurface) { sink->SetUnknown(update.mSequenceCounter); continue; } nsRefPtr<gfxContext> ctx = sink->BeginUpdate(update.mUpdateRect + offset, update.mSequenceCounter); if (!ctx) { continue; } DrawTarget* dt = ctx->GetDrawTarget(); dt->SetTransform(Matrix::Translation(offset.x, offset.y)); rotBuffer.DrawBufferWithRotation(dt, RotatedBuffer::BUFFER_BLACK); update.mLayer->GetSink()->EndUpdate(ctx, update.mUpdateRect + offset); } }
void gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx) { if (!mContext) return; mBlur->Blur(mData); mozilla::gfx::Rect* dirtyRect = mBlur->GetDirtyRect(); DrawTarget *dest = aDestinationCtx->GetDrawTarget(); if (!dest) { NS_ERROR("Blurring not supported for Thebes contexts!"); return; } mozilla::RefPtr<SourceSurface> mask = dest->CreateSourceSurfaceFromData(mData, mBlur->GetSize(), mBlur->GetStride(), FORMAT_A8); if (!mask) { NS_ERROR("Failed to create mask!"); return; } nsRefPtr<gfxPattern> thebesPat = aDestinationCtx->GetPattern(); Pattern* pat = thebesPat->GetPattern(dest, nullptr); Matrix oldTransform = dest->GetTransform(); Matrix newTransform = oldTransform; newTransform.Translate(mBlur->GetRect().x, mBlur->GetRect().y); // Avoid a semi-expensive clip operation if we can, otherwise // clip to the dirty rect if (dirtyRect) { dest->PushClipRect(*dirtyRect); } dest->SetTransform(newTransform); dest->MaskSurface(*pat, mask, Point(0, 0)); dest->SetTransform(oldTransform); if (dirtyRect) { dest->PopClip(); } }
void gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx) { if (!mAccelerated && !mData) { return; } DrawTarget *dest = aDestinationCtx->GetDrawTarget(); if (!dest) { NS_WARNING("Blurring not supported for Thebes contexts!"); return; } RefPtr<gfxPattern> thebesPat = aDestinationCtx->GetPattern(); Pattern* pat = thebesPat->GetPattern(dest, nullptr); if (!pat) { NS_WARNING("Failed to get pattern for blur!"); return; } IntPoint topLeft; RefPtr<SourceSurface> mask = DoBlur(nullptr, &topLeft); if (!mask) { NS_ERROR("Failed to create mask!"); return; } // Avoid a semi-expensive clip operation if we can, otherwise // clip to the dirty rect Rect* dirtyRect = mBlur.GetDirtyRect(); if (dirtyRect) { dest->PushClipRect(*dirtyRect); } Matrix oldTransform = dest->GetTransform(); Matrix newTransform = oldTransform; newTransform.PreTranslate(topLeft); dest->SetTransform(newTransform); dest->MaskSurface(*pat, mask, Point(0, 0)); dest->SetTransform(oldTransform); if (dirtyRect) { dest->PopClip(); } }
void ClientLayerManager::MakeSnapshotIfRequired() { if (!mShadowTarget) { return; } if (mWidget) { if (CompositorChild* remoteRenderer = GetRemoteRenderer()) { // The compositor doesn't draw to a different sized surface // when there's a rotation. Instead we rotate the result // when drawing into dt nsIntRect outerBounds; mWidget->GetBounds(outerBounds); nsIntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents()); if (mTargetRotation) { bounds = RotateRect(bounds, outerBounds, mTargetRotation); } SurfaceDescriptor inSnapshot; if (!bounds.IsEmpty() && mForwarder->AllocSurfaceDescriptor(bounds.Size().ToIntSize(), gfxContentType::COLOR_ALPHA, &inSnapshot) && remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) { RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(inSnapshot); DrawTarget* dt = mShadowTarget->GetDrawTarget(); Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height); Rect srcRect(0, 0, bounds.width, bounds.height); gfx::Matrix rotate = ComputeTransformForUnRotation(outerBounds, mTargetRotation); gfx::Matrix oldMatrix = dt->GetTransform(); dt->SetTransform(oldMatrix * rotate); dt->DrawSurface(surf, dstRect, srcRect, DrawSurfaceOptions(), DrawOptions(1.0f, CompositionOp::OP_OVER)); dt->SetTransform(oldMatrix); } mForwarder->DestroySharedSurface(&inSnapshot); } } mShadowTarget = nullptr; }
DrawTarget* ContentClientIncremental::BorrowDrawTargetForPainting(const PaintState& aPaintState, RotatedContentBuffer::DrawIterator* aIter) { if (aPaintState.mMode == SurfaceMode::SURFACE_NONE) { return nullptr; } if (aIter) { if (aIter->mCount++ > 0) { return nullptr; } aIter->mDrawRegion = aPaintState.mRegionToDraw; } DrawTarget* result = nullptr; nsIntRect drawBounds = aPaintState.mRegionToDraw.GetBounds(); MOZ_ASSERT(!mLoanedDrawTarget); // BeginUpdate is allowed to modify the given region, // if it wants more to be repainted than we request. if (aPaintState.mMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) { nsIntRegion drawRegionCopy = aPaintState.mRegionToDraw; RefPtr<DrawTarget> onBlack = GetUpdateSurface(BUFFER_BLACK, drawRegionCopy); RefPtr<DrawTarget> onWhite = GetUpdateSurface(BUFFER_WHITE, aPaintState.mRegionToDraw); if (onBlack && onWhite) { NS_ASSERTION(aPaintState.mRegionToDraw == drawRegionCopy, "BeginUpdate should always modify the draw region in the same way!"); FillSurface(onBlack, aPaintState.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(0.0, 0.0, 0.0, 1.0)); FillSurface(onWhite, aPaintState.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(1.0, 1.0, 1.0, 1.0)); mLoanedDrawTarget = Factory::CreateDualDrawTarget(onBlack, onWhite); } else { mLoanedDrawTarget = nullptr; } } else { mLoanedDrawTarget = GetUpdateSurface(BUFFER_BLACK, aPaintState.mRegionToDraw); } if (!mLoanedDrawTarget) { NS_WARNING("unable to get context for update"); return nullptr; } result = mLoanedDrawTarget; mLoanedTransform = mLoanedDrawTarget->GetTransform(); mLoanedTransform.Translate(-drawBounds.x, -drawBounds.y); result->SetTransform(mLoanedTransform); mLoanedTransform.Translate(drawBounds.x, drawBounds.y); if (mContentType == gfxContentType::COLOR_ALPHA) { gfxUtils::ClipToRegion(result, aPaintState.mRegionToDraw); nsIntRect bounds = aPaintState.mRegionToDraw.GetBounds(); result->ClearRect(Rect(bounds.x, bounds.y, bounds.width, bounds.height)); } return result; }
void gfxQuartzNativeDrawing::EndNativeDrawing() { NS_ASSERTION(mCGContext, "EndNativeDrawing called without BeginNativeDrawing"); if (mBorrowedContext.cg) { MOZ_ASSERT(!mContext->IsCairo()); mBorrowedContext.Finish(); if (mDrawTarget) { DrawTarget *dest = mContext->GetDrawTarget(); RefPtr<SourceSurface> source = mDrawTarget->Snapshot(); IntSize backingSize(NSToIntFloor(mNativeRect.width * mBackingScale), NSToIntFloor(mNativeRect.height * mBackingScale)); Matrix oldTransform = dest->GetTransform(); Matrix newTransform = oldTransform; newTransform.Translate(mNativeRect.x, mNativeRect.y); newTransform.Scale(1.0f / mBackingScale, 1.0f / mBackingScale); dest->SetTransform(newTransform); dest->DrawSurface(source, gfx::Rect(0, 0, backingSize.width, backingSize.height), gfx::Rect(0, 0, backingSize.width, backingSize.height)); dest->SetTransform(oldTransform); } return; } cairo_quartz_finish_cg_context_with_clip(mSurfaceContext->GetCairo()); mQuartzSurface->MarkDirty(); if (mSurfaceContext != mContext) { gfxContextMatrixAutoSaveRestore save(mContext); // Copy back to destination mContext->Translate(mNativeRect.TopLeft()); mContext->Scale(1.0f / mBackingScale, 1.0f / mBackingScale); mContext->DrawSurface(mQuartzSurface, mQuartzSurface->GetSize()); } }
void gfxWindowsNativeDrawing::PaintToContext() { if (mRenderState == RENDER_STATE_NATIVE_DRAWING_DONE) { // nothing to do, it already went to the context mRenderState = RENDER_STATE_DONE; } else if (mRenderState == RENDER_STATE_ALPHA_RECOVERY_WHITE_DONE) { RefPtr<gfxImageSurface> black = mBlackSurface->GetAsImageSurface(); RefPtr<gfxImageSurface> white = mWhiteSurface->GetAsImageSurface(); if (!gfxAlphaRecovery::RecoverAlpha(black, white)) { NS_ERROR("Alpha recovery failure"); return; } RefPtr<DataSourceSurface> source = Factory::CreateWrappingDataSourceSurface(black->Data(), black->Stride(), black->GetSize(), SurfaceFormat::B8G8R8A8); { DrawTarget* dt = mContext->GetDrawTarget(); AutoRestoreTransform autoRestoreTransform(dt); Matrix newTransform = dt->GetTransform(); newTransform.PreTranslate(ToPoint(mNativeRect.TopLeft())); dt->SetTransform(newTransform); Rect rect(Point(0.0, 0.0), ToSize(mNativeRect.Size())); Matrix m = Matrix::Scaling(1.0 / mScale.width, 1.0 / mScale.height); Filter filter = (mNativeDrawFlags & DO_NEAREST_NEIGHBOR_FILTERING) ? Filter::LINEAR : Filter::GOOD; SurfacePattern pat(source, ExtendMode::CLAMP, m, filter); dt->FillRect(rect, pat); } mRenderState = RENDER_STATE_DONE; } else { NS_ERROR("Invalid RenderState in gfxWindowsNativeDrawing::PaintToContext"); } }
void nsTableCellFrame::DecorateForSelection(nsRenderingContext& aRenderingContext, nsPoint aPt) { NS_ASSERTION(IsSelected(), "Should only be called for selected cells"); int16_t displaySelection; nsPresContext* presContext = PresContext(); displaySelection = DisplaySelection(presContext); if (displaySelection) { RefPtr<nsFrameSelection> frameSelection = presContext->PresShell()->FrameSelection(); if (frameSelection->GetTableCellSelection()) { nscolor bordercolor; if (displaySelection == nsISelectionController::SELECTION_DISABLED) { bordercolor = NS_RGB(176,176,176);// disabled color } else { bordercolor = LookAndFeel::GetColor(LookAndFeel::eColorID_TextSelectBackground); } nscoord threePx = nsPresContext::CSSPixelsToAppUnits(3); if ((mRect.width > threePx) && (mRect.height > threePx)) { //compare bordercolor to ((nsStyleColor *)myColor)->mBackgroundColor) bordercolor = EnsureDifferentColors(bordercolor, StyleBackground()->mBackgroundColor); int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); Point devPixelOffset = NSPointToPoint(aPt, appUnitsPerDevPixel); DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); AutoRestoreTransform autoRestoreTransform(drawTarget); drawTarget->SetTransform( drawTarget->GetTransform().PreTranslate(devPixelOffset)); ColorPattern color(ToDeviceColor(bordercolor)); nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1); StrokeLineWithSnapping(nsPoint(onePixel, 0), nsPoint(mRect.width, 0), appUnitsPerDevPixel, *drawTarget, color); StrokeLineWithSnapping(nsPoint(0, onePixel), nsPoint(0, mRect.height), appUnitsPerDevPixel, *drawTarget, color); StrokeLineWithSnapping(nsPoint(onePixel, mRect.height), nsPoint(mRect.width, mRect.height), appUnitsPerDevPixel, *drawTarget, color); StrokeLineWithSnapping(nsPoint(mRect.width, onePixel), nsPoint(mRect.width, mRect.height), appUnitsPerDevPixel, *drawTarget, color); //middle nsRect r(onePixel, onePixel, mRect.width - onePixel, mRect.height - onePixel); Rect devPixelRect = NSRectToSnappedRect(r, appUnitsPerDevPixel, *drawTarget); drawTarget->StrokeRect(devPixelRect, color); //shading StrokeLineWithSnapping(nsPoint(2*onePixel, mRect.height-2*onePixel), nsPoint(mRect.width-onePixel, mRect.height- (2*onePixel)), appUnitsPerDevPixel, *drawTarget, color); StrokeLineWithSnapping(nsPoint(mRect.width - (2*onePixel), 2*onePixel), nsPoint(mRect.width - (2*onePixel), mRect.height-onePixel), appUnitsPerDevPixel, *drawTarget, color); } } } }