home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Kasumi / source / uberblit_gen.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  45.1 KB  |  1,598 lines

  1. #include <vd2/system/vdalloc.h>
  2. #include <vd2/Kasumi/pixmaputils.h>
  3. #include "uberblit.h"
  4. #include "uberblit_gen.h"
  5. #include "uberblit_fill.h"
  6. #include "uberblit_input.h"
  7. #include "uberblit_resample.h"
  8. #include "uberblit_resample_special.h"
  9. #include "uberblit_ycbcr.h"
  10. #include "uberblit_rgb.h"
  11. #include "uberblit_swizzle.h"
  12. #include "uberblit_pal.h"
  13. #include "uberblit_16f.h"
  14. #include "uberblit_v210.h"
  15.  
  16. #ifdef VD_CPU_X86
  17.     #include "uberblit_swizzle_x86.h"
  18.     #include "uberblit_ycbcr_x86.h"
  19.     #include "uberblit_rgb_x86.h"
  20.     #include "uberblit_resample_special_x86.h"
  21. #endif
  22.  
  23. void VDPixmapGenerate(void *dst, ptrdiff_t pitch, sint32 bpr, sint32 height, IVDPixmapGen *gen, int genIndex) {
  24.     for(sint32 y=0; y<height; ++y) {
  25.         memcpy(dst, gen->GetRow(y, genIndex), bpr);
  26.         vdptrstep(dst, pitch);
  27.     }
  28.     VDCPUCleanupExtensions();
  29. }
  30.  
  31. void VDPixmapGenerateFast(void *dst, ptrdiff_t pitch, sint32 height, IVDPixmapGen *gen) {
  32.     for(sint32 y=0; y<height; ++y) {
  33.         gen->ProcessRow(dst, y);
  34.         vdptrstep(dst, pitch);
  35.     }
  36.     VDCPUCleanupExtensions();
  37. }
  38.  
  39. ///////////////////////////////////////////////////////////////////////////////////////////////////
  40.  
  41. IVDPixmapBlitter *VDCreatePixmapUberBlitterDirectCopy(const VDPixmap& dst, const VDPixmap& src) {
  42.     return new VDPixmapUberBlitterDirectCopy;
  43. }
  44.  
  45. IVDPixmapBlitter *VDCreatePixmapUberBlitterDirectCopy(const VDPixmapLayout& dst, const VDPixmapLayout& src) {
  46.     return new VDPixmapUberBlitterDirectCopy;
  47. }
  48.  
  49. VDPixmapUberBlitterDirectCopy::VDPixmapUberBlitterDirectCopy() {
  50. }
  51.  
  52. VDPixmapUberBlitterDirectCopy::~VDPixmapUberBlitterDirectCopy() {
  53. }
  54.  
  55. void VDPixmapUberBlitterDirectCopy::Blit(const VDPixmap& dst, const VDPixmap& src) {
  56.     Blit(dst, NULL, src);
  57. }
  58.  
  59. void VDPixmapUberBlitterDirectCopy::Blit(const VDPixmap& dst, const vdrect32 *rDst, const VDPixmap& src) {
  60.     VDASSERT(dst.format == src.format);
  61.  
  62.     const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(dst.format);
  63.  
  64.     void *p = dst.data;
  65.     void *p2 = dst.data2;
  66.     void *p3 = dst.data3;
  67.     int w = dst.w;
  68.     int h = dst.h;
  69.  
  70.     if (formatInfo.qchunky)  {
  71.         w = (w + formatInfo.qw - 1) / formatInfo.qw;
  72.         h = -(-h >> formatInfo.qhbits);
  73.     }
  74.  
  75.     int w2 = -(-dst.w >> formatInfo.auxwbits);
  76.     int h2 = -(-dst.h >> formatInfo.auxhbits);
  77.  
  78.     if (rDst) {
  79.         int x1 = rDst->left;
  80.         int y1 = rDst->top;
  81.         int x2 = rDst->right;
  82.         int y2 = rDst->bottom;
  83.  
  84.         VDASSERT(x1 >= 0 && y1 >= 0 && x2 <= w && y2 <= h && x2 >= x1 && y2 >= y1);
  85.  
  86.         if (x2 < x1 || y2 < y1)
  87.             return;
  88.  
  89.         p = vdptroffset(dst.data, dst.pitch * y1 + x1 * formatInfo.qsize);
  90.         w = x2 - x1;
  91.         h = y2 - y1;
  92.  
  93.         if (formatInfo.auxbufs >= 1) {
  94.             VDASSERT(!((x1|x2) & ((1 << formatInfo.auxwbits) - 1)));
  95.             VDASSERT(!((y1|y2) & ((1 << formatInfo.auxhbits) - 1)));
  96.  
  97.             int ax1 = x1 >> formatInfo.auxwbits;
  98.             int ay1 = y1 >> formatInfo.auxhbits;
  99.             int ax2 = x2 >> formatInfo.auxwbits;
  100.             int ay2 = y2 >> formatInfo.auxhbits;
  101.  
  102.             p2 = vdptroffset(dst.data2, dst.pitch2 * ay1 + ax1);
  103.             w2 = ax2 - ax1;
  104.             h2 = ay2 - ay1;
  105.  
  106.             if (formatInfo.auxbufs >= 2)
  107.                 p3 = vdptroffset(dst.data3, dst.pitch3 * ay1 + ax1);
  108.         }
  109.     }
  110.  
  111.     uint32 bpr = formatInfo.qsize * w;
  112.  
  113.     VDMemcpyRect(p, dst.pitch, src.data, src.pitch, bpr, h);
  114.  
  115.     if (formatInfo.auxbufs >= 1) {
  116.         VDMemcpyRect(p2, dst.pitch2, src.data2, src.pitch2, w2 * formatInfo.auxsize, h2);
  117.  
  118.         if (formatInfo.auxbufs >= 2)
  119.             VDMemcpyRect(p3, dst.pitch3, src.data3, src.pitch3, w2 * formatInfo.auxsize, h2);
  120.     }
  121. }
  122.  
  123. ///////////////////////////////////////////////////////////////////////////////////////////////////
  124.  
  125. VDPixmapUberBlitter::VDPixmapUberBlitter() {
  126. }
  127.  
  128. VDPixmapUberBlitter::~VDPixmapUberBlitter() {
  129.     while(!mGenerators.empty()) {
  130.         delete mGenerators.back();
  131.         mGenerators.pop_back();
  132.     }
  133. }
  134.  
  135. void VDPixmapUberBlitter::Blit(const VDPixmap& dst, const VDPixmap& src) {
  136.     Blit(dst, NULL, src);
  137. }
  138.  
  139. void VDPixmapUberBlitter::Blit(const VDPixmap& dst, const vdrect32 *rDst, const VDPixmap& src) {
  140.     for(Sources::const_iterator it(mSources.begin()), itEnd(mSources.end()); it!=itEnd; ++it) {
  141.         const SourceEntry& se = *it;
  142.         const void *p;
  143.         ptrdiff_t pitch;
  144.  
  145.         switch(se.mSrcPlane) {
  146.             case 0:
  147.                 p = src.data;
  148.                 pitch = src.pitch;
  149.                 break;
  150.             case 1:
  151.                 p = src.data2;
  152.                 pitch = src.pitch2;
  153.                 break;
  154.             case 2:
  155.                 p = src.data3;
  156.                 pitch = src.pitch3;
  157.                 break;
  158.             default:
  159.                 VDASSERT(false);
  160.                 break;
  161.         }
  162.  
  163.         se.mpSrc->SetSource((const char *)p + pitch*se.mSrcY + se.mSrcX, pitch, src.palette);
  164.     }
  165.  
  166.     if (mOutputs[2].mpSrc) {
  167.         if (mbIndependentPlanes)
  168.             Blit3Separated(dst, rDst);
  169.         else if (mbIndependentChromaPlanes)
  170.             Blit3Split(dst, rDst);
  171.         else
  172.             Blit3(dst, rDst);
  173.     } else if (mOutputs[1].mpSrc) {
  174.         if (mbIndependentPlanes)
  175.             Blit2Separated(dst, rDst);
  176.         else
  177.             Blit2(dst, rDst);
  178.     } else
  179.         Blit(dst, rDst);
  180. }
  181.  
  182. void VDPixmapUberBlitter::Blit(const VDPixmap& dst, const vdrect32 *rDst) {
  183.     const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(dst.format);
  184.  
  185.     mOutputs[0].mpSrc->AddWindowRequest(0, 0);
  186.     mOutputs[0].mpSrc->Start();
  187.  
  188.     void *p = dst.data;
  189.     int w = dst.w;
  190.     int h = dst.h;
  191.  
  192.     if (formatInfo.qchunky) {
  193.         w = (w + formatInfo.qw - 1) / formatInfo.qw;
  194.         h = -(-h >> formatInfo.qhbits);
  195.     }
  196.  
  197.     if (rDst) {
  198.         int x1 = rDst->left;
  199.         int y1 = rDst->top;
  200.         int x2 = rDst->right;
  201.         int y2 = rDst->bottom;
  202.  
  203.         if (formatInfo.qchunky) {
  204.             x1 = x1 / formatInfo.qw;
  205.             y1 = y1 / formatInfo.qh;
  206.             x2 = (x2 + formatInfo.qw - 1) / formatInfo.qw;
  207.             y2 = (y2 + formatInfo.qh - 1) / formatInfo.qh;
  208.         }
  209.  
  210.         VDASSERT(x1 >= 0 && y1 >= 0 && x2 <= w && y2 <= h && x2 >= x1 && y2 >= y1);
  211.  
  212.         if (x2 < x1 || y2 < y1)
  213.             return;
  214.  
  215.         p = vdptroffset(dst.data, dst.pitch * y1 + x1 * formatInfo.qsize);
  216.         w = x2 - x1;
  217.         h = y2 - y1;
  218.     }
  219.  
  220.     uint32 bpr = formatInfo.qsize * w;
  221.  
  222.     if (mOutputs[0].mSrcIndex == 0)
  223.         VDPixmapGenerateFast(p, dst.pitch, h, mOutputs[0].mpSrc);
  224.     else
  225.         VDPixmapGenerate(p, dst.pitch, bpr, h, mOutputs[0].mpSrc, mOutputs[0].mSrcIndex);
  226. }
  227.  
  228. void VDPixmapUberBlitter::Blit3(const VDPixmap& px, const vdrect32 *rDst) {
  229.     const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(px.format);
  230.     IVDPixmapGen *gen = mOutputs[1].mpSrc;
  231.     int idx = mOutputs[1].mSrcIndex;
  232.     IVDPixmapGen *gen1 = mOutputs[2].mpSrc;
  233.     int idx1 = mOutputs[2].mSrcIndex;
  234.     IVDPixmapGen *gen2 = mOutputs[0].mpSrc;
  235.     int idx2 = mOutputs[0].mSrcIndex;
  236.  
  237.     gen->AddWindowRequest(0, 0);
  238.     gen->Start();
  239.     gen1->AddWindowRequest(0, 0);
  240.     gen1->Start();
  241.     gen2->AddWindowRequest(0, 0);
  242.     gen2->Start();
  243.  
  244.     uint32 auxstep = 0x80000000UL >> formatInfo.auxhbits;
  245.     uint32 auxaccum = 0;
  246.  
  247.     auxstep += auxstep;
  248.  
  249.     int qw = px.w;
  250.     int qh = px.h;
  251.  
  252.     if (formatInfo.qchunky) {
  253.         qw = (qw + formatInfo.qw - 1) / formatInfo.qw;
  254.         qh = -(-qh >> formatInfo.qhbits);
  255.     }
  256.  
  257.     uint32 height = qh;
  258.     uint32 bpr = formatInfo.qsize * qw;
  259.     uint32 bpr2 = formatInfo.auxsize * -(-px.w >> formatInfo.auxwbits);
  260.     uint8 *dst = (uint8 *)px.data;
  261.     uint8 *dst2 = (uint8 *)px.data2;
  262.     uint8 *dst3 = (uint8 *)px.data3;
  263.     ptrdiff_t pitch = px.pitch;
  264.     ptrdiff_t pitch2 = px.pitch2;
  265.     ptrdiff_t pitch3 = px.pitch3;
  266.     uint32 y2 = 0;
  267.     for(uint32 y=0; y<height; ++y) {
  268.         memcpy(dst, gen->GetRow(y, idx), bpr);
  269.         vdptrstep(dst, pitch);
  270.  
  271.         if (!auxaccum) {
  272.             memcpy(dst2, gen1->GetRow(y2, idx1), bpr2);
  273.             vdptrstep(dst2, pitch2);
  274.             memcpy(dst3, gen2->GetRow(y2, idx2), bpr2);
  275.             vdptrstep(dst3, pitch3);
  276.             ++y2;
  277.         }
  278.  
  279.         auxaccum += auxstep;
  280.     }
  281.  
  282.     VDCPUCleanupExtensions();
  283. }
  284.  
  285. void VDPixmapUberBlitter::Blit3Split(const VDPixmap& px, const vdrect32 *rDst) {
  286.     const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(px.format);
  287.     IVDPixmapGen *gen = mOutputs[1].mpSrc;
  288.     int idx = mOutputs[1].mSrcIndex;
  289.     IVDPixmapGen *gen1 = mOutputs[2].mpSrc;
  290.     int idx1 = mOutputs[2].mSrcIndex;
  291.     IVDPixmapGen *gen2 = mOutputs[0].mpSrc;
  292.     int idx2 = mOutputs[0].mSrcIndex;
  293.  
  294.     gen->AddWindowRequest(0, 0);
  295.     gen->Start();
  296.     gen1->AddWindowRequest(0, 0);
  297.     gen1->Start();
  298.     gen2->AddWindowRequest(0, 0);
  299.     gen2->Start();
  300.  
  301.     uint32 auxstep = 0x80000000UL >> formatInfo.auxhbits;
  302.     uint32 auxaccum = 0;
  303.  
  304.     auxstep += auxstep;
  305.  
  306.     int qw = px.w;
  307.     int qh = px.h;
  308.  
  309.     if (formatInfo.qchunky) {
  310.         qw = (qw + formatInfo.qw - 1) / formatInfo.qw;
  311.         qh = -(-qh >> formatInfo.qhbits);
  312.     }
  313.  
  314.     uint32 height = qh;
  315.     uint32 bpr = formatInfo.qsize * qw;
  316.     uint8 *dst = (uint8 *)px.data;
  317.     ptrdiff_t pitch = px.pitch;
  318.  
  319.     if (idx == 0) {
  320.         for(uint32 y=0; y<height; ++y) {
  321.             gen->ProcessRow(dst, y);
  322.             vdptrstep(dst, pitch);
  323.         }
  324.     } else {
  325.         for(uint32 y=0; y<height; ++y) {
  326.             memcpy(dst, gen->GetRow(y, idx), bpr);
  327.             vdptrstep(dst, pitch);
  328.         }
  329.     }
  330.  
  331.     uint32 bpr2 = -(-px.w >> formatInfo.auxwbits) * formatInfo.auxsize;
  332.     uint8 *dst2 = (uint8 *)px.data2;
  333.     uint8 *dst3 = (uint8 *)px.data3;
  334.     ptrdiff_t pitch2 = px.pitch2;
  335.     ptrdiff_t pitch3 = px.pitch3;
  336.     uint32 y2 = 0;
  337.     for(uint32 y=0; y<height; ++y) {
  338.         if (!auxaccum) {
  339.             memcpy(dst2, gen1->GetRow(y2, idx1), bpr2);
  340.             vdptrstep(dst2, pitch2);
  341.             memcpy(dst3, gen2->GetRow(y2, idx2), bpr2);
  342.             vdptrstep(dst3, pitch3);
  343.             ++y2;
  344.         }
  345.  
  346.         auxaccum += auxstep;
  347.     }
  348.  
  349.     VDCPUCleanupExtensions();
  350. }
  351.  
  352. void VDPixmapUberBlitter::Blit3Separated(const VDPixmap& px, const vdrect32 *rDst) {
  353.     const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(px.format);
  354.     IVDPixmapGen *gen = mOutputs[1].mpSrc;
  355.     int idx = mOutputs[1].mSrcIndex;
  356.     IVDPixmapGen *gen1 = mOutputs[2].mpSrc;
  357.     int idx1 = mOutputs[2].mSrcIndex;
  358.     IVDPixmapGen *gen2 = mOutputs[0].mpSrc;
  359.     int idx2 = mOutputs[0].mSrcIndex;
  360.  
  361.     gen->AddWindowRequest(0, 0);
  362.     gen->Start();
  363.     gen1->AddWindowRequest(0, 0);
  364.     gen1->Start();
  365.     gen2->AddWindowRequest(0, 0);
  366.     gen2->Start();
  367.  
  368.     int qw = px.w;
  369.     int qh = px.h;
  370.  
  371.     if (formatInfo.qchunky) {
  372.         qw = (qw + formatInfo.qw - 1) / formatInfo.qw;
  373.         qh = -(-qh >> formatInfo.qhbits);
  374.     }
  375.  
  376.     uint32 height = qh;
  377.     uint32 bpr = formatInfo.qsize * qw;
  378.     uint8 *dst = (uint8 *)px.data;
  379.     ptrdiff_t pitch = px.pitch;
  380.  
  381.     if (idx == 0) {
  382.         for(uint32 y=0; y<height; ++y) {
  383.             gen->ProcessRow(dst, y);
  384.             vdptrstep(dst, pitch);
  385.         }
  386.     } else {
  387.         for(uint32 y=0; y<height; ++y) {
  388.             memcpy(dst, gen->GetRow(y, idx), bpr);
  389.             vdptrstep(dst, pitch);
  390.         }
  391.     }
  392.  
  393.     uint32 bpr2 = -(-px.w >> formatInfo.auxwbits) * formatInfo.auxsize;
  394.     uint32 h2 = -(-px.h >> formatInfo.auxhbits);
  395.     uint8 *dst2 = (uint8 *)px.data2;
  396.     ptrdiff_t pitch2 = px.pitch2;
  397.     if (idx1 == 0) {
  398.         for(uint32 y2=0; y2<h2; ++y2) {
  399.             gen1->ProcessRow(dst2, y2);
  400.             vdptrstep(dst2, pitch2);
  401.         }
  402.     } else {
  403.         for(uint32 y2=0; y2<h2; ++y2) {
  404.             memcpy(dst2, gen1->GetRow(y2, idx1), bpr2);
  405.             vdptrstep(dst2, pitch2);
  406.         }
  407.     }
  408.  
  409.     uint8 *dst3 = (uint8 *)px.data3;
  410.     ptrdiff_t pitch3 = px.pitch3;
  411.     if (idx2 == 0) {
  412.         for(uint32 y2=0; y2<h2; ++y2) {
  413.             gen2->ProcessRow(dst3, y2);
  414.             vdptrstep(dst3, pitch3);
  415.         }
  416.     } else {
  417.         for(uint32 y2=0; y2<h2; ++y2) {
  418.             memcpy(dst3, gen2->GetRow(y2, idx2), bpr2);
  419.             vdptrstep(dst3, pitch3);
  420.         }
  421.     }
  422.  
  423.     VDCPUCleanupExtensions();
  424. }
  425.  
  426. void VDPixmapUberBlitter::Blit2(const VDPixmap& px, const vdrect32 *rDst) {
  427.     const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(px.format);
  428.     IVDPixmapGen *gen = mOutputs[0].mpSrc;
  429.     int idx = mOutputs[0].mSrcIndex;
  430.     IVDPixmapGen *gen1 = mOutputs[1].mpSrc;
  431.     int idx1 = mOutputs[1].mSrcIndex;
  432.  
  433.     gen->AddWindowRequest(0, 0);
  434.     gen->Start();
  435.     gen1->AddWindowRequest(0, 0);
  436.     gen1->Start();
  437.  
  438.     uint32 auxstep = 0x80000000UL >> formatInfo.auxhbits;
  439.     uint32 auxaccum = 0;
  440.  
  441.     auxstep += auxstep;
  442.  
  443.     int qw = px.w;
  444.     int qh = px.h;
  445.  
  446.     if (formatInfo.qchunky) {
  447.         qw = (qw + formatInfo.qw - 1) / formatInfo.qw;
  448.         qh = -(-qh >> formatInfo.qhbits);
  449.     }
  450.  
  451.     uint32 height = qh;
  452.     uint32 bpr = formatInfo.qsize * qw;
  453.     uint32 bpr2 = formatInfo.auxsize * -(-px.w >> formatInfo.auxwbits);
  454.     uint8 *dst = (uint8 *)px.data;
  455.     uint8 *dst2 = (uint8 *)px.data2;
  456.     ptrdiff_t pitch = px.pitch;
  457.     ptrdiff_t pitch2 = px.pitch2;
  458.     uint32 y2 = 0;
  459.     for(uint32 y=0; y<height; ++y) {
  460.         memcpy(dst, gen->GetRow(y, idx), bpr);
  461.         vdptrstep(dst, pitch);
  462.  
  463.         if (!auxaccum) {
  464.             memcpy(dst2, gen1->GetRow(y2, idx1), bpr2);
  465.             vdptrstep(dst2, pitch2);
  466.             ++y2;
  467.         }
  468.  
  469.         auxaccum += auxstep;
  470.     }
  471.  
  472.     VDCPUCleanupExtensions();
  473. }
  474.  
  475. void VDPixmapUberBlitter::Blit2Separated(const VDPixmap& px, const vdrect32 *rDst) {
  476.     const VDPixmapFormatInfo& formatInfo = VDPixmapGetInfo(px.format);
  477.     IVDPixmapGen *gen = mOutputs[0].mpSrc;
  478.     int idx = mOutputs[0].mSrcIndex;
  479.     IVDPixmapGen *gen1 = mOutputs[1].mpSrc;
  480.     int idx1 = mOutputs[1].mSrcIndex;
  481.  
  482.     gen->AddWindowRequest(0, 0);
  483.     gen->Start();
  484.     gen1->AddWindowRequest(0, 0);
  485.     gen1->Start();
  486.  
  487.     int qw = px.w;
  488.     int qh = px.h;
  489.  
  490.     if (formatInfo.qchunky) {
  491.         qw = (qw + formatInfo.qw - 1) / formatInfo.qw;
  492.         qh = -(-qh >> formatInfo.qhbits);
  493.     }
  494.  
  495.     uint32 height = qh;
  496.     uint32 bpr = formatInfo.qsize * qw;
  497.     uint8 *dst = (uint8 *)px.data;
  498.     ptrdiff_t pitch = px.pitch;
  499.  
  500.     if (idx == 0) {
  501.         for(uint32 y=0; y<height; ++y) {
  502.             gen->ProcessRow(dst, y);
  503.             vdptrstep(dst, pitch);
  504.         }
  505.     } else {
  506.         for(uint32 y=0; y<height; ++y) {
  507.             memcpy(dst, gen->GetRow(y, idx), bpr);
  508.             vdptrstep(dst, pitch);
  509.         }
  510.     }
  511.  
  512.     uint32 bpr2 = -(-px.w >> formatInfo.auxwbits) * formatInfo.auxsize;
  513.     uint32 h2 = -(-px.h >> formatInfo.auxhbits);
  514.     uint8 *dst2 = (uint8 *)px.data2;
  515.     ptrdiff_t pitch2 = px.pitch2;
  516.     if (idx1 == 0) {
  517.         for(uint32 y2=0; y2<h2; ++y2) {
  518.             gen1->ProcessRow(dst2, y2);
  519.             vdptrstep(dst2, pitch2);
  520.         }
  521.     } else {
  522.         for(uint32 y2=0; y2<h2; ++y2) {
  523.             memcpy(dst2, gen1->GetRow(y2, idx1), bpr2);
  524.             vdptrstep(dst2, pitch2);
  525.         }
  526.     }
  527.  
  528.     VDCPUCleanupExtensions();
  529. }
  530.  
  531. ///////////////////////////////////////////////////////////////////////////////////////////////////
  532. VDPixmapUberBlitterGenerator::VDPixmapUberBlitterGenerator() {
  533. }
  534.  
  535. VDPixmapUberBlitterGenerator::~VDPixmapUberBlitterGenerator() {
  536.     while(!mGenerators.empty()) {
  537.         delete mGenerators.back();
  538.         mGenerators.pop_back();
  539.     }
  540. }
  541.  
  542. void VDPixmapUberBlitterGenerator::swap(int index) {
  543.     std::swap(mStack.back(), (&mStack.back())[-index]);
  544. }
  545.  
  546. void VDPixmapUberBlitterGenerator::dup() {
  547.     mStack.push_back(mStack.back());
  548. }
  549.  
  550. void VDPixmapUberBlitterGenerator::pop() {
  551.     mStack.pop_back();
  552. }
  553.  
  554. void VDPixmapUberBlitterGenerator::ldsrc(int srcIndex, int srcPlane, int x, int y, uint32 w, uint32 h, uint32 type, uint32 bpr) {
  555.     VDPixmapGenSrc *src = new VDPixmapGenSrc;
  556.  
  557.     src->Init(w, h, type, bpr);
  558.  
  559.     mGenerators.push_back(src);
  560.     mStack.push_back(StackEntry(src, 0));
  561.  
  562.     SourceEntry se;
  563.     se.mpSrc = src;
  564.     se.mSrcIndex = srcIndex;
  565.     se.mSrcPlane = srcPlane;
  566.     se.mSrcX = x;
  567.     se.mSrcY = y;
  568.     mSources.push_back(se);
  569. }
  570.  
  571. void VDPixmapUberBlitterGenerator::ldconst(uint8 fill, uint32 bpr, uint32 w, uint32 h, uint32 type) {
  572.     VDPixmapGenFill8 *src = new VDPixmapGenFill8;
  573.  
  574.     src->Init(fill, bpr, w, h, type);
  575.  
  576.     mGenerators.push_back(src);
  577.     mStack.push_back(StackEntry(src, 0));
  578. }
  579.  
  580. void VDPixmapUberBlitterGenerator::extract_8in16(int offset, uint32 w, uint32 h) {
  581.     StackEntry *args = &mStack.back();
  582.     VDPixmapGen_8In16 *src = NULL;
  583.     
  584. #if VD_CPU_X86
  585.     if (MMX_enabled) {
  586.         if (offset == 0)
  587.             src = new VDPixmapGen_8In16_Even_MMX;
  588.         else if (offset == 1)
  589.             src = new VDPixmapGen_8In16_Odd_MMX;
  590.     }
  591. #endif
  592.     if (!src)
  593.         src = new VDPixmapGen_8In16;
  594.  
  595.     src->Init(args[0].mpSrc, args[0].mSrcIndex, offset, w, h);
  596.  
  597.     mGenerators.push_back(src);
  598.     MarkDependency(src, args[0].mpSrc);
  599.     args[0] = StackEntry(src, 0);
  600. }
  601.  
  602. void VDPixmapUberBlitterGenerator::extract_8in32(int offset, uint32 w, uint32 h) {
  603.     StackEntry *args = &mStack.back();
  604.     VDPixmapGen_8In32 *src = NULL;
  605.  
  606. #if VD_CPU_X86
  607.     if (MMX_enabled) {
  608.         if ((unsigned)offset < 4)
  609.             src = new VDPixmapGen_8In32_MMX;
  610.     }
  611. #endif
  612.  
  613.     if (!src)
  614.         src = new VDPixmapGen_8In32;
  615.  
  616.     src->Init(args[0].mpSrc, args[0].mSrcIndex, offset, w, h);
  617.  
  618.     mGenerators.push_back(src);
  619.     MarkDependency(src, args[0].mpSrc);
  620.     args[0] = StackEntry(src, 0);
  621. }
  622.  
  623. void VDPixmapUberBlitterGenerator::swap_8in16(uint32 w, uint32 h, uint32 bpr) {
  624.     StackEntry *args = &mStack.back();
  625.  
  626. #if VD_CPU_X86
  627.     VDPixmapGen_Swap8In16 *src = MMX_enabled ? new VDPixmapGen_Swap8In16_MMX : new VDPixmapGen_Swap8In16;
  628. #else
  629.     VDPixmapGen_Swap8In16 *src = new VDPixmapGen_Swap8In16;
  630. #endif
  631.  
  632.     src->Init(args[0].mpSrc, args[0].mSrcIndex, w, h, bpr);
  633.  
  634.     mGenerators.push_back(src);
  635.     MarkDependency(src, args[0].mpSrc);
  636.     args[0] = StackEntry(src, 0);
  637. }
  638.  
  639. void VDPixmapUberBlitterGenerator::conv_Pal1_to_8888(int srcIndex) {
  640.     StackEntry *args = &mStack.back();
  641.     VDPixmapGen_Pal1_To_X8R8G8B8 *src = new VDPixmapGen_Pal1_To_X8R8G8B8;
  642.  
  643.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  644.  
  645.     mGenerators.push_back(src);
  646.     MarkDependency(src, args[0].mpSrc);
  647.     args[0] = StackEntry(src, 0);
  648.  
  649.     SourceEntry se;
  650.     se.mpSrc = src;
  651.     se.mSrcIndex = srcIndex;
  652.     se.mSrcPlane = 0;
  653.     se.mSrcX = 0;
  654.     se.mSrcY = 0;
  655.     mSources.push_back(se);
  656. }
  657.  
  658. void VDPixmapUberBlitterGenerator::conv_Pal2_to_8888(int srcIndex) {
  659.     StackEntry *args = &mStack.back();
  660.     VDPixmapGen_Pal2_To_X8R8G8B8 *src = new VDPixmapGen_Pal2_To_X8R8G8B8;
  661.  
  662.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  663.  
  664.     mGenerators.push_back(src);
  665.     MarkDependency(src, args[0].mpSrc);
  666.     args[0] = StackEntry(src, 0);
  667.  
  668.     SourceEntry se;
  669.     se.mpSrc = src;
  670.     se.mSrcIndex = srcIndex;
  671.     se.mSrcPlane = 0;
  672.     se.mSrcX = 0;
  673.     se.mSrcY = 0;
  674.     mSources.push_back(se);
  675. }
  676.  
  677. void VDPixmapUberBlitterGenerator::conv_Pal4_to_8888(int srcIndex) {
  678.     StackEntry *args = &mStack.back();
  679.     VDPixmapGen_Pal4_To_X8R8G8B8 *src = new VDPixmapGen_Pal4_To_X8R8G8B8;
  680.  
  681.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  682.  
  683.     mGenerators.push_back(src);
  684.     MarkDependency(src, args[0].mpSrc);
  685.     args[0] = StackEntry(src, 0);
  686.  
  687.     SourceEntry se;
  688.     se.mpSrc = src;
  689.     se.mSrcIndex = srcIndex;
  690.     se.mSrcPlane = 0;
  691.     se.mSrcX = 0;
  692.     se.mSrcY = 0;
  693.     mSources.push_back(se);
  694. }
  695.  
  696. void VDPixmapUberBlitterGenerator::conv_Pal8_to_8888(int srcIndex) {
  697.     StackEntry *args = &mStack.back();
  698.     VDPixmapGen_Pal8_To_X8R8G8B8 *src = new VDPixmapGen_Pal8_To_X8R8G8B8;
  699.  
  700.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  701.  
  702.     mGenerators.push_back(src);
  703.     MarkDependency(src, args[0].mpSrc);
  704.     args[0] = StackEntry(src, 0);
  705.  
  706.     SourceEntry se;
  707.     se.mpSrc = src;
  708.     se.mSrcIndex = srcIndex;
  709.     se.mSrcPlane = 0;
  710.     se.mSrcX = 0;
  711.     se.mSrcY = 0;
  712.     mSources.push_back(se);
  713. }
  714.  
  715. void VDPixmapUberBlitterGenerator::pointh(float xoffset, float xfactor, uint32 w) {
  716.     StackEntry *args = &mStack.back();
  717.  
  718.     if (xoffset != 0.5f || xfactor != 1.0f) {
  719.         VDPixmapGenResampleRow *src = new VDPixmapGenResampleRow;
  720.  
  721.         src->Init(args[0].mpSrc, args[0].mSrcIndex, w, xoffset, xfactor, nsVDPixmap::kFilterPoint, 0, false);
  722.  
  723.         mGenerators.push_back(src);
  724.         MarkDependency(src, args[0].mpSrc);
  725.         args[0] = StackEntry(src, 0);
  726.     }
  727. }
  728.  
  729. void VDPixmapUberBlitterGenerator::pointv(float yoffset, float yfactor, uint32 h) {
  730.     StackEntry *args = &mStack.back();
  731.  
  732.     if (yoffset != 0.5f || yfactor != 1.0f) {
  733.         VDPixmapGenResampleCol *src = new VDPixmapGenResampleCol;
  734.  
  735.         src->Init(args[0].mpSrc, args[0].mSrcIndex, h, yoffset, yfactor, nsVDPixmap::kFilterPoint, 0, false);
  736.  
  737.         mGenerators.push_back(src);
  738.         MarkDependency(src, args[0].mpSrc);
  739.         args[0] = StackEntry(src, 0);
  740.     }
  741. }
  742.  
  743. void VDPixmapUberBlitterGenerator::linearh(float xoffset, float xfactor, uint32 w, bool interpOnly) {
  744.     StackEntry *args = &mStack.back();
  745.     IVDPixmapGen *src = args[0].mpSrc;
  746.     int srcIndex = args[0].mSrcIndex;
  747.  
  748.     sint32 srcw = src->GetWidth(srcIndex);
  749.     if (xoffset == 0.5f && xfactor == 1.0f && srcw == w)
  750.         return;
  751.  
  752.     if (xoffset == 0.5f && (src->GetType(srcIndex) & kVDPixType_Mask) == kVDPixType_8) {
  753.         if (xfactor == 2.0f && w == ((srcw + 1) >> 1)) {
  754.             VDPixmapGenResampleRow_d2_p0_lin_u8 *out = new VDPixmapGenResampleRow_d2_p0_lin_u8;
  755.  
  756.             out->Init(src, srcIndex);
  757.             mGenerators.push_back(out);
  758.             MarkDependency(out, src);
  759.             args[0] = StackEntry(out, 0);
  760.             return;
  761.         }
  762.  
  763.         if (xfactor == 4.0f && w == ((srcw + 3) >> 2)) {
  764.             VDPixmapGenResampleRow_d4_p0_lin_u8 *out = new VDPixmapGenResampleRow_d4_p0_lin_u8;
  765.  
  766.             out->Init(src, srcIndex);
  767.             mGenerators.push_back(out);
  768.             MarkDependency(out, src);
  769.             args[0] = StackEntry(out, 0);
  770.             return;
  771.         }
  772.  
  773.         if (xfactor == 0.5f && w == srcw*2) {
  774. #if VD_CPU_X86
  775.             VDPixmapGenResampleRow_x2_p0_lin_u8 *out = ISSE_enabled ? new VDPixmapGenResampleRow_x2_p0_lin_u8_ISSE : new VDPixmapGenResampleRow_x2_p0_lin_u8;
  776. #else
  777.             VDPixmapGenResampleRow_x2_p0_lin_u8 *out = new VDPixmapGenResampleRow_x2_p0_lin_u8;
  778. #endif
  779.  
  780.             out->Init(src, srcIndex);
  781.             mGenerators.push_back(out);
  782.             MarkDependency(out, src);
  783.             args[0] = StackEntry(out, 0);
  784.             return;
  785.         }
  786.  
  787.         if (xfactor == 0.25f && w == srcw*4) {
  788. #if VD_CPU_X86
  789.             VDPixmapGenResampleRow_x4_p0_lin_u8 *out = MMX_enabled ? new VDPixmapGenResampleRow_x4_p0_lin_u8_MMX : new VDPixmapGenResampleRow_x4_p0_lin_u8;
  790. #else
  791.             VDPixmapGenResampleRow_x4_p0_lin_u8 *out = new VDPixmapGenResampleRow_x4_p0_lin_u8;
  792. #endif
  793.  
  794.             out->Init(src, srcIndex);
  795.             mGenerators.push_back(out);
  796.             MarkDependency(out, src);
  797.             args[0] = StackEntry(out, 0);
  798.             return;
  799.         }
  800.     }
  801.  
  802.     VDPixmapGenResampleRow *out = new VDPixmapGenResampleRow;
  803.  
  804.     out->Init(args[0].mpSrc, args[0].mSrcIndex, w, xoffset, xfactor, nsVDPixmap::kFilterLinear, 0, interpOnly);
  805.  
  806.     mGenerators.push_back(out);
  807.     MarkDependency(out, src);
  808.     args[0] = StackEntry(out, 0);
  809. }
  810.  
  811. void VDPixmapUberBlitterGenerator::linearv(float yoffset, float yfactor, uint32 h, bool interpOnly) {
  812.     StackEntry *args = &mStack.back();
  813.     IVDPixmapGen *src = args[0].mpSrc;
  814.     int srcIndex = args[0].mSrcIndex;
  815.  
  816.     sint32 srch = src->GetHeight(srcIndex);
  817.     if (yoffset == 0.5f && yfactor == 1.0f && srch == h)
  818.         return;
  819.  
  820.     if ((src->GetType(srcIndex) & kVDPixType_Mask) == kVDPixType_8) {
  821.         if (yoffset == 1.0f && yfactor == 2.0f && h == ((srch + 1) >> 1)) {
  822.             VDPixmapGenResampleCol_x2_phalf_lin_u8 *out = new VDPixmapGenResampleCol_x2_phalf_lin_u8;
  823.  
  824.             out->Init(src, srcIndex);
  825.             mGenerators.push_back(out);
  826.             MarkDependency(out, src);
  827.             args[0] = StackEntry(out, 0);
  828.             return;
  829.         }
  830.  
  831.         if (yoffset == 2.0f && yfactor == 4.0f && h == ((srch + 2) >> 2)) {
  832.             VDPixmapGenResampleCol_x4_p1half_lin_u8 *out = new VDPixmapGenResampleCol_x4_p1half_lin_u8;
  833.  
  834.             out->Init(src, srcIndex);
  835.             mGenerators.push_back(out);
  836.             MarkDependency(out, src);
  837.             args[0] = StackEntry(out, 0);
  838.             return;
  839.         }
  840.  
  841.         if (yoffset == 0.25f && yfactor == 0.5f && h == srch*2) {
  842. #if VD_CPU_X86
  843.             VDPixmapGenResampleCol_d2_pnqrtr_lin_u8 *out = ISSE_enabled ? new VDPixmapGenResampleCol_d2_pnqrtr_lin_u8_ISSE : new VDPixmapGenResampleCol_d2_pnqrtr_lin_u8;
  844. #else
  845.             VDPixmapGenResampleCol_d2_pnqrtr_lin_u8 *out = new VDPixmapGenResampleCol_d2_pnqrtr_lin_u8;
  846. #endif
  847.  
  848.             out->Init(src, srcIndex);
  849.             mGenerators.push_back(out);
  850.             MarkDependency(out, src);
  851.             args[0] = StackEntry(out, 0);
  852.             return;
  853.         }
  854.  
  855.         if (yoffset == 0.125f && yfactor == 0.25f && h == srch*4) {
  856. #if VD_CPU_X86
  857.             VDPixmapGenResampleCol_d4_pn38_lin_u8 *out = ISSE_enabled ? new VDPixmapGenResampleCol_d4_pn38_lin_u8_ISSE : new VDPixmapGenResampleCol_d4_pn38_lin_u8;
  858. #else
  859.             VDPixmapGenResampleCol_d4_pn38_lin_u8 *out = new VDPixmapGenResampleCol_d4_pn38_lin_u8;
  860. #endif
  861.  
  862.             out->Init(src, srcIndex);
  863.             mGenerators.push_back(out);
  864.             MarkDependency(out, src);
  865.             args[0] = StackEntry(out, 0);
  866.             return;
  867.         }
  868.     }
  869.  
  870.     VDPixmapGenResampleCol *out = new VDPixmapGenResampleCol;
  871.  
  872.     out->Init(src, srcIndex, h, yoffset, yfactor, nsVDPixmap::kFilterLinear, 0, interpOnly);
  873.  
  874.     mGenerators.push_back(out);
  875.     MarkDependency(out, src);
  876.     args[0] = StackEntry(out, 0);
  877. }
  878.  
  879. void VDPixmapUberBlitterGenerator::linear(float xoffset, float xfactor, uint32 w, float yoffset, float yfactor, uint32 h) {
  880.     linearh(xoffset, xfactor, w, false);
  881.     linearv(yoffset, yfactor, h, false);
  882. }
  883.  
  884. void VDPixmapUberBlitterGenerator::cubich(float xoffset, float xfactor, uint32 w, float splineFactor, bool interpOnly) {
  885.     StackEntry *args = &mStack.back();
  886.  
  887.     if (xoffset != 0.5f || xfactor != 1.0f) {
  888.         VDPixmapGenResampleRow *src = new VDPixmapGenResampleRow;
  889.  
  890.         src->Init(args[0].mpSrc, args[0].mSrcIndex, w, xoffset, xfactor, nsVDPixmap::kFilterCubic, splineFactor, interpOnly);
  891.  
  892.         mGenerators.push_back(src);
  893.         MarkDependency(src, args[0].mpSrc);
  894.         args[0] = StackEntry(src, 0);
  895.     }
  896. }
  897.  
  898. void VDPixmapUberBlitterGenerator::cubicv(float yoffset, float yfactor, uint32 h, float splineFactor, bool interpOnly) {
  899.     StackEntry *args = &mStack.back();
  900.  
  901.     if (yoffset != 0.5f || yfactor != 1.0f) {
  902.         VDPixmapGenResampleCol *src = new VDPixmapGenResampleCol;
  903.  
  904.         src->Init(args[0].mpSrc, args[0].mSrcIndex, h, yoffset, yfactor, nsVDPixmap::kFilterCubic, splineFactor, interpOnly);
  905.  
  906.         mGenerators.push_back(src);
  907.         MarkDependency(src, args[0].mpSrc);
  908.         args[0] = StackEntry(src, 0);
  909.     }
  910. }
  911.  
  912. void VDPixmapUberBlitterGenerator::cubic(float xoffset, float xfactor, uint32 w, float yoffset, float yfactor, uint32 h, float splineFactor) {
  913.     cubich(xoffset, xfactor, w, splineFactor, false);
  914.     cubicv(yoffset, yfactor, h, splineFactor, false);
  915. }
  916.  
  917. void VDPixmapUberBlitterGenerator::lanczos3h(float xoffset, float xfactor, uint32 w) {
  918.     StackEntry *args = &mStack.back();
  919.  
  920.     if (xoffset != 0.5f || xfactor != 1.0f) {
  921.         VDPixmapGenResampleRow *src = new VDPixmapGenResampleRow;
  922.  
  923.         src->Init(args[0].mpSrc, args[0].mSrcIndex, w, xoffset, xfactor, nsVDPixmap::kFilterLanczos3, 0, false);
  924.  
  925.         mGenerators.push_back(src);
  926.         MarkDependency(src, args[0].mpSrc);
  927.         args[0] = StackEntry(src, 0);
  928.     }
  929. }
  930.  
  931. void VDPixmapUberBlitterGenerator::lanczos3v(float yoffset, float yfactor, uint32 h) {
  932.     StackEntry *args = &mStack.back();
  933.  
  934.     if (yoffset != 0.5f || yfactor != 1.0f) {
  935.         VDPixmapGenResampleCol *src = new VDPixmapGenResampleCol;
  936.  
  937.         src->Init(args[0].mpSrc, args[0].mSrcIndex, h, yoffset, yfactor, nsVDPixmap::kFilterLanczos3, 0, false);
  938.  
  939.         mGenerators.push_back(src);
  940.         MarkDependency(src, args[0].mpSrc);
  941.         args[0] = StackEntry(src, 0);
  942.     }
  943. }
  944.  
  945. void VDPixmapUberBlitterGenerator::lanczos3(float xoffset, float xfactor, uint32 w, float yoffset, float yfactor, uint32 h) {
  946.     lanczos3h(xoffset, xfactor, w);
  947.     lanczos3v(yoffset, yfactor, h);
  948. }
  949.  
  950. void VDPixmapUberBlitterGenerator::conv_555_to_8888() {
  951.     StackEntry *args = &mStack.back();
  952. #ifdef VD_CPU_X86
  953.     VDPixmapGen_X1R5G5B5_To_X8R8G8B8 *src = MMX_enabled ? new VDPixmapGen_X1R5G5B5_To_X8R8G8B8_MMX : new VDPixmapGen_X1R5G5B5_To_X8R8G8B8;
  954. #else
  955.     VDPixmapGen_X1R5G5B5_To_X8R8G8B8 *src = new VDPixmapGen_X1R5G5B5_To_X8R8G8B8;
  956. #endif
  957.  
  958.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  959.  
  960.     mGenerators.push_back(src);
  961.     MarkDependency(src, args[0].mpSrc);
  962.     args[0] = StackEntry(src, 0);
  963. }
  964.  
  965. void VDPixmapUberBlitterGenerator::conv_565_to_8888() {
  966.     StackEntry *args = &mStack.back();
  967. #ifdef VD_CPU_X86
  968.     VDPixmapGen_R5G6B5_To_X8R8G8B8 *src = MMX_enabled ? new VDPixmapGen_R5G6B5_To_X8R8G8B8_MMX : new VDPixmapGen_R5G6B5_To_X8R8G8B8;
  969. #else
  970.     VDPixmapGen_R5G6B5_To_X8R8G8B8 *src = new VDPixmapGen_R5G6B5_To_X8R8G8B8;
  971. #endif
  972.  
  973.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  974.  
  975.     mGenerators.push_back(src);
  976.     MarkDependency(src, args[0].mpSrc);
  977.     args[0] = StackEntry(src, 0);
  978. }
  979.  
  980. void VDPixmapUberBlitterGenerator::conv_888_to_8888() {
  981.     StackEntry *args = &mStack.back();
  982. #ifdef VD_CPU_X86
  983.     VDPixmapGen_R8G8B8_To_A8R8G8B8 *src = MMX_enabled ? new VDPixmapGen_R8G8B8_To_X8R8G8B8_MMX : new VDPixmapGen_R8G8B8_To_A8R8G8B8;
  984. #else
  985.     VDPixmapGen_R8G8B8_To_A8R8G8B8 *src = new VDPixmapGen_R8G8B8_To_A8R8G8B8;
  986. #endif
  987.  
  988.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  989.  
  990.     mGenerators.push_back(src);
  991.     MarkDependency(src, args[0].mpSrc);
  992.     args[0] = StackEntry(src, 0);
  993. }
  994.  
  995. void VDPixmapUberBlitterGenerator::conv_8_to_32F() {
  996.     StackEntry *args = &mStack.back();
  997.     VDPixmapGen_8_To_32F *src = new VDPixmapGen_8_To_32F;
  998.  
  999.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1000.  
  1001.     mGenerators.push_back(src);
  1002.     MarkDependency(src, args[0].mpSrc);
  1003.     args[0] = StackEntry(src, 0);
  1004. }
  1005.  
  1006. void VDPixmapUberBlitterGenerator::conv_16F_to_32F() {
  1007.     StackEntry *args = &mStack.back();
  1008.     VDPixmapGen_16F_To_32F *src = new VDPixmapGen_16F_To_32F;
  1009.  
  1010.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1011.  
  1012.     mGenerators.push_back(src);
  1013.     MarkDependency(src, args[0].mpSrc);
  1014.     args[0] = StackEntry(src, 0);
  1015. }
  1016.  
  1017. void VDPixmapUberBlitterGenerator::conv_V210_to_32F() {
  1018.     StackEntry *args = &mStack.back();
  1019.     VDPixmapGen_V210_To_32F *src = new VDPixmapGen_V210_To_32F;
  1020.  
  1021.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1022.  
  1023.     mGenerators.push_back(src);
  1024.     MarkDependency(src, args[0].mpSrc);
  1025.     args[0] = StackEntry(src, 0);
  1026.     mStack.push_back(StackEntry(src, 1));
  1027.     mStack.push_back(StackEntry(src, 2));
  1028. }
  1029.  
  1030. void VDPixmapUberBlitterGenerator::conv_8888_to_X32F() {
  1031.     StackEntry *args = &mStack.back();
  1032.     VDPixmapGen_X8R8G8B8_To_X32B32G32R32F *src = new VDPixmapGen_X8R8G8B8_To_X32B32G32R32F;
  1033.  
  1034.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1035.  
  1036.     mGenerators.push_back(src);
  1037.     MarkDependency(src, args[0].mpSrc);
  1038.     args[0] = StackEntry(src, 0);
  1039. }
  1040.  
  1041. void VDPixmapUberBlitterGenerator::conv_8888_to_555() {
  1042.     StackEntry *args = &mStack.back();
  1043. #ifdef VD_CPU_X86
  1044.     VDPixmapGen_X8R8G8B8_To_X1R5G5B5 *src = MMX_enabled ? new VDPixmapGen_X8R8G8B8_To_X1R5G5B5_MMX : new VDPixmapGen_X8R8G8B8_To_X1R5G5B5;
  1045. #else
  1046.     VDPixmapGen_X8R8G8B8_To_X1R5G5B5 *src = new VDPixmapGen_X8R8G8B8_To_X1R5G5B5;
  1047. #endif
  1048.  
  1049.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1050.  
  1051.     mGenerators.push_back(src);
  1052.     MarkDependency(src, args[0].mpSrc);
  1053.     args[0] = StackEntry(src, 0);
  1054. }
  1055.  
  1056. void VDPixmapUberBlitterGenerator::conv_555_to_565() {
  1057.     StackEntry *args = &mStack.back();
  1058. #ifdef VD_CPU_X86
  1059.     VDPixmapGen_X1R5G5B5_To_R5G6B5 *src = MMX_enabled ? new VDPixmapGen_X1R5G5B5_To_R5G6B5_MMX : new VDPixmapGen_X1R5G5B5_To_R5G6B5;
  1060. #else
  1061.     VDPixmapGen_X1R5G5B5_To_R5G6B5 *src = new VDPixmapGen_X1R5G5B5_To_R5G6B5;
  1062. #endif
  1063.  
  1064.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1065.  
  1066.     mGenerators.push_back(src);
  1067.     MarkDependency(src, args[0].mpSrc);
  1068.     args[0] = StackEntry(src, 0);
  1069. }
  1070.  
  1071. void VDPixmapUberBlitterGenerator::conv_565_to_555() {
  1072.     StackEntry *args = &mStack.back();
  1073. #ifdef VD_CPU_X86
  1074.     VDPixmapGen_R5G6B5_To_X1R5G5B5 *src = MMX_enabled ? new VDPixmapGen_R5G6B5_To_X1R5G5B5_MMX : new VDPixmapGen_R5G6B5_To_X1R5G5B5;
  1075. #else
  1076.     VDPixmapGen_R5G6B5_To_X1R5G5B5 *src = new VDPixmapGen_R5G6B5_To_X1R5G5B5;
  1077. #endif
  1078.  
  1079.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1080.  
  1081.     mGenerators.push_back(src);
  1082.     MarkDependency(src, args[0].mpSrc);
  1083.     args[0] = StackEntry(src, 0);
  1084. }
  1085.  
  1086. void VDPixmapUberBlitterGenerator::conv_8888_to_565() {
  1087.     StackEntry *args = &mStack.back();
  1088. #ifdef VD_CPU_X86
  1089.     VDPixmapGen_X8R8G8B8_To_R5G6B5 *src = MMX_enabled ? new VDPixmapGen_X8R8G8B8_To_R5G6B5_MMX : new VDPixmapGen_X8R8G8B8_To_R5G6B5;
  1090. #else
  1091.     VDPixmapGen_X8R8G8B8_To_R5G6B5 *src = new VDPixmapGen_X8R8G8B8_To_R5G6B5;
  1092. #endif
  1093.  
  1094.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1095.  
  1096.     mGenerators.push_back(src);
  1097.     MarkDependency(src, args[0].mpSrc);
  1098.     args[0] = StackEntry(src, 0);
  1099. }
  1100.  
  1101. void VDPixmapUberBlitterGenerator::conv_8888_to_888() {
  1102.     StackEntry *args = &mStack.back();
  1103. #ifdef VD_CPU_X86
  1104.     VDPixmapGen_X8R8G8B8_To_R8G8B8 *src = MMX_enabled ? new VDPixmapGen_X8R8G8B8_To_R8G8B8_MMX : new VDPixmapGen_X8R8G8B8_To_R8G8B8;
  1105. #else
  1106.     VDPixmapGen_X8R8G8B8_To_R8G8B8 *src = new VDPixmapGen_X8R8G8B8_To_R8G8B8;
  1107. #endif
  1108.  
  1109.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1110.  
  1111.     mGenerators.push_back(src);
  1112.     MarkDependency(src, args[0].mpSrc);
  1113.     args[0] = StackEntry(src, 0);
  1114. }
  1115.  
  1116. void VDPixmapUberBlitterGenerator::conv_32F_to_8() {
  1117.     StackEntry *args = &mStack.back();
  1118.     VDPixmapGen_32F_To_8 *src = new VDPixmapGen_32F_To_8;
  1119.  
  1120.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1121.  
  1122.     mGenerators.push_back(src);
  1123.     MarkDependency(src, args[0].mpSrc);
  1124.     args[0] = StackEntry(src, 0);
  1125. }
  1126.  
  1127. void VDPixmapUberBlitterGenerator::conv_X32F_to_8888() {
  1128.     StackEntry *args = &mStack.back();
  1129.     VDPixmapGen_X32B32G32R32F_To_X8R8G8B8 *src = new VDPixmapGen_X32B32G32R32F_To_X8R8G8B8;
  1130.  
  1131.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1132.  
  1133.     mGenerators.push_back(src);
  1134.     MarkDependency(src, args[0].mpSrc);
  1135.     args[0] = StackEntry(src, 0);
  1136. }
  1137.  
  1138. void VDPixmapUberBlitterGenerator::conv_32F_to_16F() {
  1139.     StackEntry *args = &mStack.back();
  1140.     VDPixmapGen_32F_To_16F *src = new VDPixmapGen_32F_To_16F;
  1141.  
  1142.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1143.  
  1144.     mGenerators.push_back(src);
  1145.     MarkDependency(src, args[0].mpSrc);
  1146.     args[0] = StackEntry(src, 0);
  1147. }
  1148.  
  1149. void VDPixmapUberBlitterGenerator::conv_32F_to_V210() {
  1150.     StackEntry *args = &*(mStack.end() - 3);
  1151.     VDPixmapGen_32F_To_V210 *src = new VDPixmapGen_32F_To_V210;
  1152.  
  1153.     src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
  1154.  
  1155.     mGenerators.push_back(src);
  1156.     MarkDependency(src, args[0].mpSrc);
  1157.     MarkDependency(src, args[1].mpSrc);
  1158.     MarkDependency(src, args[2].mpSrc);
  1159.     args[0] = StackEntry(src, 0);
  1160.     mStack.pop_back();
  1161.     mStack.pop_back();
  1162. }
  1163.  
  1164. void VDPixmapUberBlitterGenerator::convd_8888_to_555() {
  1165.     StackEntry *args = &mStack.back();
  1166.     VDPixmapGen_X8R8G8B8_To_X1R5G5B5_Dithered *src = new VDPixmapGen_X8R8G8B8_To_X1R5G5B5_Dithered;
  1167.  
  1168.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1169.  
  1170.     mGenerators.push_back(src);
  1171.     MarkDependency(src, args[0].mpSrc);
  1172.     args[0] = StackEntry(src, 0);
  1173. }
  1174.  
  1175. void VDPixmapUberBlitterGenerator::convd_8888_to_565() {
  1176.     StackEntry *args = &mStack.back();
  1177.     VDPixmapGen_X8R8G8B8_To_R5G6B5_Dithered *src = new VDPixmapGen_X8R8G8B8_To_R5G6B5_Dithered;
  1178.  
  1179.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1180.  
  1181.     mGenerators.push_back(src);
  1182.     MarkDependency(src, args[0].mpSrc);
  1183.     args[0] = StackEntry(src, 0);
  1184. }
  1185.  
  1186. void VDPixmapUberBlitterGenerator::convd_32F_to_8() {
  1187.     StackEntry *args = &mStack.back();
  1188.     VDPixmapGen_32F_To_8_Dithered *src = new VDPixmapGen_32F_To_8_Dithered;
  1189.  
  1190.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1191.  
  1192.     mGenerators.push_back(src);
  1193.     MarkDependency(src, args[0].mpSrc);
  1194.     args[0] = StackEntry(src, 0);
  1195. }
  1196.  
  1197. void VDPixmapUberBlitterGenerator::convd_X32F_to_8888() {
  1198.     StackEntry *args = &mStack.back();
  1199.     VDPixmapGen_X32B32G32R32F_To_X8R8G8B8_Dithered *src = new VDPixmapGen_X32B32G32R32F_To_X8R8G8B8_Dithered;
  1200.  
  1201.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1202.  
  1203.     mGenerators.push_back(src);
  1204.     MarkDependency(src, args[0].mpSrc);
  1205.     args[0] = StackEntry(src, 0);
  1206. }
  1207.  
  1208. void VDPixmapUberBlitterGenerator::interleave_B8G8_R8G8() {
  1209.     StackEntry *args = &mStack.back() - 2;
  1210.     VDPixmapGen_B8x3_To_B8G8_R8G8 *src = NULL;
  1211.     
  1212. #if VD_CPU_X86
  1213.     if (MMX_enabled)
  1214.         src = new VDPixmapGen_B8x3_To_B8G8_R8G8_MMX;
  1215. #endif
  1216.  
  1217.     if (!src)
  1218.         src = new VDPixmapGen_B8x3_To_B8G8_R8G8;
  1219.  
  1220.     src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
  1221.  
  1222.     mGenerators.push_back(src);
  1223.     MarkDependency(src, args[0].mpSrc);
  1224.     MarkDependency(src, args[1].mpSrc);
  1225.     MarkDependency(src, args[2].mpSrc);
  1226.     args[0] = StackEntry(src, 0);
  1227.     mStack.pop_back();
  1228.     mStack.pop_back();
  1229. }
  1230.  
  1231. void VDPixmapUberBlitterGenerator::interleave_G8B8_G8R8() {
  1232.     StackEntry *args = &mStack.back() - 2;
  1233.     VDPixmapGen_B8x3_To_G8B8_G8R8 *src = NULL;
  1234.     
  1235. #if VD_CPU_X86
  1236.     if (MMX_enabled)
  1237.         src = new VDPixmapGen_B8x3_To_G8B8_G8R8_MMX;
  1238. #endif
  1239.  
  1240.     if (!src)
  1241.         src = new VDPixmapGen_B8x3_To_G8B8_G8R8;
  1242.  
  1243.     src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
  1244.  
  1245.     mGenerators.push_back(src);
  1246.     MarkDependency(src, args[0].mpSrc);
  1247.     MarkDependency(src, args[1].mpSrc);
  1248.     MarkDependency(src, args[2].mpSrc);
  1249.     args[0] = StackEntry(src, 0);
  1250.     mStack.pop_back();
  1251.     mStack.pop_back();
  1252. }
  1253.  
  1254. void VDPixmapUberBlitterGenerator::interleave_X8R8G8B8() {
  1255.     StackEntry *args = &mStack.back() - 2;
  1256.     VDPixmapGen_B8x3_To_X8R8G8B8 *src = new VDPixmapGen_B8x3_To_X8R8G8B8;
  1257.  
  1258.     src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
  1259.  
  1260.     mGenerators.push_back(src);
  1261.     MarkDependency(src, args[0].mpSrc);
  1262.     MarkDependency(src, args[1].mpSrc);
  1263.     MarkDependency(src, args[2].mpSrc);
  1264.     args[0] = StackEntry(src, 0);
  1265.     mStack.pop_back();
  1266.     mStack.pop_back();
  1267. }
  1268.  
  1269. void VDPixmapUberBlitterGenerator::interleave_B8R8() {
  1270.     StackEntry *args = &mStack.back() - 1;
  1271.  
  1272. #if VD_CPU_X86
  1273.     VDPixmapGen_B8x2_To_B8R8 *src = MMX_enabled ? new VDPixmapGen_B8x2_To_B8R8_MMX : new VDPixmapGen_B8x2_To_B8R8;
  1274. #else
  1275.     VDPixmapGen_B8x2_To_B8R8 *src = new VDPixmapGen_B8x2_To_B8R8;
  1276. #endif
  1277.  
  1278.     src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex);
  1279.  
  1280.     mGenerators.push_back(src);
  1281.     MarkDependency(src, args[0].mpSrc);
  1282.     MarkDependency(src, args[1].mpSrc);
  1283.     args[0] = StackEntry(src, 0);
  1284.     mStack.pop_back();
  1285. }
  1286.  
  1287. void VDPixmapUberBlitterGenerator::ycbcr601_to_rgb32() {
  1288.     StackEntry *args = &mStack.back() - 2;
  1289.  
  1290. #ifdef VD_CPU_X86
  1291.     VDPixmapGenYCbCr601ToRGB32 *src = MMX_enabled ? new VDPixmapGenYCbCr601ToRGB32_MMX : new VDPixmapGenYCbCr601ToRGB32;
  1292. #else
  1293.     VDPixmapGenYCbCr601ToRGB32 *src = new VDPixmapGenYCbCr601ToRGB32;
  1294. #endif
  1295.  
  1296.     src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
  1297.  
  1298.     mGenerators.push_back(src);
  1299.     MarkDependency(src, args[0].mpSrc);
  1300.     MarkDependency(src, args[1].mpSrc);
  1301.     MarkDependency(src, args[2].mpSrc);
  1302.     args[0] = StackEntry(src, 0);
  1303.     mStack.pop_back();
  1304.     mStack.pop_back();
  1305. }
  1306.  
  1307. void VDPixmapUberBlitterGenerator::ycbcr709_to_rgb32() {
  1308.     StackEntry *args = &mStack.back() - 2;
  1309.  
  1310.     VDPixmapGenYCbCr709ToRGB32 *src = new VDPixmapGenYCbCr709ToRGB32;
  1311.  
  1312.     src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
  1313.  
  1314.     mGenerators.push_back(src);
  1315.     MarkDependency(src, args[0].mpSrc);
  1316.     MarkDependency(src, args[1].mpSrc);
  1317.     MarkDependency(src, args[2].mpSrc);
  1318.     args[0] = StackEntry(src, 0);
  1319.     mStack.pop_back();
  1320.     mStack.pop_back();
  1321. }
  1322.  
  1323. void VDPixmapUberBlitterGenerator::rgb32_to_ycbcr601() {
  1324.     StackEntry *args = &mStack.back();
  1325. #ifdef VD_CPU_X86
  1326.     VDPixmapGenRGB32ToYCbCr601 *src = SSE2_enabled ? new VDPixmapGenRGB32ToYCbCr601_SSE2 : new VDPixmapGenRGB32ToYCbCr601;
  1327. #else
  1328.     VDPixmapGenRGB32ToYCbCr601 *src = new VDPixmapGenRGB32ToYCbCr601;
  1329. #endif
  1330.  
  1331.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1332.  
  1333.     mGenerators.push_back(src);
  1334.     MarkDependency(src, args[0].mpSrc);
  1335.     args[0] = StackEntry(src, 0);
  1336.     mStack.push_back(StackEntry(src, 1));
  1337.     mStack.push_back(StackEntry(src, 2));
  1338. }
  1339.  
  1340. void VDPixmapUberBlitterGenerator::rgb32_to_ycbcr709() {
  1341.     StackEntry *args = &mStack.back();
  1342.     VDPixmapGenRGB32ToYCbCr709 *src = new VDPixmapGenRGB32ToYCbCr709;
  1343.  
  1344.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1345.  
  1346.     mGenerators.push_back(src);
  1347.     MarkDependency(src, args[0].mpSrc);
  1348.     args[0] = StackEntry(src, 0);
  1349.     mStack.push_back(StackEntry(src, 1));
  1350.     mStack.push_back(StackEntry(src, 2));
  1351. }
  1352.  
  1353. void VDPixmapUberBlitterGenerator::ycbcr601_to_rgb32_32f() {
  1354.     StackEntry *args = &mStack.back() - 2;
  1355.  
  1356.     VDPixmapGenYCbCr601ToRGB32F *src = new VDPixmapGenYCbCr601ToRGB32F;
  1357.  
  1358.     src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
  1359.  
  1360.     mGenerators.push_back(src);
  1361.     MarkDependency(src, args[0].mpSrc);
  1362.     MarkDependency(src, args[1].mpSrc);
  1363.     MarkDependency(src, args[2].mpSrc);
  1364.     args[0] = StackEntry(src, 0);
  1365.     mStack.pop_back();
  1366.     mStack.pop_back();
  1367. }
  1368.  
  1369. void VDPixmapUberBlitterGenerator::ycbcr709_to_rgb32_32f() {
  1370.     StackEntry *args = &mStack.back() - 2;
  1371.  
  1372.     VDPixmapGenYCbCr709ToRGB32F *src = new VDPixmapGenYCbCr709ToRGB32F;
  1373.  
  1374.     src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
  1375.  
  1376.     mGenerators.push_back(src);
  1377.     MarkDependency(src, args[0].mpSrc);
  1378.     MarkDependency(src, args[1].mpSrc);
  1379.     MarkDependency(src, args[2].mpSrc);
  1380.     args[0] = StackEntry(src, 0);
  1381.     mStack.pop_back();
  1382.     mStack.pop_back();
  1383. }
  1384.  
  1385. void VDPixmapUberBlitterGenerator::rgb32_to_ycbcr601_32f() {
  1386.     StackEntry *args = &mStack.back();
  1387.     VDPixmapGenRGB32FToYCbCr601 *src = new VDPixmapGenRGB32FToYCbCr601;
  1388.  
  1389.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1390.  
  1391.     mGenerators.push_back(src);
  1392.     MarkDependency(src, args[0].mpSrc);
  1393.     args[0] = StackEntry(src, 0);
  1394.     mStack.push_back(StackEntry(src, 1));
  1395.     mStack.push_back(StackEntry(src, 2));
  1396. }
  1397.  
  1398. void VDPixmapUberBlitterGenerator::rgb32_to_ycbcr709_32f() {
  1399.     StackEntry *args = &mStack.back();
  1400.     VDPixmapGenRGB32FToYCbCr709 *src = new VDPixmapGenRGB32FToYCbCr709;
  1401.  
  1402.     src->Init(args[0].mpSrc, args[0].mSrcIndex);
  1403.  
  1404.     mGenerators.push_back(src);
  1405.     MarkDependency(src, args[0].mpSrc);
  1406.     args[0] = StackEntry(src, 0);
  1407.     mStack.push_back(StackEntry(src, 1));
  1408.     mStack.push_back(StackEntry(src, 2));
  1409. }
  1410.  
  1411. void VDPixmapUberBlitterGenerator::ycbcr601_to_ycbcr709() {
  1412.     StackEntry *args = &mStack.back() - 2;
  1413.  
  1414.     IVDPixmapGen *src;
  1415.     if ((args[0].mpSrc->GetType(args[0].mSrcIndex) & kVDPixType_Mask) == kVDPixType_32F_LE) {
  1416.         VDPixmapGenYCbCr601ToYCbCr709_32F *src2 = new VDPixmapGenYCbCr601ToYCbCr709_32F;
  1417.  
  1418.         src2->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
  1419.         src = src2;
  1420.     } else {
  1421.         VDPixmapGenYCbCr601ToYCbCr709 *src2 = new VDPixmapGenYCbCr601ToYCbCr709;
  1422.  
  1423.         src2->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
  1424.         src = src2;
  1425.     }
  1426.  
  1427.     mGenerators.push_back(src);
  1428.     MarkDependency(src, args[0].mpSrc);
  1429.     MarkDependency(src, args[1].mpSrc);
  1430.     MarkDependency(src, args[2].mpSrc);
  1431.     args[0] = StackEntry(src, 0);
  1432.     args[1] = StackEntry(src, 1);
  1433.     args[2] = StackEntry(src, 2);
  1434. }
  1435.  
  1436. void VDPixmapUberBlitterGenerator::ycbcr709_to_ycbcr601() {
  1437.     StackEntry *args = &mStack.back() - 2;
  1438.  
  1439.     IVDPixmapGen *src;
  1440.     if ((args[0].mpSrc->GetType(args[0].mSrcIndex) & kVDPixType_Mask) == kVDPixType_32F_LE) {
  1441.         VDPixmapGenYCbCr709ToYCbCr601_32F *src2 = new VDPixmapGenYCbCr709ToYCbCr601_32F;
  1442.  
  1443.         src2->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
  1444.         src = src2;
  1445.     } else {
  1446.         VDPixmapGenYCbCr709ToYCbCr601 *src2 = new VDPixmapGenYCbCr709ToYCbCr601;
  1447.  
  1448.         src2->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
  1449.         src = src2;
  1450.     }
  1451.  
  1452.     mGenerators.push_back(src);
  1453.     MarkDependency(src, args[0].mpSrc);
  1454.     MarkDependency(src, args[1].mpSrc);
  1455.     MarkDependency(src, args[2].mpSrc);
  1456.     args[0] = StackEntry(src, 0);
  1457.     args[1] = StackEntry(src, 1);
  1458.     args[2] = StackEntry(src, 2);
  1459. }
  1460.  
  1461. IVDPixmapBlitter *VDPixmapUberBlitterGenerator::create() {
  1462.     vdautoptr<VDPixmapUberBlitter> blitter(new VDPixmapUberBlitter);
  1463.  
  1464.     int numStackEntries = (int)mStack.size();
  1465.  
  1466.     for(int i=0; i<3; ++i) {
  1467.         if (i < numStackEntries) {
  1468.             blitter->mOutputs[i].mpSrc = mStack[i].mpSrc;
  1469.             blitter->mOutputs[i].mSrcIndex = mStack[i].mSrcIndex;
  1470.         } else {
  1471.             blitter->mOutputs[i].mpSrc = NULL;
  1472.             blitter->mOutputs[i].mSrcIndex = 0;
  1473.         }
  1474.     }
  1475.  
  1476.     mStack.clear();
  1477.  
  1478.     // If this blitter has three outputs, determine if outputs 1 and 2 are independent
  1479.     // from output 0.
  1480.     blitter->mbIndependentChromaPlanes = true;
  1481.     blitter->mbIndependentPlanes = true;
  1482.     if (numStackEntries >= 3) {
  1483.         int numGens = mGenerators.size();
  1484.         vdfastvector<uint8> genflags(numGens, 0);
  1485.  
  1486.         enum {
  1487.             kFlagStateful = 0x80,
  1488.             kFlagY = 0x01,
  1489.             kFlagCb = 0x02,
  1490.             kFlagCr = 0x04,
  1491.             kFlagYCbCr = 0x07
  1492.         };
  1493.  
  1494.         for(int i=0; i<3; ++i)
  1495.             genflags[std::find(mGenerators.begin(), mGenerators.end(), blitter->mOutputs[i].mpSrc) - mGenerators.begin()] |= (1 << i);
  1496.  
  1497.         for(int i=0; i<numGens; ++i) {
  1498.             IVDPixmapGen *gen = mGenerators[i];
  1499.  
  1500.             if (gen->IsStateful())
  1501.                 genflags[i] |= kFlagStateful;
  1502.         }
  1503.  
  1504.         while(!mDependencies.empty()) {
  1505.             const Dependency& dep = mDependencies.back();
  1506.  
  1507.             genflags[dep.mSrcIdx] |= (genflags[dep.mDstIdx] & ~kFlagStateful);
  1508.  
  1509.             mDependencies.pop_back();
  1510.         }
  1511.  
  1512.         for(int i=0; i<numGens; ++i) {
  1513.             uint8 flags = genflags[i];
  1514.  
  1515.             if (!(flags & kFlagStateful))
  1516.                 continue;
  1517.  
  1518.             switch(flags & kFlagYCbCr) {
  1519.                 case 0:
  1520.                 case kFlagY:
  1521.                 case kFlagCb:
  1522.                 case kFlagCr:
  1523.                     break;
  1524.                 case kFlagCr | kFlagCb:
  1525.                     blitter->mbIndependentPlanes = false;
  1526.                     break;
  1527.                 case kFlagCb | kFlagY:
  1528.                 case kFlagCr | kFlagY:
  1529.                 case kFlagCr | kFlagCb | kFlagY:
  1530.                     blitter->mbIndependentPlanes = false;
  1531.                     blitter->mbIndependentChromaPlanes = false;
  1532.                     break;
  1533.             }
  1534.         }
  1535.     } else if (numStackEntries >= 2) {
  1536.         int numGens = mGenerators.size();
  1537.         vdfastvector<uint8> genflags(numGens, 0);
  1538.  
  1539.         enum {
  1540.             kFlagStateful = 0x80,
  1541.             kFlagY = 0x01,
  1542.             kFlagC = 0x02,
  1543.             kFlagYC = 0x03
  1544.         };
  1545.  
  1546.         for(int i=0; i<2; ++i)
  1547.             genflags[std::find(mGenerators.begin(), mGenerators.end(), blitter->mOutputs[i].mpSrc) - mGenerators.begin()] |= (1 << i);
  1548.  
  1549.         for(int i=0; i<numGens; ++i) {
  1550.             IVDPixmapGen *gen = mGenerators[i];
  1551.  
  1552.             if (gen->IsStateful())
  1553.                 genflags[i] |= kFlagStateful;
  1554.         }
  1555.  
  1556.         while(!mDependencies.empty()) {
  1557.             const Dependency& dep = mDependencies.back();
  1558.  
  1559.             genflags[dep.mSrcIdx] |= (genflags[dep.mDstIdx] & ~kFlagStateful);
  1560.  
  1561.             mDependencies.pop_back();
  1562.         }
  1563.  
  1564.         for(int i=0; i<numGens; ++i) {
  1565.             uint8 flags = genflags[i];
  1566.  
  1567.             if (!(flags & kFlagStateful))
  1568.                 continue;
  1569.  
  1570.             switch(flags & kFlagYC) {
  1571.                 case kFlagYC:
  1572.                     blitter->mbIndependentPlanes = false;
  1573.                     blitter->mbIndependentChromaPlanes = false;
  1574.                     break;
  1575.             }
  1576.         }
  1577.     }
  1578.  
  1579.     blitter->mGenerators.swap(mGenerators);
  1580.     blitter->mSources.swap(mSources);
  1581.     return blitter.release();
  1582. }
  1583.  
  1584. void VDPixmapUberBlitterGenerator::MarkDependency(IVDPixmapGen *dst, IVDPixmapGen *src) {
  1585.     Generators::const_iterator it1(std::find(mGenerators.begin(), mGenerators.end(), dst));
  1586.     Generators::const_iterator it2(std::find(mGenerators.begin(), mGenerators.end(), src));
  1587.  
  1588.     VDASSERT(it1 != mGenerators.end());
  1589.     VDASSERT(it2 != mGenerators.end());
  1590.  
  1591.     int idx1 = it1 - mGenerators.begin();
  1592.     int idx2 = it2 - mGenerators.begin();
  1593.  
  1594.     Dependency dep = { idx1, idx2 };
  1595.  
  1596.     mDependencies.push_back(dep);
  1597. }
  1598.