void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo) { fMSFBOType = kNone_MSFBOType; if (kDesktop_GrGLBinding != ctxInfo.binding()) { if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) { // chrome's extension is equivalent to the EXT msaa // and fbo_blit extensions. fMSFBOType = kDesktopEXT_MSFBOType; } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) { fMSFBOType = kAppleES_MSFBOType; } } else { if ((ctxInfo.version() >= GR_GL_VER(3,0)) || ctxInfo.hasExtension("GL_ARB_framebuffer_object")) { fMSFBOType = GrGLCaps::kDesktopARB_MSFBOType; } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") && ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) { fMSFBOType = GrGLCaps::kDesktopEXT_MSFBOType; } // TODO: We could populate fMSAACoverageModes using GetInternalformativ // on GL 4.2+. It's format-specific, though. See also // http://code.google.com/p/skia/issues/detail?id=470 about using actual // rather than requested sample counts in cache key. if (ctxInfo.hasExtension("GL_NV_framebuffer_multisample_coverage")) { fCoverageAAType = kNVDesktop_CoverageAAType; GrGLint count; GR_GL_GetIntegerv(ctxInfo.interface(), GR_GL_MAX_MULTISAMPLE_COVERAGE_MODES, &count); fMSAACoverageModes.setCount(count); GR_GL_GetIntegerv(ctxInfo.interface(), GR_GL_MULTISAMPLE_COVERAGE_MODES, (int*)&fMSAACoverageModes[0]); // The NV driver seems to return the modes already sorted but the // spec doesn't require this. So we sort. qsort(&fMSAACoverageModes[0], count, sizeof(MSAACoverageMode), SkCastForQSort(coverage_mode_compare)); } } if (kNone_MSFBOType != fMSFBOType) { GR_GL_GetIntegerv(ctxInfo.interface(), GR_GL_MAX_SAMPLES, &fMaxSampleCount); } }
/// Creates difference images, returns the number that have a 0 metric. /// If outputDir.isEmpty(), don't write out diff files. static void create_diff_images (DiffMetricProc dmp, const int colorThreshold, RecordArray* differences, const SkString& baseDir, const SkString& comparisonDir, const SkString& outputDir, const StringArray& matchSubstrings, const StringArray& nomatchSubstrings, bool recurseIntoSubdirs, bool getBounds, bool verbose, DiffSummary* summary) { SkASSERT(!baseDir.isEmpty()); SkASSERT(!comparisonDir.isEmpty()); FileArray baseFiles; FileArray comparisonFiles; get_file_list(baseDir, matchSubstrings, nomatchSubstrings, recurseIntoSubdirs, &baseFiles); get_file_list(comparisonDir, matchSubstrings, nomatchSubstrings, recurseIntoSubdirs, &comparisonFiles); if (!baseFiles.isEmpty()) { qsort(baseFiles.begin(), baseFiles.count(), sizeof(SkString*), SkCastForQSort(compare_file_name_metrics)); } if (!comparisonFiles.isEmpty()) { qsort(comparisonFiles.begin(), comparisonFiles.count(), sizeof(SkString*), SkCastForQSort(compare_file_name_metrics)); } int i = 0; int j = 0; while (i < baseFiles.count() && j < comparisonFiles.count()) { SkString basePath(baseDir); SkString comparisonPath(comparisonDir); DiffRecord *drp = new DiffRecord; int v = strcmp(baseFiles[i]->c_str(), comparisonFiles[j]->c_str()); if (v < 0) { // in baseDir, but not in comparisonDir drp->fResult = DiffRecord::kCouldNotCompare_Result; basePath.append(*baseFiles[i]); comparisonPath.append(*baseFiles[i]); drp->fBase.fFilename = *baseFiles[i]; drp->fBase.fFullPath = basePath; drp->fBase.fStatus = DiffResource::kExists_Status; drp->fComparison.fFilename = *baseFiles[i]; drp->fComparison.fFullPath = comparisonPath; drp->fComparison.fStatus = DiffResource::kDoesNotExist_Status; VERBOSE_STATUS("MISSING", ANSI_COLOR_YELLOW, baseFiles[i]); ++i; } else if (v > 0) { // in comparisonDir, but not in baseDir drp->fResult = DiffRecord::kCouldNotCompare_Result; basePath.append(*comparisonFiles[j]); comparisonPath.append(*comparisonFiles[j]); drp->fBase.fFilename = *comparisonFiles[j]; drp->fBase.fFullPath = basePath; drp->fBase.fStatus = DiffResource::kDoesNotExist_Status; drp->fComparison.fFilename = *comparisonFiles[j]; drp->fComparison.fFullPath = comparisonPath; drp->fComparison.fStatus = DiffResource::kExists_Status; VERBOSE_STATUS("MISSING", ANSI_COLOR_YELLOW, comparisonFiles[j]); ++j; } else { // Found the same filename in both baseDir and comparisonDir. SkASSERT(DiffRecord::kUnknown_Result == drp->fResult); basePath.append(*baseFiles[i]); comparisonPath.append(*comparisonFiles[j]); drp->fBase.fFilename = *baseFiles[i]; drp->fBase.fFullPath = basePath; drp->fBase.fStatus = DiffResource::kExists_Status; drp->fComparison.fFilename = *comparisonFiles[j]; drp->fComparison.fFullPath = comparisonPath; drp->fComparison.fStatus = DiffResource::kExists_Status; SkAutoDataUnref baseFileBits(read_file(drp->fBase.fFullPath.c_str())); if (baseFileBits) { drp->fBase.fStatus = DiffResource::kRead_Status; } SkAutoDataUnref comparisonFileBits(read_file(drp->fComparison.fFullPath.c_str())); if (comparisonFileBits) { drp->fComparison.fStatus = DiffResource::kRead_Status; } if (NULL == baseFileBits || NULL == comparisonFileBits) { if (NULL == baseFileBits) { drp->fBase.fStatus = DiffResource::kCouldNotRead_Status; VERBOSE_STATUS("READ FAIL", ANSI_COLOR_RED, baseFiles[i]); } if (NULL == comparisonFileBits) { drp->fComparison.fStatus = DiffResource::kCouldNotRead_Status; VERBOSE_STATUS("READ FAIL", ANSI_COLOR_RED, comparisonFiles[j]); } drp->fResult = DiffRecord::kCouldNotCompare_Result; } else if (are_buffers_equal(baseFileBits, comparisonFileBits)) { drp->fResult = DiffRecord::kEqualBits_Result; VERBOSE_STATUS("MATCH", ANSI_COLOR_GREEN, baseFiles[i]); } else { AutoReleasePixels arp(drp); get_bitmap(baseFileBits, drp->fBase, SkImageDecoder::kDecodePixels_Mode); get_bitmap(comparisonFileBits, drp->fComparison, SkImageDecoder::kDecodePixels_Mode); VERBOSE_STATUS("DIFFERENT", ANSI_COLOR_RED, baseFiles[i]); if (DiffResource::kDecoded_Status == drp->fBase.fStatus && DiffResource::kDecoded_Status == drp->fComparison.fStatus) { create_and_write_diff_image(drp, dmp, colorThreshold, outputDir, drp->fBase.fFilename); } else { drp->fResult = DiffRecord::kCouldNotCompare_Result; } } ++i; ++j; } if (getBounds) { get_bounds(*drp); } SkASSERT(DiffRecord::kUnknown_Result != drp->fResult); differences->push(drp); summary->add(drp); } for (; i < baseFiles.count(); ++i) { // files only in baseDir DiffRecord *drp = new DiffRecord(); drp->fBase.fFilename = *baseFiles[i]; drp->fBase.fFullPath = baseDir; drp->fBase.fFullPath.append(drp->fBase.fFilename); drp->fBase.fStatus = DiffResource::kExists_Status; drp->fComparison.fFilename = *baseFiles[i]; drp->fComparison.fFullPath = comparisonDir; drp->fComparison.fFullPath.append(drp->fComparison.fFilename); drp->fComparison.fStatus = DiffResource::kDoesNotExist_Status; drp->fResult = DiffRecord::kCouldNotCompare_Result; if (getBounds) { get_bounds(*drp); } differences->push(drp); summary->add(drp); } for (; j < comparisonFiles.count(); ++j) { // files only in comparisonDir DiffRecord *drp = new DiffRecord(); drp->fBase.fFilename = *comparisonFiles[j]; drp->fBase.fFullPath = baseDir; drp->fBase.fFullPath.append(drp->fBase.fFilename); drp->fBase.fStatus = DiffResource::kDoesNotExist_Status; drp->fComparison.fFilename = *comparisonFiles[j]; drp->fComparison.fFullPath = comparisonDir; drp->fComparison.fFullPath.append(drp->fComparison.fFilename); drp->fComparison.fStatus = DiffResource::kExists_Status; drp->fResult = DiffRecord::kCouldNotCompare_Result; if (getBounds) { get_bounds(*drp); } differences->push(drp); summary->add(drp); } release_file_list(&baseFiles); release_file_list(&comparisonFiles); }