// VirtualDub - Video processing and capture application // Graphics support library // Copyright (C) 1998-2009 Avery Lee // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include #include #include "uberblit.h" #include "uberblit_gen.h" #include "uberblit_fill.h" #include "uberblit_input.h" #include "uberblit_resample.h" #include "uberblit_resample_special.h" #include "uberblit_ycbcr.h" #include "uberblit_ycbcr_generic.h" #include "uberblit_rgb.h" #include "uberblit_swizzle.h" #include "uberblit_pal.h" #include "uberblit_16f.h" #include "uberblit_v210.h" #include "uberblit_interlace.h" #ifdef VD_CPU_X86 #include "uberblit_swizzle_x86.h" #include "uberblit_ycbcr_x86.h" #include "uberblit_rgb_x86.h" #include "uberblit_resample_special_x86.h" #endif void VDPixmapGenerate(void *dst, ptrdiff_t pitch, sint32 bpr, sint32 height, IVDPixmapGen *gen, int genIndex) { for(sint32 y=0; yGetRow(y, genIndex), bpr); vdptrstep(dst, pitch); } VDCPUCleanupExtensions(); } void VDPixmapGenerateFast(void *dst, ptrdiff_t pitch, sint32 height, IVDPixmapGen *gen) { for(sint32 y=0; yProcessRow(dst, y); vdptrstep(dst, pitch); } VDCPUCleanupExtensions(); } /////////////////////////////////////////////////////////////////////////////////////////////////// IVDPixmapBlitter *VDCreatePixmapUberBlitterDirectCopy(const VDPixmap& dst, const VDPixmap& src) { return new VDPixmapUberBlitterDirectCopy; } IVDPixmapBlitter *VDCreatePixmapUberBlitterDirectCopy(const VDPixmapLayout& dst, const VDPixmapLayout& src) { return new VDPixmapUberBlitterDirectCopy; } VDPixmapUberBlitterDirectCopy::VDPixmapUberBlitterDirectCopy() { } VDPixmapUberBlitterDirectCopy::~VDPixmapUberBlitterDirectCopy() { } void VDPixmapUberBlitterDirectCopy::Blit(const VDPixmap& dst, const VDPixmap& src) { Blit(dst, NULL, src); } void VDPixmapUberBlitterDirectCopy::Blit(const VDPixmap& dst, const vdrect32 *rDst, const VDPixmap& src) { VDASSERT(dst.format == src.format); const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(dst.format); void *p = dst.data; void *p2 = dst.data2; void *p3 = dst.data3; int w = std::min(dst.w, src.w); int h = std::min(dst.h, src.h); if (formatInfo.qchunky) { w = (w + formatInfo.qw - 1) / formatInfo.qw; h = -(-h >> formatInfo.qhbits); } int w2 = -(-dst.w >> formatInfo.auxwbits); int h2 = -(-dst.h >> formatInfo.auxhbits); if (rDst) { int x1 = rDst->left; int y1 = rDst->top; int x2 = rDst->right; int y2 = rDst->bottom; VDASSERT(x1 >= 0 && y1 >= 0 && x2 <= w && y2 <= h && x2 >= x1 && y2 >= y1); if (x2 < x1 || y2 < y1) return; p = vdptroffset(dst.data, dst.pitch * y1 + x1 * formatInfo.qsize); w = x2 - x1; h = y2 - y1; if (formatInfo.auxbufs >= 1) { VDASSERT(!((x1|x2) & ((1 << formatInfo.auxwbits) - 1))); VDASSERT(!((y1|y2) & ((1 << formatInfo.auxhbits) - 1))); int ax1 = x1 >> formatInfo.auxwbits; int ay1 = y1 >> formatInfo.auxhbits; int ax2 = x2 >> formatInfo.auxwbits; int ay2 = y2 >> formatInfo.auxhbits; p2 = vdptroffset(dst.data2, dst.pitch2 * ay1 + ax1); w2 = ax2 - ax1; h2 = ay2 - ay1; if (formatInfo.auxbufs >= 2) p3 = vdptroffset(dst.data3, dst.pitch3 * ay1 + ax1); } } uint32 bpr = formatInfo.qsize * w; VDMemcpyRect(p, dst.pitch, src.data, src.pitch, bpr, h); if (formatInfo.auxbufs >= 1) { VDMemcpyRect(p2, dst.pitch2, src.data2, src.pitch2, w2 * formatInfo.auxsize, h2); if (formatInfo.auxbufs >= 2) VDMemcpyRect(p3, dst.pitch3, src.data3, src.pitch3, w2 * formatInfo.auxsize, h2); } } /////////////////////////////////////////////////////////////////////////////////////////////////// VDPixmapUberBlitter::VDPixmapUberBlitter() { } VDPixmapUberBlitter::~VDPixmapUberBlitter() { while(!mGenerators.empty()) { delete mGenerators.back(); mGenerators.pop_back(); } } void VDPixmapUberBlitter::Blit(const VDPixmap& dst, const VDPixmap& src) { Blit(dst, NULL, src); } void VDPixmapUberBlitter::Blit(const VDPixmap& dst, const vdrect32 *rDst, const VDPixmap& src) { for(Sources::const_iterator it(mSources.begin()), itEnd(mSources.end()); it!=itEnd; ++it) { const SourceEntry& se = *it; const void *p; ptrdiff_t pitch; switch(se.mSrcPlane) { case 0: p = src.data; pitch = src.pitch; break; case 1: p = src.data2; pitch = src.pitch2; break; case 2: p = src.data3; pitch = src.pitch3; break; default: VDASSERT(false); break; } se.mpSrc->SetSource((const char *)p + pitch*se.mSrcY + se.mSrcX, pitch, src.palette); } if (mOutputs[2].mpSrc) { if (mbIndependentPlanes) Blit3Separated(dst, rDst); else if (mbIndependentChromaPlanes) Blit3Split(dst, rDst); else Blit3(dst, rDst); } else if (mOutputs[1].mpSrc) { if (mbIndependentPlanes) Blit2Separated(dst, rDst); else Blit2(dst, rDst); } else Blit(dst, rDst); } void VDPixmapUberBlitter::Blit(const VDPixmap& dst, const vdrect32 *rDst) { const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(dst.format); mOutputs[0].mpSrc->AddWindowRequest(0, 0); mOutputs[0].mpSrc->Start(); void *p = dst.data; int w = dst.w; int h = dst.h; if (formatInfo.qchunky) { w = (w + formatInfo.qw - 1) / formatInfo.qw; h = -(-h >> formatInfo.qhbits); } if (rDst) { int x1 = rDst->left; int y1 = rDst->top; int x2 = rDst->right; int y2 = rDst->bottom; if (formatInfo.qchunky) { x1 = x1 / formatInfo.qw; y1 = y1 / formatInfo.qh; x2 = (x2 + formatInfo.qw - 1) / formatInfo.qw; y2 = (y2 + formatInfo.qh - 1) / formatInfo.qh; } VDASSERT(x1 >= 0 && y1 >= 0 && x2 <= w && y2 <= h && x2 >= x1 && y2 >= y1); if (x2 < x1 || y2 < y1) return; p = vdptroffset(dst.data, dst.pitch * y1 + x1 * formatInfo.qsize); w = x2 - x1; h = y2 - y1; } uint32 bpr = formatInfo.qsize * w; if (mOutputs[0].mSrcIndex == 0) VDPixmapGenerateFast(p, dst.pitch, h, mOutputs[0].mpSrc); else VDPixmapGenerate(p, dst.pitch, bpr, h, mOutputs[0].mpSrc, mOutputs[0].mSrcIndex); } void VDPixmapUberBlitter::Blit3(const VDPixmap& px, const vdrect32 *rDst) { const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(px.format); IVDPixmapGen *gen = mOutputs[1].mpSrc; int idx = mOutputs[1].mSrcIndex; IVDPixmapGen *gen1 = mOutputs[2].mpSrc; int idx1 = mOutputs[2].mSrcIndex; IVDPixmapGen *gen2 = mOutputs[0].mpSrc; int idx2 = mOutputs[0].mSrcIndex; gen->AddWindowRequest(0, 0); gen->Start(); gen1->AddWindowRequest(0, 0); gen1->Start(); gen2->AddWindowRequest(0, 0); gen2->Start(); uint32 auxstep = 0x80000000UL >> formatInfo.auxhbits; uint32 auxaccum = 0; auxstep += auxstep; int qw = px.w; int qh = px.h; if (formatInfo.qchunky) { qw = (qw + formatInfo.qw - 1) / formatInfo.qw; qh = -(-qh >> formatInfo.qhbits); } uint32 height = qh; uint32 bpr = formatInfo.qsize * qw; uint32 bpr2 = formatInfo.auxsize * -(-px.w >> formatInfo.auxwbits); uint8 *dst = (uint8 *)px.data; uint8 *dst2 = (uint8 *)px.data2; uint8 *dst3 = (uint8 *)px.data3; ptrdiff_t pitch = px.pitch; ptrdiff_t pitch2 = px.pitch2; ptrdiff_t pitch3 = px.pitch3; uint32 y2 = 0; for(uint32 y=0; yGetRow(y, idx), bpr); vdptrstep(dst, pitch); if (!auxaccum) { memcpy(dst2, gen1->GetRow(y2, idx1), bpr2); vdptrstep(dst2, pitch2); memcpy(dst3, gen2->GetRow(y2, idx2), bpr2); vdptrstep(dst3, pitch3); ++y2; } auxaccum += auxstep; } VDCPUCleanupExtensions(); } void VDPixmapUberBlitter::Blit3Split(const VDPixmap& px, const vdrect32 *rDst) { const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(px.format); IVDPixmapGen *gen = mOutputs[1].mpSrc; int idx = mOutputs[1].mSrcIndex; IVDPixmapGen *gen1 = mOutputs[2].mpSrc; int idx1 = mOutputs[2].mSrcIndex; IVDPixmapGen *gen2 = mOutputs[0].mpSrc; int idx2 = mOutputs[0].mSrcIndex; gen->AddWindowRequest(0, 0); gen->Start(); gen1->AddWindowRequest(0, 0); gen1->Start(); gen2->AddWindowRequest(0, 0); gen2->Start(); uint32 auxstep = 0x80000000UL >> formatInfo.auxhbits; uint32 auxaccum = 0; auxstep += auxstep; int qw = px.w; int qh = px.h; if (formatInfo.qchunky) { qw = (qw + formatInfo.qw - 1) / formatInfo.qw; qh = -(-qh >> formatInfo.qhbits); } uint32 height = qh; uint32 bpr = formatInfo.qsize * qw; uint8 *dst = (uint8 *)px.data; ptrdiff_t pitch = px.pitch; if (idx == 0) { for(uint32 y=0; yProcessRow(dst, y); vdptrstep(dst, pitch); } } else { for(uint32 y=0; yGetRow(y, idx), bpr); vdptrstep(dst, pitch); } } uint32 bpr2 = -(-px.w >> formatInfo.auxwbits) * formatInfo.auxsize; uint8 *dst2 = (uint8 *)px.data2; uint8 *dst3 = (uint8 *)px.data3; ptrdiff_t pitch2 = px.pitch2; ptrdiff_t pitch3 = px.pitch3; uint32 y2 = 0; for(uint32 y=0; yGetRow(y2, idx1), bpr2); vdptrstep(dst2, pitch2); memcpy(dst3, gen2->GetRow(y2, idx2), bpr2); vdptrstep(dst3, pitch3); ++y2; } auxaccum += auxstep; } VDCPUCleanupExtensions(); } void VDPixmapUberBlitter::Blit3Separated(const VDPixmap& px, const vdrect32 *rDst) { const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(px.format); IVDPixmapGen *gen = mOutputs[1].mpSrc; int idx = mOutputs[1].mSrcIndex; IVDPixmapGen *gen1 = mOutputs[2].mpSrc; int idx1 = mOutputs[2].mSrcIndex; IVDPixmapGen *gen2 = mOutputs[0].mpSrc; int idx2 = mOutputs[0].mSrcIndex; gen->AddWindowRequest(0, 0); gen->Start(); gen1->AddWindowRequest(0, 0); gen1->Start(); gen2->AddWindowRequest(0, 0); gen2->Start(); int qw = px.w; int qh = px.h; if (formatInfo.qchunky) { qw = (qw + formatInfo.qw - 1) / formatInfo.qw; qh = -(-qh >> formatInfo.qhbits); } uint32 height = qh; uint32 bpr = formatInfo.qsize * qw; uint8 *dst = (uint8 *)px.data; ptrdiff_t pitch = px.pitch; if (idx == 0) { for(uint32 y=0; yProcessRow(dst, y); vdptrstep(dst, pitch); } } else { for(uint32 y=0; yGetRow(y, idx), bpr); vdptrstep(dst, pitch); } } uint32 bpr2 = -(-px.w >> formatInfo.auxwbits) * formatInfo.auxsize; uint32 h2 = -(-px.h >> formatInfo.auxhbits); uint8 *dst2 = (uint8 *)px.data2; ptrdiff_t pitch2 = px.pitch2; if (idx1 == 0) { for(uint32 y2=0; y2ProcessRow(dst2, y2); vdptrstep(dst2, pitch2); } } else { for(uint32 y2=0; y2GetRow(y2, idx1), bpr2); vdptrstep(dst2, pitch2); } } uint8 *dst3 = (uint8 *)px.data3; ptrdiff_t pitch3 = px.pitch3; if (idx2 == 0) { for(uint32 y2=0; y2ProcessRow(dst3, y2); vdptrstep(dst3, pitch3); } } else { for(uint32 y2=0; y2GetRow(y2, idx2), bpr2); vdptrstep(dst3, pitch3); } } VDCPUCleanupExtensions(); } void VDPixmapUberBlitter::Blit2(const VDPixmap& px, const vdrect32 *rDst) { const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(px.format); IVDPixmapGen *gen = mOutputs[0].mpSrc; int idx = mOutputs[0].mSrcIndex; IVDPixmapGen *gen1 = mOutputs[1].mpSrc; int idx1 = mOutputs[1].mSrcIndex; gen->AddWindowRequest(0, 0); gen->Start(); gen1->AddWindowRequest(0, 0); gen1->Start(); uint32 auxstep = 0x80000000UL >> formatInfo.auxhbits; uint32 auxaccum = 0; auxstep += auxstep; int qw = px.w; int qh = px.h; if (formatInfo.qchunky) { qw = (qw + formatInfo.qw - 1) / formatInfo.qw; qh = -(-qh >> formatInfo.qhbits); } uint32 height = qh; uint32 bpr = formatInfo.qsize * qw; uint32 bpr2 = formatInfo.auxsize * -(-px.w >> formatInfo.auxwbits); uint8 *dst = (uint8 *)px.data; uint8 *dst2 = (uint8 *)px.data2; ptrdiff_t pitch = px.pitch; ptrdiff_t pitch2 = px.pitch2; uint32 y2 = 0; for(uint32 y=0; yGetRow(y, idx), bpr); vdptrstep(dst, pitch); if (!auxaccum) { memcpy(dst2, gen1->GetRow(y2, idx1), bpr2); vdptrstep(dst2, pitch2); ++y2; } auxaccum += auxstep; } VDCPUCleanupExtensions(); } void VDPixmapUberBlitter::Blit2Separated(const VDPixmap& px, const vdrect32 *rDst) { const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(px.format); IVDPixmapGen *gen = mOutputs[0].mpSrc; int idx = mOutputs[0].mSrcIndex; IVDPixmapGen *gen1 = mOutputs[1].mpSrc; int idx1 = mOutputs[1].mSrcIndex; gen->AddWindowRequest(0, 0); gen->Start(); gen1->AddWindowRequest(0, 0); gen1->Start(); int qw = px.w; int qh = px.h; if (formatInfo.qchunky) { qw = (qw + formatInfo.qw - 1) / formatInfo.qw; qh = -(-qh >> formatInfo.qhbits); } uint32 height = qh; uint32 bpr = formatInfo.qsize * qw; uint8 *dst = (uint8 *)px.data; ptrdiff_t pitch = px.pitch; if (idx == 0) { for(uint32 y=0; yProcessRow(dst, y); vdptrstep(dst, pitch); } } else { for(uint32 y=0; yGetRow(y, idx), bpr); vdptrstep(dst, pitch); } } uint32 bpr2 = -(-px.w >> formatInfo.auxwbits) * formatInfo.auxsize; uint32 h2 = -(-px.h >> formatInfo.auxhbits); uint8 *dst2 = (uint8 *)px.data2; ptrdiff_t pitch2 = px.pitch2; if (idx1 == 0) { for(uint32 y2=0; y2ProcessRow(dst2, y2); vdptrstep(dst2, pitch2); } } else { for(uint32 y2=0; y2GetRow(y2, idx1), bpr2); vdptrstep(dst2, pitch2); } } VDCPUCleanupExtensions(); } /////////////////////////////////////////////////////////////////////////////////////////////////// VDPixmapUberBlitterGenerator::VDPixmapUberBlitterGenerator() { } VDPixmapUberBlitterGenerator::~VDPixmapUberBlitterGenerator() { while(!mGenerators.empty()) { delete mGenerators.back(); mGenerators.pop_back(); } } void VDPixmapUberBlitterGenerator::swap(int index) { std::swap(mStack.back(), (&mStack.back())[-index]); } void VDPixmapUberBlitterGenerator::dup() { mStack.push_back(mStack.back()); } void VDPixmapUberBlitterGenerator::pop() { mStack.pop_back(); } void VDPixmapUberBlitterGenerator::ldsrc(int srcIndex, int srcPlane, int x, int y, uint32 w, uint32 h, uint32 type, uint32 bpr) { VDPixmapGenSrc *src = new VDPixmapGenSrc; src->Init(w, h, type, bpr); mGenerators.push_back(src); mStack.push_back(StackEntry(src, 0)); SourceEntry se; se.mpSrc = src; se.mSrcIndex = srcIndex; se.mSrcPlane = srcPlane; se.mSrcX = x; se.mSrcY = y; mSources.push_back(se); } void VDPixmapUberBlitterGenerator::ldconst(uint8 fill, uint32 bpr, uint32 w, uint32 h, uint32 type) { VDPixmapGenFill8 *src = new VDPixmapGenFill8; src->Init(fill, bpr, w, h, type); mGenerators.push_back(src); mStack.push_back(StackEntry(src, 0)); } void VDPixmapUberBlitterGenerator::extract_8in16(int offset, uint32 w, uint32 h) { StackEntry *args = &mStack.back(); VDPixmapGen_8In16 *src = NULL; #if VD_CPU_X86 if (MMX_enabled) { if (offset == 0) src = new VDPixmapGen_8In16_Even_MMX; else if (offset == 1) src = new VDPixmapGen_8In16_Odd_MMX; } #endif if (!src) src = new VDPixmapGen_8In16; src->Init(args[0].mpSrc, args[0].mSrcIndex, offset, w, h); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::extract_8in32(int offset, uint32 w, uint32 h) { StackEntry *args = &mStack.back(); VDPixmapGen_8In32 *src = NULL; #if VD_CPU_X86 if (MMX_enabled) { if ((unsigned)offset < 4) src = new VDPixmapGen_8In32_MMX; } #endif if (!src) src = new VDPixmapGen_8In32; src->Init(args[0].mpSrc, args[0].mSrcIndex, offset, w, h); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::swap_8in16(uint32 w, uint32 h, uint32 bpr) { StackEntry *args = &mStack.back(); #if VD_CPU_X86 VDPixmapGen_Swap8In16 *src = MMX_enabled ? new VDPixmapGen_Swap8In16_MMX : new VDPixmapGen_Swap8In16; #else VDPixmapGen_Swap8In16 *src = new VDPixmapGen_Swap8In16; #endif src->Init(args[0].mpSrc, args[0].mSrcIndex, w, h, bpr); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_Pal1_to_8888(int srcIndex) { StackEntry *args = &mStack.back(); VDPixmapGen_Pal1_To_X8R8G8B8 *src = new VDPixmapGen_Pal1_To_X8R8G8B8; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); SourceEntry se; se.mpSrc = src; se.mSrcIndex = srcIndex; se.mSrcPlane = 0; se.mSrcX = 0; se.mSrcY = 0; mSources.push_back(se); } void VDPixmapUberBlitterGenerator::conv_Pal2_to_8888(int srcIndex) { StackEntry *args = &mStack.back(); VDPixmapGen_Pal2_To_X8R8G8B8 *src = new VDPixmapGen_Pal2_To_X8R8G8B8; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); SourceEntry se; se.mpSrc = src; se.mSrcIndex = srcIndex; se.mSrcPlane = 0; se.mSrcX = 0; se.mSrcY = 0; mSources.push_back(se); } void VDPixmapUberBlitterGenerator::conv_Pal4_to_8888(int srcIndex) { StackEntry *args = &mStack.back(); VDPixmapGen_Pal4_To_X8R8G8B8 *src = new VDPixmapGen_Pal4_To_X8R8G8B8; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); SourceEntry se; se.mpSrc = src; se.mSrcIndex = srcIndex; se.mSrcPlane = 0; se.mSrcX = 0; se.mSrcY = 0; mSources.push_back(se); } void VDPixmapUberBlitterGenerator::conv_Pal8_to_8888(int srcIndex) { StackEntry *args = &mStack.back(); VDPixmapGen_Pal8_To_X8R8G8B8 *src = new VDPixmapGen_Pal8_To_X8R8G8B8; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); SourceEntry se; se.mpSrc = src; se.mSrcIndex = srcIndex; se.mSrcPlane = 0; se.mSrcX = 0; se.mSrcY = 0; mSources.push_back(se); } void VDPixmapUberBlitterGenerator::pointh(float xoffset, float xfactor, uint32 w) { StackEntry *args = &mStack.back(); if (xoffset != 0.5f || xfactor != 1.0f) { VDPixmapGenResampleRow *src = new VDPixmapGenResampleRow; src->Init(args[0].mpSrc, args[0].mSrcIndex, w, xoffset, xfactor, nsVDPixmap::kFilterPoint, 0, false); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } } void VDPixmapUberBlitterGenerator::pointv(float yoffset, float yfactor, uint32 h) { StackEntry *args = &mStack.back(); if (yoffset != 0.5f || yfactor != 1.0f) { VDPixmapGenResampleCol *src = new VDPixmapGenResampleCol; src->Init(args[0].mpSrc, args[0].mSrcIndex, h, yoffset, yfactor, nsVDPixmap::kFilterPoint, 0, false); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } } void VDPixmapUberBlitterGenerator::linearh(float xoffset, float xfactor, uint32 w, bool interpOnly) { StackEntry *args = &mStack.back(); IVDPixmapGen *src = args[0].mpSrc; int srcIndex = args[0].mSrcIndex; sint32 srcw = src->GetWidth(srcIndex); if (xoffset == 0.5f && xfactor == 1.0f && srcw == w) return; if (xoffset == 0.5f && (src->GetType(srcIndex) & kVDPixType_Mask) == kVDPixType_8) { if (xfactor == 2.0f && w == ((srcw + 1) >> 1)) { VDPixmapGenResampleRow_d2_p0_lin_u8 *out = new VDPixmapGenResampleRow_d2_p0_lin_u8; out->Init(src, srcIndex); mGenerators.push_back(out); MarkDependency(out, src); args[0] = StackEntry(out, 0); return; } if (xfactor == 4.0f && w == ((srcw + 3) >> 2)) { VDPixmapGenResampleRow_d4_p0_lin_u8 *out = new VDPixmapGenResampleRow_d4_p0_lin_u8; out->Init(src, srcIndex); mGenerators.push_back(out); MarkDependency(out, src); args[0] = StackEntry(out, 0); return; } if (xfactor == 0.5f && w == srcw*2) { #if VD_CPU_X86 VDPixmapGenResampleRow_x2_p0_lin_u8 *out = ISSE_enabled ? new VDPixmapGenResampleRow_x2_p0_lin_u8_ISSE : new VDPixmapGenResampleRow_x2_p0_lin_u8; #else VDPixmapGenResampleRow_x2_p0_lin_u8 *out = new VDPixmapGenResampleRow_x2_p0_lin_u8; #endif out->Init(src, srcIndex); mGenerators.push_back(out); MarkDependency(out, src); args[0] = StackEntry(out, 0); return; } if (xfactor == 0.25f && w == srcw*4) { #if VD_CPU_X86 VDPixmapGenResampleRow_x4_p0_lin_u8 *out = MMX_enabled ? new VDPixmapGenResampleRow_x4_p0_lin_u8_MMX : new VDPixmapGenResampleRow_x4_p0_lin_u8; #else VDPixmapGenResampleRow_x4_p0_lin_u8 *out = new VDPixmapGenResampleRow_x4_p0_lin_u8; #endif out->Init(src, srcIndex); mGenerators.push_back(out); MarkDependency(out, src); args[0] = StackEntry(out, 0); return; } } VDPixmapGenResampleRow *out = new VDPixmapGenResampleRow; out->Init(args[0].mpSrc, args[0].mSrcIndex, w, xoffset, xfactor, nsVDPixmap::kFilterLinear, 0, interpOnly); mGenerators.push_back(out); MarkDependency(out, src); args[0] = StackEntry(out, 0); } void VDPixmapUberBlitterGenerator::linearv(float yoffset, float yfactor, uint32 h, bool interpOnly) { StackEntry *args = &mStack.back(); IVDPixmapGen *src = args[0].mpSrc; int srcIndex = args[0].mSrcIndex; sint32 srch = src->GetHeight(srcIndex); if (yoffset == 0.5f && yfactor == 1.0f && srch == h) return; if ((src->GetType(srcIndex) & kVDPixType_Mask) == kVDPixType_8) { if (yoffset == 1.0f && yfactor == 2.0f && h == ((srch + 1) >> 1)) { VDPixmapGenResampleCol_x2_phalf_lin_u8 *out = new VDPixmapGenResampleCol_x2_phalf_lin_u8; out->Init(src, srcIndex); mGenerators.push_back(out); MarkDependency(out, src); args[0] = StackEntry(out, 0); return; } if (yoffset == 2.0f && yfactor == 4.0f && h == ((srch + 2) >> 2)) { VDPixmapGenResampleCol_x4_p1half_lin_u8 *out = new VDPixmapGenResampleCol_x4_p1half_lin_u8; out->Init(src, srcIndex); mGenerators.push_back(out); MarkDependency(out, src); args[0] = StackEntry(out, 0); return; } if (yoffset == 0.25f && yfactor == 0.5f && h == srch*2) { #if VD_CPU_X86 VDPixmapGenResampleCol_d2_pnqrtr_lin_u8 *out = ISSE_enabled ? new VDPixmapGenResampleCol_d2_pnqrtr_lin_u8_ISSE : new VDPixmapGenResampleCol_d2_pnqrtr_lin_u8; #else VDPixmapGenResampleCol_d2_pnqrtr_lin_u8 *out = new VDPixmapGenResampleCol_d2_pnqrtr_lin_u8; #endif out->Init(src, srcIndex); mGenerators.push_back(out); MarkDependency(out, src); args[0] = StackEntry(out, 0); return; } if (yoffset == 0.125f && yfactor == 0.25f && h == srch*4) { #if VD_CPU_X86 VDPixmapGenResampleCol_d4_pn38_lin_u8 *out = ISSE_enabled ? new VDPixmapGenResampleCol_d4_pn38_lin_u8_ISSE : new VDPixmapGenResampleCol_d4_pn38_lin_u8; #else VDPixmapGenResampleCol_d4_pn38_lin_u8 *out = new VDPixmapGenResampleCol_d4_pn38_lin_u8; #endif out->Init(src, srcIndex); mGenerators.push_back(out); MarkDependency(out, src); args[0] = StackEntry(out, 0); return; } } VDPixmapGenResampleCol *out = new VDPixmapGenResampleCol; out->Init(src, srcIndex, h, yoffset, yfactor, nsVDPixmap::kFilterLinear, 0, interpOnly); mGenerators.push_back(out); MarkDependency(out, src); args[0] = StackEntry(out, 0); } void VDPixmapUberBlitterGenerator::linear(float xoffset, float xfactor, uint32 w, float yoffset, float yfactor, uint32 h) { linearh(xoffset, xfactor, w, false); linearv(yoffset, yfactor, h, false); } void VDPixmapUberBlitterGenerator::cubich(float xoffset, float xfactor, uint32 w, float splineFactor, bool interpOnly) { StackEntry *args = &mStack.back(); if (xoffset != 0.5f || xfactor != 1.0f) { VDPixmapGenResampleRow *src = new VDPixmapGenResampleRow; src->Init(args[0].mpSrc, args[0].mSrcIndex, w, xoffset, xfactor, nsVDPixmap::kFilterCubic, splineFactor, interpOnly); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } } void VDPixmapUberBlitterGenerator::cubicv(float yoffset, float yfactor, uint32 h, float splineFactor, bool interpOnly) { StackEntry *args = &mStack.back(); if (yoffset != 0.5f || yfactor != 1.0f) { VDPixmapGenResampleCol *src = new VDPixmapGenResampleCol; src->Init(args[0].mpSrc, args[0].mSrcIndex, h, yoffset, yfactor, nsVDPixmap::kFilterCubic, splineFactor, interpOnly); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } } void VDPixmapUberBlitterGenerator::cubic(float xoffset, float xfactor, uint32 w, float yoffset, float yfactor, uint32 h, float splineFactor) { cubich(xoffset, xfactor, w, splineFactor, false); cubicv(yoffset, yfactor, h, splineFactor, false); } void VDPixmapUberBlitterGenerator::lanczos3h(float xoffset, float xfactor, uint32 w) { StackEntry *args = &mStack.back(); if (xoffset != 0.5f || xfactor != 1.0f) { VDPixmapGenResampleRow *src = new VDPixmapGenResampleRow; src->Init(args[0].mpSrc, args[0].mSrcIndex, w, xoffset, xfactor, nsVDPixmap::kFilterLanczos3, 0, false); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } } void VDPixmapUberBlitterGenerator::lanczos3v(float yoffset, float yfactor, uint32 h) { StackEntry *args = &mStack.back(); if (yoffset != 0.5f || yfactor != 1.0f) { VDPixmapGenResampleCol *src = new VDPixmapGenResampleCol; src->Init(args[0].mpSrc, args[0].mSrcIndex, h, yoffset, yfactor, nsVDPixmap::kFilterLanczos3, 0, false); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } } void VDPixmapUberBlitterGenerator::lanczos3(float xoffset, float xfactor, uint32 w, float yoffset, float yfactor, uint32 h) { lanczos3h(xoffset, xfactor, w); lanczos3v(yoffset, yfactor, h); } void VDPixmapUberBlitterGenerator::conv_555_to_8888() { StackEntry *args = &mStack.back(); #ifdef VD_CPU_X86 VDPixmapGen_X1R5G5B5_To_X8R8G8B8 *src = MMX_enabled ? new VDPixmapGen_X1R5G5B5_To_X8R8G8B8_MMX : new VDPixmapGen_X1R5G5B5_To_X8R8G8B8; #else VDPixmapGen_X1R5G5B5_To_X8R8G8B8 *src = new VDPixmapGen_X1R5G5B5_To_X8R8G8B8; #endif src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_565_to_8888() { StackEntry *args = &mStack.back(); #ifdef VD_CPU_X86 VDPixmapGen_R5G6B5_To_X8R8G8B8 *src = MMX_enabled ? new VDPixmapGen_R5G6B5_To_X8R8G8B8_MMX : new VDPixmapGen_R5G6B5_To_X8R8G8B8; #else VDPixmapGen_R5G6B5_To_X8R8G8B8 *src = new VDPixmapGen_R5G6B5_To_X8R8G8B8; #endif src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_888_to_8888() { StackEntry *args = &mStack.back(); #ifdef VD_CPU_X86 VDPixmapGen_R8G8B8_To_A8R8G8B8 *src = MMX_enabled ? new VDPixmapGen_R8G8B8_To_X8R8G8B8_MMX : new VDPixmapGen_R8G8B8_To_A8R8G8B8; #else VDPixmapGen_R8G8B8_To_A8R8G8B8 *src = new VDPixmapGen_R8G8B8_To_A8R8G8B8; #endif src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_8_to_32F() { StackEntry *args = &mStack.back(); VDPixmapGen_8_To_32F *src = new VDPixmapGen_8_To_32F; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_16F_to_32F() { StackEntry *args = &mStack.back(); VDPixmapGen_16F_To_32F *src = new VDPixmapGen_16F_To_32F; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_V210_to_32F() { StackEntry *args = &mStack.back(); VDPixmapGen_V210_To_32F *src = new VDPixmapGen_V210_To_32F; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); mStack.push_back(StackEntry(src, 1)); mStack.push_back(StackEntry(src, 2)); } void VDPixmapUberBlitterGenerator::conv_8888_to_X32F() { StackEntry *args = &mStack.back(); VDPixmapGen_X8R8G8B8_To_X32B32G32R32F *src = new VDPixmapGen_X8R8G8B8_To_X32B32G32R32F; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_8888_to_555() { StackEntry *args = &mStack.back(); #ifdef VD_CPU_X86 VDPixmapGen_X8R8G8B8_To_X1R5G5B5 *src = MMX_enabled ? new VDPixmapGen_X8R8G8B8_To_X1R5G5B5_MMX : new VDPixmapGen_X8R8G8B8_To_X1R5G5B5; #else VDPixmapGen_X8R8G8B8_To_X1R5G5B5 *src = new VDPixmapGen_X8R8G8B8_To_X1R5G5B5; #endif src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_555_to_565() { StackEntry *args = &mStack.back(); #ifdef VD_CPU_X86 VDPixmapGen_X1R5G5B5_To_R5G6B5 *src = MMX_enabled ? new VDPixmapGen_X1R5G5B5_To_R5G6B5_MMX : new VDPixmapGen_X1R5G5B5_To_R5G6B5; #else VDPixmapGen_X1R5G5B5_To_R5G6B5 *src = new VDPixmapGen_X1R5G5B5_To_R5G6B5; #endif src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_565_to_555() { StackEntry *args = &mStack.back(); #ifdef VD_CPU_X86 VDPixmapGen_R5G6B5_To_X1R5G5B5 *src = MMX_enabled ? new VDPixmapGen_R5G6B5_To_X1R5G5B5_MMX : new VDPixmapGen_R5G6B5_To_X1R5G5B5; #else VDPixmapGen_R5G6B5_To_X1R5G5B5 *src = new VDPixmapGen_R5G6B5_To_X1R5G5B5; #endif src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_8888_to_565() { StackEntry *args = &mStack.back(); #ifdef VD_CPU_X86 VDPixmapGen_X8R8G8B8_To_R5G6B5 *src = MMX_enabled ? new VDPixmapGen_X8R8G8B8_To_R5G6B5_MMX : new VDPixmapGen_X8R8G8B8_To_R5G6B5; #else VDPixmapGen_X8R8G8B8_To_R5G6B5 *src = new VDPixmapGen_X8R8G8B8_To_R5G6B5; #endif src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_8888_to_888() { StackEntry *args = &mStack.back(); #ifdef VD_CPU_X86 VDPixmapGen_X8R8G8B8_To_R8G8B8 *src = MMX_enabled ? new VDPixmapGen_X8R8G8B8_To_R8G8B8_MMX : new VDPixmapGen_X8R8G8B8_To_R8G8B8; #else VDPixmapGen_X8R8G8B8_To_R8G8B8 *src = new VDPixmapGen_X8R8G8B8_To_R8G8B8; #endif src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_32F_to_8() { StackEntry *args = &mStack.back(); VDPixmapGen_32F_To_8 *src = new VDPixmapGen_32F_To_8; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_X32F_to_8888() { StackEntry *args = &mStack.back(); VDPixmapGen_X32B32G32R32F_To_X8R8G8B8 *src = new VDPixmapGen_X32B32G32R32F_To_X8R8G8B8; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_32F_to_16F() { StackEntry *args = &mStack.back(); VDPixmapGen_32F_To_16F *src = new VDPixmapGen_32F_To_16F; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::conv_32F_to_V210() { StackEntry *args = &*(mStack.end() - 3); VDPixmapGen_32F_To_V210 *src = new VDPixmapGen_32F_To_V210; src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); mStack.pop_back(); mStack.pop_back(); } void VDPixmapUberBlitterGenerator::convd_8888_to_555() { StackEntry *args = &mStack.back(); VDPixmapGen_X8R8G8B8_To_X1R5G5B5_Dithered *src = new VDPixmapGen_X8R8G8B8_To_X1R5G5B5_Dithered; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::convd_8888_to_565() { StackEntry *args = &mStack.back(); VDPixmapGen_X8R8G8B8_To_R5G6B5_Dithered *src = new VDPixmapGen_X8R8G8B8_To_R5G6B5_Dithered; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::convd_32F_to_8() { StackEntry *args = &mStack.back(); VDPixmapGen_32F_To_8_Dithered *src = new VDPixmapGen_32F_To_8_Dithered; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::convd_X32F_to_8888() { StackEntry *args = &mStack.back(); VDPixmapGen_X32B32G32R32F_To_X8R8G8B8_Dithered *src = new VDPixmapGen_X32B32G32R32F_To_X8R8G8B8_Dithered; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); } void VDPixmapUberBlitterGenerator::interleave_B8G8_R8G8() { StackEntry *args = &mStack.back() - 2; VDPixmapGen_B8x3_To_B8G8_R8G8 *src = NULL; #if VD_CPU_X86 if (MMX_enabled) src = new VDPixmapGen_B8x3_To_B8G8_R8G8_MMX; #endif if (!src) src = new VDPixmapGen_B8x3_To_B8G8_R8G8; src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); mStack.pop_back(); mStack.pop_back(); } void VDPixmapUberBlitterGenerator::interleave_G8B8_G8R8() { StackEntry *args = &mStack.back() - 2; VDPixmapGen_B8x3_To_G8B8_G8R8 *src = NULL; #if VD_CPU_X86 if (MMX_enabled) src = new VDPixmapGen_B8x3_To_G8B8_G8R8_MMX; #endif if (!src) src = new VDPixmapGen_B8x3_To_G8B8_G8R8; src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); mStack.pop_back(); mStack.pop_back(); } void VDPixmapUberBlitterGenerator::interleave_X8R8G8B8() { StackEntry *args = &mStack.back() - 2; VDPixmapGen_B8x3_To_X8R8G8B8 *src = new VDPixmapGen_B8x3_To_X8R8G8B8; src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); mStack.pop_back(); mStack.pop_back(); } void VDPixmapUberBlitterGenerator::interleave_B8R8() { StackEntry *args = &mStack.back() - 1; #if VD_CPU_X86 VDPixmapGen_B8x2_To_B8R8 *src = MMX_enabled ? new VDPixmapGen_B8x2_To_B8R8_MMX : new VDPixmapGen_B8x2_To_B8R8; #else VDPixmapGen_B8x2_To_B8R8 *src = new VDPixmapGen_B8x2_To_B8R8; #endif src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); args[0] = StackEntry(src, 0); mStack.pop_back(); } void VDPixmapUberBlitterGenerator::merge_fields(uint32 w, uint32 h, uint32 bpr) { StackEntry *args = &mStack.back() - 1; VDPixmapGen_MergeFields *src = new VDPixmapGen_MergeFields; src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, w, h, bpr); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); args[0] = StackEntry(src, 0); mStack.pop_back(); } void VDPixmapUberBlitterGenerator::split_fields(uint32 bpr) { StackEntry *args = &mStack.back(); VDPixmapGen_SplitFields *src = new VDPixmapGen_SplitFields; src->Init(args[0].mpSrc, args[0].mSrcIndex, bpr); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); mStack.push_back(StackEntry(src, 1)); } void VDPixmapUberBlitterGenerator::ycbcr601_to_rgb32() { StackEntry *args = &mStack.back() - 2; #ifdef VD_CPU_X86 VDPixmapGenYCbCr601ToRGB32 *src = MMX_enabled ? new VDPixmapGenYCbCr601ToRGB32_MMX : new VDPixmapGenYCbCr601ToRGB32; #else VDPixmapGenYCbCr601ToRGB32 *src = new VDPixmapGenYCbCr601ToRGB32; #endif src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); mStack.pop_back(); mStack.pop_back(); } void VDPixmapUberBlitterGenerator::ycbcr709_to_rgb32() { StackEntry *args = &mStack.back() - 2; VDPixmapGenYCbCr709ToRGB32 *src = new VDPixmapGenYCbCr709ToRGB32; src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); mStack.pop_back(); mStack.pop_back(); } void VDPixmapUberBlitterGenerator::rgb32_to_ycbcr601() { StackEntry *args = &mStack.back(); #ifdef VD_CPU_X86 VDPixmapGenRGB32ToYCbCr601 *src = SSE2_enabled ? new VDPixmapGenRGB32ToYCbCr601_SSE2 : new VDPixmapGenRGB32ToYCbCr601; #else VDPixmapGenRGB32ToYCbCr601 *src = new VDPixmapGenRGB32ToYCbCr601; #endif src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); mStack.push_back(StackEntry(src, 1)); mStack.push_back(StackEntry(src, 2)); } void VDPixmapUberBlitterGenerator::rgb32_to_ycbcr709() { StackEntry *args = &mStack.back(); VDPixmapGenRGB32ToYCbCr709 *src = new VDPixmapGenRGB32ToYCbCr709; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); mStack.push_back(StackEntry(src, 1)); mStack.push_back(StackEntry(src, 2)); } void VDPixmapUberBlitterGenerator::ycbcr601_to_rgb32_32f() { StackEntry *args = &mStack.back() - 2; VDPixmapGenYCbCr601ToRGB32F *src = new VDPixmapGenYCbCr601ToRGB32F; src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); mStack.pop_back(); mStack.pop_back(); } void VDPixmapUberBlitterGenerator::ycbcr709_to_rgb32_32f() { StackEntry *args = &mStack.back() - 2; VDPixmapGenYCbCr709ToRGB32F *src = new VDPixmapGenYCbCr709ToRGB32F; src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); mStack.pop_back(); mStack.pop_back(); } void VDPixmapUberBlitterGenerator::rgb32_to_ycbcr601_32f() { StackEntry *args = &mStack.back(); VDPixmapGenRGB32FToYCbCr601 *src = new VDPixmapGenRGB32FToYCbCr601; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); mStack.push_back(StackEntry(src, 1)); mStack.push_back(StackEntry(src, 2)); } void VDPixmapUberBlitterGenerator::rgb32_to_ycbcr709_32f() { StackEntry *args = &mStack.back(); VDPixmapGenRGB32FToYCbCr709 *src = new VDPixmapGenRGB32FToYCbCr709; src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); mStack.push_back(StackEntry(src, 1)); mStack.push_back(StackEntry(src, 2)); } void VDPixmapUberBlitterGenerator::ycbcr601_to_ycbcr709() { StackEntry *args = &mStack.back() - 2; IVDPixmapGen *src; if ((args[0].mpSrc->GetType(args[0].mSrcIndex) & kVDPixType_Mask) == kVDPixType_32F_LE) { VDPixmapGenYCbCr601ToYCbCr709_32F *src2 = new VDPixmapGenYCbCr601ToYCbCr709_32F; src2->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); src = src2; } else { VDPixmapGenYCbCr601ToYCbCr709 *src2 = new VDPixmapGenYCbCr601ToYCbCr709; src2->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); src = src2; } mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); args[1] = StackEntry(src, 1); args[2] = StackEntry(src, 2); } void VDPixmapUberBlitterGenerator::ycbcr709_to_ycbcr601() { StackEntry *args = &mStack.back() - 2; IVDPixmapGen *src; if ((args[0].mpSrc->GetType(args[0].mSrcIndex) & kVDPixType_Mask) == kVDPixType_32F_LE) { VDPixmapGenYCbCr709ToYCbCr601_32F *src2 = new VDPixmapGenYCbCr709ToYCbCr601_32F; src2->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); src = src2; } else { VDPixmapGenYCbCr709ToYCbCr601 *src2 = new VDPixmapGenYCbCr709ToYCbCr601; src2->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); src = src2; } mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); args[1] = StackEntry(src, 1); args[2] = StackEntry(src, 2); } void VDPixmapUberBlitterGenerator::ycbcr_to_rgb32_generic(const VDPixmapGenYCbCrBasis& basis, bool studioRGB) { StackEntry *args = &mStack.back() - 2; VDPixmapGenYCbCrToRGB32Generic *src = new VDPixmapGenYCbCrToRGB32Generic(basis, studioRGB); src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); mStack.pop_back(); mStack.pop_back(); } void VDPixmapUberBlitterGenerator::ycbcr_to_rgb32f_generic(const VDPixmapGenYCbCrBasis& basis) { StackEntry *args = &mStack.back() - 2; VDPixmapGenYCbCrToRGB32FGeneric *src = new VDPixmapGenYCbCrToRGB32FGeneric(basis); src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); mStack.pop_back(); mStack.pop_back(); } void VDPixmapUberBlitterGenerator::rgb32_to_ycbcr_generic(const VDPixmapGenYCbCrBasis& basis, bool studioRGB, uint32 colorSpace) { StackEntry *args = &mStack.back(); VDPixmapGenRGB32ToYCbCrGeneric *src = new VDPixmapGenRGB32ToYCbCrGeneric(basis, studioRGB, colorSpace); src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); mStack.push_back(StackEntry(src, 1)); mStack.push_back(StackEntry(src, 2)); } void VDPixmapUberBlitterGenerator::rgb32f_to_ycbcr_generic(const VDPixmapGenYCbCrBasis& basis, uint32 colorSpace) { StackEntry *args = &mStack.back(); VDPixmapGenRGB32FToYCbCrGeneric *src = new VDPixmapGenRGB32FToYCbCrGeneric(basis, colorSpace); src->Init(args[0].mpSrc, args[0].mSrcIndex); mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); args[0] = StackEntry(src, 0); mStack.push_back(StackEntry(src, 1)); mStack.push_back(StackEntry(src, 2)); } void VDPixmapUberBlitterGenerator::ycbcr_to_ycbcr_generic(const VDPixmapGenYCbCrBasis& basisDst, bool dstLimitedRange, const VDPixmapGenYCbCrBasis& basisSrc, bool srcLimitedRange, uint32 colorSpace) { StackEntry *args = &mStack.back() - 2; IVDPixmapGen *src; if ((args[0].mpSrc->GetType(args[0].mSrcIndex) & kVDPixType_Mask) == kVDPixType_32F_LE) { VDPixmapGenYCbCrToYCbCrGeneric_32F *src2 = new VDPixmapGenYCbCrToYCbCrGeneric_32F(basisDst, dstLimitedRange, basisSrc, srcLimitedRange, colorSpace); src2->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); src = src2; } else { VDPixmapGenYCbCrToYCbCrGeneric *src2 = new VDPixmapGenYCbCrToYCbCrGeneric(basisDst, dstLimitedRange, basisSrc, srcLimitedRange, colorSpace); src2->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex); src = src2; } mGenerators.push_back(src); MarkDependency(src, args[0].mpSrc); MarkDependency(src, args[1].mpSrc); MarkDependency(src, args[2].mpSrc); args[0] = StackEntry(src, 0); args[1] = StackEntry(src, 1); args[2] = StackEntry(src, 2); } IVDPixmapBlitter *VDPixmapUberBlitterGenerator::create() { vdautoptr blitter(new VDPixmapUberBlitter); int numStackEntries = (int)mStack.size(); for(int i=0; i<3; ++i) { if (i < numStackEntries) { blitter->mOutputs[i].mpSrc = mStack[i].mpSrc; blitter->mOutputs[i].mSrcIndex = mStack[i].mSrcIndex; } else { blitter->mOutputs[i].mpSrc = NULL; blitter->mOutputs[i].mSrcIndex = 0; } } mStack.clear(); // If this blitter has three outputs, determine if outputs 1 and 2 are independent // from output 0. blitter->mbIndependentChromaPlanes = true; blitter->mbIndependentPlanes = true; if (numStackEntries >= 3) { int numGens = mGenerators.size(); vdfastvector genflags(numGens, 0); enum { kFlagStateful = 0x80, kFlagY = 0x01, kFlagCb = 0x02, kFlagCr = 0x04, kFlagYCbCr = 0x07 }; for(int i=0; i<3; ++i) genflags[std::find(mGenerators.begin(), mGenerators.end(), blitter->mOutputs[i].mpSrc) - mGenerators.begin()] |= (1 << i); for(int i=0; iIsStateful()) genflags[i] |= kFlagStateful; } while(!mDependencies.empty()) { const Dependency& dep = mDependencies.back(); genflags[dep.mSrcIdx] |= (genflags[dep.mDstIdx] & ~kFlagStateful); mDependencies.pop_back(); } for(int i=0; imbIndependentPlanes = false; break; case kFlagCb | kFlagY: case kFlagCr | kFlagY: case kFlagCr | kFlagCb | kFlagY: blitter->mbIndependentPlanes = false; blitter->mbIndependentChromaPlanes = false; break; } } } else if (numStackEntries >= 2) { int numGens = mGenerators.size(); vdfastvector genflags(numGens, 0); enum { kFlagStateful = 0x80, kFlagY = 0x01, kFlagC = 0x02, kFlagYC = 0x03 }; for(int i=0; i<2; ++i) genflags[std::find(mGenerators.begin(), mGenerators.end(), blitter->mOutputs[i].mpSrc) - mGenerators.begin()] |= (1 << i); for(int i=0; iIsStateful()) genflags[i] |= kFlagStateful; } while(!mDependencies.empty()) { const Dependency& dep = mDependencies.back(); genflags[dep.mSrcIdx] |= (genflags[dep.mDstIdx] & ~kFlagStateful); mDependencies.pop_back(); } for(int i=0; imbIndependentPlanes = false; blitter->mbIndependentChromaPlanes = false; break; } } } blitter->mGenerators.swap(mGenerators); blitter->mSources.swap(mSources); return blitter.release(); } void VDPixmapUberBlitterGenerator::MarkDependency(IVDPixmapGen *dst, IVDPixmapGen *src) { Generators::const_iterator it1(std::find(mGenerators.begin(), mGenerators.end(), dst)); Generators::const_iterator it2(std::find(mGenerators.begin(), mGenerators.end(), src)); VDASSERT(it1 != mGenerators.end()); VDASSERT(it2 != mGenerators.end()); int idx1 = it1 - mGenerators.begin(); int idx2 = it2 - mGenerators.begin(); Dependency dep = { idx1, idx2 }; mDependencies.push_back(dep); }